Documentation ¶
Overview ¶
Package ratelimit implements rate limiting functionality for the proxy.
It provides per process rate limiting. It can be configured globally, or based on routes. Rate limiting can be lookuped based on HTTP headers like X-Forwarded-For or Authorization.
Lookuper Type - Authorization Header ¶
This lookuper will use the content of the Authorization header to calculate rate limiting. This will work for Bearer tokens or Basic Auth without change of the rate limiter configuration.
Lookuper Type - X-Forwarded-For Header ¶
This lookuper will use the remote IP of the origin request to calculate rate limiting. If there is no such header it will use the remote IP of the request. This is the default Lookuper and may be the one most users want to use.
Usage ¶
When imported as a package, the Registry can be used to hold the rate limiters and their settings. On a higher level, rate limiter settings can be simply passed to skipper as part of the skipper.Options object, or defined as command line flags.
The following command starts skipper with default X-Forwarded-For Lookuper, that will start to rate limit after 5 requests within 60s from the same client
% skipper -ratelimits type=client,max-hits=5,time-window=60s
The following configuration will rate limit /foo after 2 requests within 90s from the same requester and all other requests after 20 requests within 60s from the same client
% cat ratelimit.eskip foo: Path("/foo") -> clientRatelimit(2,"1m30s") -> "http://www.example.org/foo" rest: * -> clientRatelimit(20,"1m") -> "http://www.example.net/" % skipper -enable-ratelimits -routes-file=ratelimit.eskip
The following configuration will rate limit requests after 100 requests within 1 minute with the same Authorization Header
% cat ratelimit-auth.eskip all: * -> clientRatelimit(100,"1m","auth") -> "http://www.example.org/" % skipper -enable-ratelimits -routes-file=ratelimit-auth.eskip
The following configuration will rate limit requests to /login after 10 requests summed across all skipper peers within one hour from the same requester.
% cat ratelimit.eskip foo: Path("/login") -> clientRatelimit(10,"1h") -> "http://www.example.org/login" rest: * -> "http://www.example.net/" % skipper -enable-ratelimits -routes-file=ratelimit.eskip -enable-swarm
Rate limiter settings can be applied globally via command line flags or within routing settings.
Settings - Type ¶
Defines the type of the rate limiter. There are types that only use local state information and others that use cluster information using swarm.Swarm to exchange information. Types that use instance local information are ServiceRatelimit to be used to protect backends and ClientRatelimit to protect from too chatty clients. Types that use cluster information are ClusterServiceRatelimit to be used to protect backends and and ClusterClientRatelimit to protect from too chatty clients. ClusterClientRatelimit should be carefully tested with your current memory settings (about 15MB for 100.000 attackers per filter), but the use cases are to protect from login attacks, user enumeration or DDoS attacks.
Settings - MaxHits ¶
Defines the maximum number of requests per user within a TimeWindow.
Settings - TimeWindow ¶
Defines the time window until rate limits will be enforced, if maximum number of requests are exceeded. This is defined as a string representation of Go's time.Duration, e.g. 1m30s.
Settings - Lookuper ¶
Defines an optional configuration to choose which Header should be used to group client requests. It accepts the default "x-forwarded-for" or "auth"
HTTP Response ¶
In case of rate limiting, the HTTP response status will be 429 Too Many Requests and two headers will be set.
One which shows the maximum requests per hour:
X-Rate-Limit: 6000
And another indicating how long (in seconds) to wait before making a new request:
Retry-After: 3600
Both are based on RFC 6585.
Registry ¶
The active rate limiters are stored in a registry. They are created based on routes or command line flags. The registry synchronizes access to the shared rate limiters. A registry has default settings that it will apply and that it will use the disable rate limiter in case it's not defined in the configuration or not global enabled.
Index ¶
Constants ¶
const ( // Header is Header = "X-Rate-Limit" // RetryHeader is name of the header which will be used to indicate how // long a client should wait before making a new request RetryAfterHeader = "Retry-After" // ServiceRatelimitName is the name of the Ratelimit filter, which will be shown in log ServiceRatelimitName = "ratelimit" // LocalRatelimitName *deprecated*, use ClientRatelimitName instead LocalRatelimitName = "localRatelimit" // ClientRatelimitName is the name of the ClientRatelimit filter, which will be shown in log ClientRatelimitName = "clientRatelimit" // ClusterServiceRatelimitName is the name of the ClusterServiceRatelimit filter, which will be shown in log ClusterServiceRatelimitName = "clusterRatelimit" // ClusterClientRatelimitName is the name of the ClusterClientRatelimit filter, which will be shown in log ClusterClientRatelimitName = "clusterClientRatelimit" // DisableRatelimitName is the name of the DisableRatelimit, which will be shown in log DisableRatelimitName = "disableRatelimit" )
const ( DefaultMaxhits = 20 DefaultTimeWindow = 1 * time.Second DefaultCleanInterval = 60 * time.Second )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AuthLookuper ¶
type AuthLookuper struct{}
AuthLookuper implements Lookuper interface and will select a bucket by Authorization header.
func NewAuthLookuper ¶
func NewAuthLookuper() AuthLookuper
NewAuthLookuper returns an empty AuthLookuper
type Lookuper ¶
type Lookuper interface { // Lookup is used to get the string which is used to define // how the bucket of a ratelimiter looks like, which is used // to decide to ratelimit or not. For example you can use the // X-Forwarded-For Header if you want to rate limit based on // source ip behind a proxy/loadbalancer or the Authorization // Header for request per token or user. Lookup(*http.Request) string }
Lookuper makes it possible to be more flexible for ratelimiting.
type Ratelimit ¶
type Ratelimit struct {
// contains filtered or unexported fields
}
Ratelimit is a proxy object that delegates to limiter implemetations and stores settings for the ratelimiter
func (*Ratelimit) Allow ¶
Allow returns true if the s is not ratelimited, false if it is ratelimited
func (*Ratelimit) Close ¶
func (l *Ratelimit) Close()
Close will stop any cleanup goroutines in underlying limiter implementation.
func (*Ratelimit) RetryAfter ¶ added in v0.10.89
RetryAfter informs how many seconds to wait for the next request
type RatelimitType ¶ added in v0.10.113
type RatelimitType int
RatelimitType defines the type of the used ratelimit
const ( // NoRatelimit is not used NoRatelimit RatelimitType = iota // ServiceRatelimit is used to have a simple rate limit for a // backend service, which is calculated and measured within // each instance ServiceRatelimit // LocalRatelimit *deprecated* will be replaced by ClientRatelimit LocalRatelimit // ClientRatelimit is used to have a simple local rate limit // per user for a backend, which is calculated and measured // within each instance. One filter consumes memory calculated // by the following formular, where N is the number of // individual clients put into the same bucket, M the maximum // number of requests allowed: // // memory = N * M * 15 byte // // For example /login protection 100.000 attacker, 10 requests // for 1 hour will use roughly 14.6 MB. ClientRatelimit // ClusterServiceRatelimit is used to calculate a rate limit // for a whole skipper fleet for a backend service, needs // swarm to be enabled with -enable-swarm. ClusterServiceRatelimit // ClusterClientRatelimit is used to calculate a rate limit // for a whole skipper fleet per user for a backend, needs // swarm to be enabled with -enable-swarm. // One filter consumes memory calculated // by the following formular, where N is the number of // individual clients put into the same bucket, M the maximum // number of requests allowed, S the number of skipper peers: // // memory = N * M * 15 + S * len(peername) // // For example /login protection 100.000 attacker, 10 requests // for 1 hour, 100 skipper peers with each a name of 8 // characters will use roughly 14.7 MB. ClusterClientRatelimit // DisableRatelimit is used to disable rate limit DisableRatelimit )
type Registry ¶
Registry objects hold the active ratelimiters, ensure synchronized access to them, apply default settings and recycle the idle ratelimiters.
func NewRegistry ¶
NewRegistry initializes a registry with the provided default settings.
func NewSwarmRegistry ¶ added in v0.10.113
NewSwarmRegistry initializes a registry with an optional swarm and the provided default settings. If swarm is nil, clusterRatelimits will be replaced by voidRatelimit, which is a noop limiter implementation.
type SameBucketLookuper ¶
type SameBucketLookuper struct{}
SameBucketLookuper implements Lookuper interface and will always match to the same bucket.
func NewSameBucketLookuper ¶
func NewSameBucketLookuper() SameBucketLookuper
NewSameBucketLookuper returns a SameBucketLookuper.
type Settings ¶
type Settings struct { // Type of the chosen rate limiter Type RatelimitType // Lookuper to decide which data to use to identify the same // bucket (for example how to lookup the client identifier) Lookuper Lookuper // MaxHits the maximum number of hits for a time duration // allowed in the same bucket. MaxHits int // TimeWindow is the time duration that is valid for hits to // be counted in the rate limit. TimeWindow time.Duration // CleanInterval is the duration old data can expire, because // need to cleanup data in for example client ratelimits. CleanInterval time.Duration }
Settings configures the chosen rate limiter
type Swarmer ¶ added in v0.10.113
type Swarmer interface { string, interface{}) error // Values is used to get global information about current rates. Values(string) map[string]interface{} }ShareValue(
Swarmer interface defines the requirement for a Swarm, for use as an exchange method for cluster ratelimits: ratelimit.ClusterServiceRatelimit and ratelimit.ClusterClientRatelimit.
type XForwardedForLookuper ¶
type XForwardedForLookuper struct{}
XForwardedForLookuper implements Lookuper interface and will select a bucket by X-Forwarded-For header or clientIP.
func NewXForwardedForLookuper ¶
func NewXForwardedForLookuper() XForwardedForLookuper
NewXForwardedForLookuper returns an empty XForwardedForLookuper