In this lesson we'll see how to use engine X as bolt in rate limiting module to create what can be thought
of as traffic lights for incoming connections rate limiting a survey implies rather than simply limiting
managing incoming connections to the server for a specific reason.
Common Reasons to rate limit a server can be to add an extra layer of security against potential brute
force attacks preventing traffic spikes for a more reliable server or even to restrict users to a service
based on the tier something like a download service for example.
Now given the tools we have at our disposal which right now is the browser and Apache bench testing
our servers rate limiting is going to be a bit difficult.
What I'll do then to better demonstrate the outcome of connections to the server is install a new tool
called seach siege is a lot like a Benge but focussed more on load testing a server rather than benchmarking
it.
A minor difference but one that will suit the needs of this lesson.
Better to install siege then again using a P T.
I'll say apt get install seach to install this on sentence.
You'll most likely have to bolded from source which is simple enough and instructions can be found in
the documentation is linked in the list and resources.
That's all done so to check the tool is working.
Let's run a test to the demo site for that image.
Thumb.
P In G I'll say C each with a V flag fall for both slogging are two meaning run.
Two tests of C Five being five concurrent connections so five concurrent connections then another 5
10 in total to fundos PRNG enter.
And that finishes almost immediately resulting in 10 hits 5 times two and 10 of those being successful.
So clearly no limiting here.
This output now demonstrating why this tool is going to work better for these tests as any failed or
rejected connections will also appear in red.
Just a bit more visual.
OK so with that done let's implement some basic rate limiting over to the configuration file where like
the fast CGI cache and the SSL session cache will define a new memory zone in which to track connection
limits.
Limit request zone and the first argument to say here is again a key with which to identify how rate
limiting as a blood.
For example if we set this to the server underscore name variable rate limiting will apply to requests
based on the server name.
So essentially all requests to this IP.
If however we made this key binary remote address which is the connecting IP address rate limiting will
be applied per user as each connecting client will have a unique IP address.
This per IP limit being perfect for something like rate limiting a log in form and thus preventing or
rather severely slowing down a brute force attack.
Or in our case I'll use request underscore.
You are my meaning limit connections per request.
You are right.
Regardless of the client IP or anything else.
If a certain you are high for example thumbed or PRNG receives more connection requests then the zone
allows apply rate limiting.
Next specify the zone name.
I'll make this my zone calon and the size of the soane in memory 10 meg which will be plenty.
With the last parameter being the all important rate.
This takes a unique format of the number of requests.
Say 60 are for 60 requests per.
With a slash and an engine next time format like em or minutes.
So this so now saying limit requests to the same request you are try to not exceed 60 requests per minute.
Very importantly.
Note that this does not mean the server can accept 60 requests at once and they no more for the remainder
of that monnet But rather it sets a frequency of requests for this time frame.
In other words this 60 requests per minute is the exact same thing as saying one request per second
or three thousand six hundred requests per hour and so on.
The point being that engine X will apply rate limits evenly thus preventing traffic spikes.
Okay then with our zone created we can add it to either the server context.
So apply to all requests on the server or inside a location context like this default location we have
here meaning we can test it on that thumbed or PRNG image say limit underscore.
Request zone equals my zone.
The name of that zone we defined.
Save this reload the configuration and run that same test again 5 concurrent requests for thumb of P
in G twice.
Enter and this time round we get only the very first request succeeding with the remaining 9 resulting
in 5 0 3 errors which is service unavailable.
So what happened here.
The way rate limiting is applied is the server received five connections at once.
Being the first batch of siege requests it responded to the first one of those five being that we're
allowing one request per second and immediately rejected the remaining four.
This obviously happened very quickly.
Well with in a second meaning that when the second batch of requests were sent to the server that one
second limit had not yet passed and all 5 requests of the next batch also got rejected.
This being the default rate limiting behaviour.
If we change this to perform two tests for a single connection.
Same as now the one second has elapsed since the last test.
But again the second request gets denied.
As soon as that second limit starts again.
Let's say however I manually perform a code request for thunder P and G.
Again only checking the headers for the status code the second from the last test has elapsed.
So enter it works.
Wait more than one second and run this again another 200 success.
More than a second and so on.
So as long as these requests are sent more than 1 second apart no limiting as applied 1 second being
extremely aggressive of course but for the sake of demonstrating.
Okay so that's the default rate limiting behaviour but the zone directive does allow us to change this
behaviour somewhat.
The first will look at a city in a burst limit by specifying on the zone directive berst equals and
a number.
For example 5 they're supplying a burst allowance which will discuss in a second to all implementations
of this zone.
Alternatively then to better specify where we enable bursts.
We can also specify this on the limit request implementation like so just a more granular way of configuring
the rate limiting behaviour especially if you have multiple implementations of the same zone.
So what does this burst allowance do.
Basically setting a burst changes their default behaviour of immediately rejecting all requests exceeding
the limit to allow this number of requests to also be fulfilled meaning our server will now accept one
plus five connections within the second.
It does not however mean that these five will be responded to immediately.
Instead they will still have to adhere to the specified limit only that they will have to wait and won't
be rejected.
With that 5o 3 error we saw this then provides a bit of a buffer and rather than creating hard limits
allows us to implement what would be considered more traffic shaping.
So slowing down connections save this and reload the configuration.
Run that first test again to Lot of 5 concurrent connections meaning we're within this six total allowed
and this time the first is responded to immediately as before and the remaining four gets four fold
one every second.
So perfectly within the right limit.
Then once the second batch of 5 connections is sen. we're still within the right limit and again the
same shaping occurs.
So all 10 requests is successful but taking nine point three seconds nearly one second per request only
the first immediate request making up for those few milliseconds.
So much more eloquent way of limiting say front in traffic for example.
Change this test to exceed the burst however.
Say 15 concurrent connections doing only one lot less time.
And immediately the exceeded number of requests is rejected whilst the remainder gets throttled to one
per second leaving us with the total six requests exceeding one blast burst and the remaining nine immediately
receiving five or three errors as there were outside the raised limit and the allowed burst.
The final modification we can apply to our limits zone.
Is there no delay parameter.
This only being applicable to a zone that already defines a burst value as well essentially no delay
says serve the allowed burst requests as quickly as possible so not adhering to the right limit for
the burst requests.
But very importantly still maintain the applicable time limit for any new requests.
Meaning if we performed six concurrent requests even though there will all be served as quickly as possible
the right limit will still only reset at 1 request each second.
This might sound a bit confusing so let me demonstrate again save and reload the configuration.
I'll run a single test for the full six requests only.
And as soon as that is done which should be very quick due to that no delay parameter I'll run the same
one again.
Enter again.
And done.
So what we can see here is how long it took me to run the sick and test then the first six requests
were all responded to successfully as per our rate of 1 plus 5 the burst which all in all took nearly
a full second and then it took me a little over another second to run the second test as we only managed
to have 2 of those request responded to meaning the total limit of 1 request per second making six seconds
was still active and the two seconds it took until the second Test ran freed up two requests in that
limit which is what the no delay parameter allows us to do.
That wraps up rate limiting and given these three variations of default burst and no delay.
The limiting strategies are endless.
If this got a bit confusing towards the end.
Be sure to watch this listen again and also take a look at the excellent article linked in the resources.