After a recent conversation on the Ubuntu Forums I wanted to post an example of using iptables.
Of course there are several types of DOS attacks , in this post I will demonstrating the use if iptables to limit the traffic on port 80.
The goal is to keep your web server “responsive” to legitimate traffic, but to throttle back on excessive (potential DOS) traffic.
In this demonstration iptables is configured :
-p tcp --dport 80 => Specifies traffic on port 80 (Normally Apache, but as you can see here I am using nginx).
-m state NEW => This rule applies to NEW connections.
-m limit --limit 50/minute --limit-burst 200 -j ACCEPT =>This is the essence of preventing DOS.
If you understood the above rule, you should understand this one as well.
Do not let that rule fool you, although it seems very open, it does put some limits on your connections.
Test it for yourself, try using the first rule with and without the second rule.
Hit F5 repetitively, load the page as fast as you can. Your web site should remain nice and responsive.
So far, so good, we want our site to remain responsive.
See this link or the Apache documentation for information of ab.
Requests per second: 7.59 [#/sec] .
Total time for requests: 13 seconds .
(Data) Transfer rate: 444.98 [Kbytes/sec] .
Second attempt (I reduced the number of requests to 90):
Requests per second: 1.29 [#/sec] (mean)
Total time for requests: 69 seconds.
(Data) Transfer rate: 75.71 [Kbytes/sec] [Kbytes/sec].
Notice :
Requests per second: 16.86 [#/sec]
Total time for requests: 69 seconds.
(Data) Transfer rate: 974.37 [Kbytes/sec] .
As you can see, the server has no problem dishing out 974.37 [Kbytes/sec] !!!
With these rules your web site remains responsive to human interaction in firefox. Go ahead, hit F5 (refresh the page) as fast as you can, see if you can get your web page to slow down =) .
The difference is that as with a DOS attack, ab is hitting the server faster then you can with F5 , so your site is responsive to “normal” activity, but blocks DOS.
Obviously this is but one example and there are several types of DOS attacks. The goal is to demonstrate the use of iptables using a few “simple” rules.
You task is to take this knowledge and apply it to you own server.
Of course there are several types of DOS attacks , in this post I will demonstrating the use if iptables to limit the traffic on port 80.
The goal is to keep your web server “responsive” to legitimate traffic, but to throttle back on excessive (potential DOS) traffic.
In this demonstration iptables is configured :
- The default policy is ACCEPT (to prevent lockout in the event of flushing the rules with iptables -F).
- “Legitimate” traffic is then allowed. In this example I am allowing traffic only on port 80.
- All other traffic is then blocked at the end of the INPUT chain (the final rule in the INPUT chain is to DROP all traffic).
First rule : Limit NEW traffic on port 80
sudo iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m limit --limit 50/minute --limit-burst 200 -j ACCEPT
Lets break that rule down into intelligible chunks.-p tcp --dport 80 => Specifies traffic on port 80 (Normally Apache, but as you can see here I am using nginx).
-m state NEW => This rule applies to NEW connections.
-m limit --limit 50/minute --limit-burst 200 -j ACCEPT =>This is the essence of preventing DOS.
- “--limit-burst” is a bit confusing, but in a nutshell 200 new connections (packets really) are allowed before the limit of 50 NEW connections (packets) per minute is applied.
Second rule – Limit established traffic
This rule applies to RELATED and ESTABLISHED all traffic on all ports, but is very liberal (and thus should not affect traffic on port 22 or DNS).If you understood the above rule, you should understand this one as well.
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 50/second --limit-burst 50 -j ACCEPT
In summary, 50 ESTABLISHED (and/or RELATED) connections (packets
really) are allowed before the limit of 50 ESTABLISHED (and/or RELATED)
connections (packets) per second is applied.Do not let that rule fool you, although it seems very open, it does put some limits on your connections.
Test it for yourself, try using the first rule with and without the second rule.
Full set of rules
After the above commands, here is the complete set of rules I am testing:iptables-save # Generated by iptables-save v1.4.4 on -- *nat :PREROUTING ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT # Completed on -- # Generated by iptables-save -- *mangle :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT # Completed on -- # Generated by iptables-save v1.4.4 on -- *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 50/sec \ --limit-burst 50 -j ACCEPT -A INPUT -p icmp -m limit --limit 1/sec -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -m limit --limit 50/min \ --limit-burst 200 -j ACCEPT -A INPUT -j LOG -A INPUT -j DROP -A FORWARD -j DROP -A OUTPUT -o lo -j ACCEPT COMMIT # Completed on --This rule set is for demonstration only and is NOT a complete set of rules for a web server. Do no use this rule set unmodified on a production server.
Testing the rule set
Human interaction
Open Firefox, point it to your web page. The web page should load nice and fast.Hit F5 repetitively, load the page as fast as you can. Your web site should remain nice and responsive.
So far, so good, we want our site to remain responsive.
Simulated DOS
Actual DOS attacks are many times faster then humans, here I will use ab.See this link or the Apache documentation for information of ab.
Baseline, without the above 2 rules
ab -n 100 -c 10 http://bodhi's_test_server.com/ This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking bodhi's_test_server.com (be patient).....done Server Software: nginx Server Hostname: bodhi's_test_server.com Server Port: 80 Document Path: / Document Length: 59786 bytes Concurrency Level: 10 Time taken for tests: 13.174 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 6002700 bytes HTML transferred: 5978600 bytes Requests per second: 7.59 [#/sec] (mean) Time per request: 1317.369 [ms] (mean) Time per request: 131.737 [ms] (mean, across all concurrent requests) Transfer rate: 444.98 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 122 129 2.2 128 134 Processing: 1151 1182 19.1 1177 1260 Waiting: 125 132 8.2 128 170 Total: 1280 1310 19.3 1305 1390 Percentage of the requests served within a certain time (ms) 50% 1305 66% 1313 75% 1316 80% 1321 90% 1328 95% 1354 98% 1386 99% 1390 100% 1390 (longest request)Notice:
Requests per second: 7.59 [#/sec] .
Total time for requests: 13 seconds .
(Data) Transfer rate: 444.98 [Kbytes/sec] .
With the above rules
First attempt:ab -n 100 -c 10 http://bodhi's_test_server.com/ This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking bodhi's_test_server.com (be patient)... apr_poll: The timeout specified has expired (70007) Total of 99 requests completedOh no ! timed out, LOL
Second attempt (I reduced the number of requests to 90):
ab -n 90 -c 10 http://bodhi's_test_server.com/ This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking bodhi's_test_server.com (be patient).....done Server Software: nginx Server Hostname: bodhi's_test_server.com Server Port: 80 Document Path: / Document Length: 59786 bytes Concurrency Level: 10 Time taken for tests: 69.684 seconds Complete requests: 90 Failed requests: 0 Write errors: 0 Total transferred: 5402430 bytes HTML transferred: 5380740 bytes Requests per second: 1.29 [#/sec] (mean) Time per request: 7742.658 [ms] (mean) Time per request: 774.266 [ms] (mean, across all concurrent requests) Transfer rate: 75.71 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 123 128 4.3 127 155 Processing: 1036 6269 10081.4 1921 51059 Waiting: 125 1240 5908.7 128 49656 Total: 1159 6396 10081.1 2044 51186 Percentage of the requests served within a certain time (ms) 50% 2044 66% 2981 75% 5478 80% 7047 90% 20358 95% 27356 98% 48218 99% 51186 100% 51186 (longest request)Notice :
Requests per second: 1.29 [#/sec] (mean)
Total time for requests: 69 seconds.
(Data) Transfer rate: 75.71 [Kbytes/sec] [Kbytes/sec].
For those unfamiliar with ab, that is a “minor” DOS
For comparison, here is what ab can do to the server (iptables was flushed [disabled]):ab -n 1000 -c 100 http://bodhi's_test_server.com/ This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking bodhi's_test_server.com (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx Server Hostname: bodhi's_test_server.com Server Port: 80 Document Path: / Document Length: 58708 bytes Concurrency Level: 100 Time taken for tests: 59.324 seconds Complete requests: 1000 Failed requests: 945 (Connect: 0, Receive: 0, Length: 945, Exceptions: 0) Write errors: 0 Total transferred: 59190450 bytes HTML transferred: 58945935 bytes Requests per second: 16.86 [#/sec] (mean) Time per request: 5932.368 [ms] (mean) Time per request: 59.324 [ms] (mean, across all concurrent requests) Transfer rate: 974.37 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 127 908 817.9 788 8016 Processing: 735 4779 1805.2 4368 15707 Waiting: 128 981 827.2 811 12143 Total: 1058 5687 1880.8 5269 17450 Percentage of the requests served within a certain time (ms) 50% 5269 66% 5899 75% 6340 80% 6863 90% 8078 95% 9001 98% 10937 99% 11730 100% 17450 (longest request)
Notice :
Requests per second: 16.86 [#/sec]
Total time for requests: 69 seconds.
(Data) Transfer rate: 974.37 [Kbytes/sec] .
As you can see, the server has no problem dishing out 974.37 [Kbytes/sec] !!!
Closing remarks
Hopefully you now understand this “simple” example limiting a DOS on port 80.With these rules your web site remains responsive to human interaction in firefox. Go ahead, hit F5 (refresh the page) as fast as you can, see if you can get your web page to slow down =) .
The difference is that as with a DOS attack, ab is hitting the server faster then you can with F5 , so your site is responsive to “normal” activity, but blocks DOS.
Obviously this is but one example and there are several types of DOS attacks. The goal is to demonstrate the use of iptables using a few “simple” rules.
You task is to take this knowledge and apply it to you own server.
No comments:
Post a Comment