{"id":5955,"date":"2016-05-17T12:29:53","date_gmt":"2016-05-17T04:29:53","guid":{"rendered":"http:\/\/rmohan.com\/?p=5955"},"modified":"2016-05-17T12:29:53","modified_gmt":"2016-05-17T04:29:53","slug":"mitigate-ddos-attack-with-ngx_http_limit_req_module-and-fail2ban","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=5955","title":{"rendered":"Mitigate DDoS attack with ngx_http_limit_req_module and fail2ban"},"content":{"rendered":"<p><strong>Mitigate DDoS attack with ngx_http_limit_req_module and fail2ban<\/strong><\/p>\n<p>The fail2ban do have comprehensive collection of scripts that scan log files and ban IPs that match malicious activities.<\/p>\n<p>But we are going to look on how to use ngx_http_limit_req_module logs to ban IPs that shows sign of Distributed Denial of Service (DDoS) attack on your website.<br \/>\nIt is assumed in this tutorial that Nginx server is installed in your server.<\/p>\n<p>The following procedures are tested on\u00a0 running Centos 7 64-bit Linux distribution.<\/p>\n<p>Enable ngx_http_limit_req_module by adding the following script in your Nginx configuration:<\/p>\n<p>http {<br \/>\nlimit_req_zone $binary_remote_addr zone=one:10m rate=1r\/s;<br \/>\n&#8230;<br \/>\nserver {<br \/>\n&#8230;<br \/>\nlimit_req zone=one burst=5;<br \/>\n}<br \/>\n}<\/p>\n<p>Restart Nginx server:<\/p>\n<p>systemctl restart\u00a0 nginx.service<\/p>\n<p>You will see entry something like this in Nginx error log if there&#8217;s abuse detected:<\/p>\n<p>2015\/08\/27 02:18:05 [error] 21235#21235: *326 limiting requests, excess: 5.297 by zone &#8220;one&#8221;, client: 91.214.169.44, server: www.webfoobar.com, request: &#8220;GET \/node\/8 HTTP\/1.1&#8221;, host: &#8220;www.webfoobar.com&#8221;, referrer: &#8220;https:\/\/www.webfoobar.com\/archive\/201502&#8221;<\/p>\n<p>We will use this sample log entry for our fail2ban filter script.<br \/>\nInstall fail2ban:<\/p>\n<p>yum install -y fail2ban<\/p>\n<p>Create fail2ban filter script based on the Nginx error log entry:<\/p>\n<p>vi \/etc\/fail2ban\/filter.d\/nginx-ddos.conf<\/p>\n<p>The content of this filter file:<\/p>\n<p>[Definition]<br \/>\nfailregex = limiting requests, excess:.* by zone.*client:<br \/>\nignoreregex =<\/p>\n<p>We will use the \/etc\/hosts.deny to block the IP of the DDoS attacker so we will need to create new fail2ban action script:<\/p>\n<p>vi \/etc\/fail2ban\/action.d\/hostsdeny.conf<\/p>\n<p>Add the following script as its content:<\/p>\n<p>[Definition]<br \/>\nactionstart =<br \/>\nactionstop =<br \/>\nactioncheck =<br \/>\nactionban = IP= &amp;&amp;<br \/>\nprintf %%b &#8220;: $IP\\n&#8221; &gt;&gt;<br \/>\nactionunban = IP= &amp;&amp; sed -i.old \/ALL:\\ $IP\/d<\/p>\n<p>[Init]<br \/>\nfile = \/etc\/hosts.deny<br \/>\ndaemon_list = ALL<\/p>\n<p>Enable the newly created fail2ban filter:<\/p>\n<p>vi \/etc\/fail2ban\/jail.local<\/p>\n<p>Append the following script:<\/p>\n<p>[nginx-ddos]<br \/>\nenabled = true<br \/>\nport\u00a0\u00a0\u00a0 = http,https<br \/>\nbanaction = hostsdeny<br \/>\nfindtime = 120<br \/>\nbantime\u00a0 = 7200<br \/>\nmaxretry = 30<br \/>\nlogpath = %(nginx_error_log)s<\/p>\n<p>Start the fail2ban service:<\/p>\n<p>systemctl start fail2ban<br \/>\nsystemctl enable fail2ban.service<br \/>\nsystemctl list-unit-files | grep fail2ban<\/p>\n<p>To check the status of this fail2ban filter:<\/p>\n<p>fail2ban-client status nginx-ddos<\/p>\n<p>You will see something like this:<\/p>\n<p>Status for the jail: nginx-ddos<br \/>\n|- Filter<br \/>\n|\u00a0 |- Currently failed: 18<br \/>\n|\u00a0 |- Total failed:\u00a0\u00a0\u00a0\u00a0 770<br \/>\n|\u00a0 `- File list:\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/var\/log\/nginx\/nginx_error_log<br \/>\n`- Actions<br \/>\n|- Currently banned: 1<br \/>\n|- Total banned:\u00a0\u00a0\u00a0\u00a0 8<br \/>\n`- Banned IP list:\u00a0\u00a0 91.214.169.44<\/p>\n<p>To test if the fail2ban nginx-ddos filter working:<\/p>\n<p>fail2ban-regex \/var\/log\/nginx\/nginx_error_log \/etc\/fail2ban\/filter.d\/nginx-ddos.conf<\/p>\n<p>You can use apache-bench to test the whole system:<\/p>\n<p>ab -n 20 -c 10 http:\/\/www.example.com<\/p>\n<p>Execute the following command to monitor the fail2ban log:<\/p>\n<p>watch -n 1 tail -n 20 \/var\/log\/fail2ban.log<\/p>\n<p>And you will something like this while testing with apache-bench:<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mitigate DDoS attack with ngx_http_limit_req_module and fail2ban<\/p>\n<p>The fail2ban do have comprehensive collection of scripts that scan log files and ban IPs that match malicious activities.<\/p>\n<p>But we are going to look on how to use ngx_http_limit_req_module logs to ban IPs that shows sign of Distributed Denial of Service (DDoS) attack on your website. It [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[73],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/5955"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5955"}],"version-history":[{"count":1,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/5955\/revisions"}],"predecessor-version":[{"id":5956,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/5955\/revisions\/5956"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5955"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5955"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5955"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}