1 00:00:04,510 --> 00:00:10,270 In this lesson we'll see how to use engine X as bolt in rate limiting module to create what can be thought 2 00:00:10,270 --> 00:00:17,200 of as traffic lights for incoming connections rate limiting a survey implies rather than simply limiting 3 00:00:17,500 --> 00:00:22,010 managing incoming connections to the server for a specific reason. 4 00:00:22,180 --> 00:00:27,760 Common Reasons to rate limit a server can be to add an extra layer of security against potential brute 5 00:00:27,760 --> 00:00:34,750 force attacks preventing traffic spikes for a more reliable server or even to restrict users to a service 6 00:00:34,750 --> 00:00:39,620 based on the tier something like a download service for example. 7 00:00:39,730 --> 00:00:46,480 Now given the tools we have at our disposal which right now is the browser and Apache bench testing 8 00:00:46,510 --> 00:00:49,540 our servers rate limiting is going to be a bit difficult. 9 00:00:49,540 --> 00:00:55,390 What I'll do then to better demonstrate the outcome of connections to the server is install a new tool 10 00:00:55,420 --> 00:01:03,280 called seach siege is a lot like a Benge but focussed more on load testing a server rather than benchmarking 11 00:01:03,280 --> 00:01:03,770 it. 12 00:01:03,850 --> 00:01:07,180 A minor difference but one that will suit the needs of this lesson. 13 00:01:07,180 --> 00:01:11,680 Better to install siege then again using a P T. 14 00:01:11,680 --> 00:01:17,160 I'll say apt get install seach to install this on sentence. 15 00:01:17,160 --> 00:01:22,600 You'll most likely have to bolded from source which is simple enough and instructions can be found in 16 00:01:22,600 --> 00:01:26,430 the documentation is linked in the list and resources. 17 00:01:26,770 --> 00:01:29,650 That's all done so to check the tool is working. 18 00:01:29,650 --> 00:01:33,420 Let's run a test to the demo site for that image. 19 00:01:33,490 --> 00:01:33,980 Thumb. 20 00:01:33,990 --> 00:01:43,000 P In G I'll say C each with a V flag fall for both slogging are two meaning run. 21 00:01:43,000 --> 00:01:53,260 Two tests of C Five being five concurrent connections so five concurrent connections then another 5 22 00:01:53,500 --> 00:01:58,230 10 in total to fundos PRNG enter. 23 00:01:59,890 --> 00:02:08,620 And that finishes almost immediately resulting in 10 hits 5 times two and 10 of those being successful. 24 00:02:08,620 --> 00:02:10,980 So clearly no limiting here. 25 00:02:11,290 --> 00:02:17,110 This output now demonstrating why this tool is going to work better for these tests as any failed or 26 00:02:17,110 --> 00:02:20,150 rejected connections will also appear in red. 27 00:02:20,200 --> 00:02:21,900 Just a bit more visual. 28 00:02:22,190 --> 00:02:29,110 OK so with that done let's implement some basic rate limiting over to the configuration file where like 29 00:02:29,110 --> 00:02:36,300 the fast CGI cache and the SSL session cache will define a new memory zone in which to track connection 30 00:02:36,310 --> 00:02:37,480 limits. 31 00:02:37,480 --> 00:02:45,820 Limit request zone and the first argument to say here is again a key with which to identify how rate 32 00:02:45,820 --> 00:02:47,360 limiting as a blood. 33 00:02:47,560 --> 00:02:54,190 For example if we set this to the server underscore name variable rate limiting will apply to requests 34 00:02:54,490 --> 00:02:56,620 based on the server name. 35 00:02:56,620 --> 00:03:00,220 So essentially all requests to this IP. 36 00:03:00,280 --> 00:03:07,750 If however we made this key binary remote address which is the connecting IP address rate limiting will 37 00:03:07,750 --> 00:03:13,420 be applied per user as each connecting client will have a unique IP address. 38 00:03:13,420 --> 00:03:19,210 This per IP limit being perfect for something like rate limiting a log in form and thus preventing or 39 00:03:19,210 --> 00:03:22,460 rather severely slowing down a brute force attack. 40 00:03:22,780 --> 00:03:26,390 Or in our case I'll use request underscore. 41 00:03:26,410 --> 00:03:29,980 You are my meaning limit connections per request. 42 00:03:29,980 --> 00:03:30,840 You are right. 43 00:03:31,000 --> 00:03:34,400 Regardless of the client IP or anything else. 44 00:03:34,530 --> 00:03:41,110 If a certain you are high for example thumbed or PRNG receives more connection requests then the zone 45 00:03:41,170 --> 00:03:43,640 allows apply rate limiting. 46 00:03:44,020 --> 00:03:46,780 Next specify the zone name. 47 00:03:46,780 --> 00:03:54,700 I'll make this my zone calon and the size of the soane in memory 10 meg which will be plenty. 48 00:03:55,480 --> 00:03:59,290 With the last parameter being the all important rate. 49 00:03:59,440 --> 00:04:02,910 This takes a unique format of the number of requests. 50 00:04:02,950 --> 00:04:07,400 Say 60 are for 60 requests per. 51 00:04:07,570 --> 00:04:13,570 With a slash and an engine next time format like em or minutes. 52 00:04:13,570 --> 00:04:22,350 So this so now saying limit requests to the same request you are try to not exceed 60 requests per minute. 53 00:04:22,510 --> 00:04:23,660 Very importantly. 54 00:04:23,680 --> 00:04:30,490 Note that this does not mean the server can accept 60 requests at once and they no more for the remainder 55 00:04:30,490 --> 00:04:37,030 of that monnet But rather it sets a frequency of requests for this time frame. 56 00:04:37,060 --> 00:04:44,950 In other words this 60 requests per minute is the exact same thing as saying one request per second 57 00:04:45,570 --> 00:04:50,390 or three thousand six hundred requests per hour and so on. 58 00:04:50,440 --> 00:04:56,340 The point being that engine X will apply rate limits evenly thus preventing traffic spikes. 59 00:04:56,620 --> 00:05:01,550 Okay then with our zone created we can add it to either the server context. 60 00:05:01,690 --> 00:05:09,490 So apply to all requests on the server or inside a location context like this default location we have 61 00:05:09,490 --> 00:05:16,230 here meaning we can test it on that thumbed or PRNG image say limit underscore. 62 00:05:16,240 --> 00:05:20,870 Request zone equals my zone. 63 00:05:20,980 --> 00:05:23,200 The name of that zone we defined. 64 00:05:23,440 --> 00:05:32,350 Save this reload the configuration and run that same test again 5 concurrent requests for thumb of P 65 00:05:32,350 --> 00:05:34,330 in G twice. 66 00:05:34,330 --> 00:05:41,260 Enter and this time round we get only the very first request succeeding with the remaining 9 resulting 67 00:05:41,260 --> 00:05:45,490 in 5 0 3 errors which is service unavailable. 68 00:05:45,490 --> 00:05:46,750 So what happened here. 69 00:05:46,840 --> 00:05:51,880 The way rate limiting is applied is the server received five connections at once. 70 00:05:51,880 --> 00:05:59,170 Being the first batch of siege requests it responded to the first one of those five being that we're 71 00:05:59,170 --> 00:06:04,650 allowing one request per second and immediately rejected the remaining four. 72 00:06:04,660 --> 00:06:06,490 This obviously happened very quickly. 73 00:06:06,520 --> 00:06:12,940 Well with in a second meaning that when the second batch of requests were sent to the server that one 74 00:06:12,940 --> 00:06:19,690 second limit had not yet passed and all 5 requests of the next batch also got rejected. 75 00:06:19,720 --> 00:06:22,740 This being the default rate limiting behaviour. 76 00:06:22,750 --> 00:06:26,980 If we change this to perform two tests for a single connection. 77 00:06:27,040 --> 00:06:31,230 Same as now the one second has elapsed since the last test. 78 00:06:31,240 --> 00:06:33,420 But again the second request gets denied. 79 00:06:33,430 --> 00:06:36,000 As soon as that second limit starts again. 80 00:06:36,460 --> 00:06:41,110 Let's say however I manually perform a code request for thunder P and G. 81 00:06:41,170 --> 00:06:46,870 Again only checking the headers for the status code the second from the last test has elapsed. 82 00:06:46,870 --> 00:06:49,270 So enter it works. 83 00:06:49,270 --> 00:06:54,350 Wait more than one second and run this again another 200 success. 84 00:06:54,520 --> 00:06:57,110 More than a second and so on. 85 00:06:57,250 --> 00:07:04,510 So as long as these requests are sent more than 1 second apart no limiting as applied 1 second being 86 00:07:04,510 --> 00:07:08,560 extremely aggressive of course but for the sake of demonstrating. 87 00:07:08,900 --> 00:07:14,680 Okay so that's the default rate limiting behaviour but the zone directive does allow us to change this 88 00:07:14,680 --> 00:07:16,450 behaviour somewhat. 89 00:07:16,450 --> 00:07:24,130 The first will look at a city in a burst limit by specifying on the zone directive berst equals and 90 00:07:24,130 --> 00:07:24,700 a number. 91 00:07:24,730 --> 00:07:32,710 For example 5 they're supplying a burst allowance which will discuss in a second to all implementations 92 00:07:32,770 --> 00:07:34,370 of this zone. 93 00:07:34,390 --> 00:07:38,370 Alternatively then to better specify where we enable bursts. 94 00:07:38,470 --> 00:07:45,610 We can also specify this on the limit request implementation like so just a more granular way of configuring 95 00:07:45,610 --> 00:07:51,460 the rate limiting behaviour especially if you have multiple implementations of the same zone. 96 00:07:51,460 --> 00:07:54,420 So what does this burst allowance do. 97 00:07:54,490 --> 00:08:00,550 Basically setting a burst changes their default behaviour of immediately rejecting all requests exceeding 98 00:08:00,550 --> 00:08:08,200 the limit to allow this number of requests to also be fulfilled meaning our server will now accept one 99 00:08:08,380 --> 00:08:11,430 plus five connections within the second. 100 00:08:11,710 --> 00:08:16,510 It does not however mean that these five will be responded to immediately. 101 00:08:16,510 --> 00:08:22,570 Instead they will still have to adhere to the specified limit only that they will have to wait and won't 102 00:08:22,570 --> 00:08:23,380 be rejected. 103 00:08:23,380 --> 00:08:30,130 With that 5o 3 error we saw this then provides a bit of a buffer and rather than creating hard limits 104 00:08:30,340 --> 00:08:34,660 allows us to implement what would be considered more traffic shaping. 105 00:08:34,660 --> 00:08:40,300 So slowing down connections save this and reload the configuration. 106 00:08:41,040 --> 00:08:49,280 Run that first test again to Lot of 5 concurrent connections meaning we're within this six total allowed 107 00:08:49,680 --> 00:08:55,620 and this time the first is responded to immediately as before and the remaining four gets four fold 108 00:08:55,650 --> 00:08:57,330 one every second. 109 00:08:57,540 --> 00:09:00,120 So perfectly within the right limit. 110 00:09:00,120 --> 00:09:06,220 Then once the second batch of 5 connections is sen. we're still within the right limit and again the 111 00:09:06,220 --> 00:09:08,030 same shaping occurs. 112 00:09:08,160 --> 00:09:16,530 So all 10 requests is successful but taking nine point three seconds nearly one second per request only 113 00:09:16,530 --> 00:09:20,590 the first immediate request making up for those few milliseconds. 114 00:09:20,890 --> 00:09:25,680 So much more eloquent way of limiting say front in traffic for example. 115 00:09:27,000 --> 00:09:29,680 Change this test to exceed the burst however. 116 00:09:30,880 --> 00:09:35,630 Say 15 concurrent connections doing only one lot less time. 117 00:09:37,250 --> 00:09:43,760 And immediately the exceeded number of requests is rejected whilst the remainder gets throttled to one 118 00:09:43,760 --> 00:09:51,890 per second leaving us with the total six requests exceeding one blast burst and the remaining nine immediately 119 00:09:51,890 --> 00:09:57,370 receiving five or three errors as there were outside the raised limit and the allowed burst. 120 00:09:58,140 --> 00:10:01,110 The final modification we can apply to our limits zone. 121 00:10:01,200 --> 00:10:03,470 Is there no delay parameter. 122 00:10:03,600 --> 00:10:10,350 This only being applicable to a zone that already defines a burst value as well essentially no delay 123 00:10:10,350 --> 00:10:17,430 says serve the allowed burst requests as quickly as possible so not adhering to the right limit for 124 00:10:17,430 --> 00:10:18,710 the burst requests. 125 00:10:18,870 --> 00:10:25,230 But very importantly still maintain the applicable time limit for any new requests. 126 00:10:25,230 --> 00:10:31,050 Meaning if we performed six concurrent requests even though there will all be served as quickly as possible 127 00:10:31,500 --> 00:10:36,270 the right limit will still only reset at 1 request each second. 128 00:10:36,270 --> 00:10:43,030 This might sound a bit confusing so let me demonstrate again save and reload the configuration. 129 00:10:43,890 --> 00:10:47,640 I'll run a single test for the full six requests only. 130 00:10:47,880 --> 00:10:53,910 And as soon as that is done which should be very quick due to that no delay parameter I'll run the same 131 00:10:53,910 --> 00:10:55,130 one again. 132 00:10:55,440 --> 00:10:57,620 Enter again. 133 00:10:58,700 --> 00:10:59,860 And done. 134 00:11:00,020 --> 00:11:05,630 So what we can see here is how long it took me to run the sick and test then the first six requests 135 00:11:05,660 --> 00:11:13,250 were all responded to successfully as per our rate of 1 plus 5 the burst which all in all took nearly 136 00:11:13,250 --> 00:11:20,030 a full second and then it took me a little over another second to run the second test as we only managed 137 00:11:20,030 --> 00:11:27,980 to have 2 of those request responded to meaning the total limit of 1 request per second making six seconds 138 00:11:28,160 --> 00:11:35,060 was still active and the two seconds it took until the second Test ran freed up two requests in that 139 00:11:35,060 --> 00:11:39,720 limit which is what the no delay parameter allows us to do. 140 00:11:39,770 --> 00:11:45,980 That wraps up rate limiting and given these three variations of default burst and no delay. 141 00:11:45,980 --> 00:11:48,610 The limiting strategies are endless. 142 00:11:48,690 --> 00:11:50,800 If this got a bit confusing towards the end. 143 00:11:50,800 --> 00:11:57,110 Be sure to watch this listen again and also take a look at the excellent article linked in the resources.