Nginx simple defense against CC attacks

Source: Internet
Author: User

Nginx is a lightweight Web server developed by Russian programmer Igor Sysoev. It was initially used by Russian large-scale entry websites and search for Rambler. It is characterized by a small amount of memory and high concurrency. In fact, Nginx's concurrency is indeed good in the same type of website servers.

Although Nginx can process a larger number of connections than Apache, http get flood not only targets WEB servers, but also database servers. A large number of HTTP requests generate a large number of database queries, so that the database can stop responding within a few seconds, and the system load increases, leading to server hosting.

This article describes how to quickly and effectively defend against CC attacks in Centos + Nginx. As for how to install Nginx is not detailed introduction, interested readers can download the source code on the official Nginx website (http://www.nginx.org/) for compilation. If you are using Centos5, you can also use the rpm package for installation (http://centos.alt.ru/repository/centos/5/i386/nginx-stable-0.7.65-1.el5.i386.rpm ).

1. Active Suppression
To enable Nginx to support more concurrent connections, adjust the number of worker threads and the maximum number of connections supported by each worker thread according to the actual situation. For example, if "worker_processes 10" and "worker_connections 1024" are set, the maximum number of connections supported by this server is 10 × 1024 = 10240.
Worker_processes 10;
Events {
Use epoll;
Worker_connections 10240;
}

Nginx 0.7 provides two Restricted User connection modules: NginxHttpLimitZoneModule and NginxHttpLimitReqModule.
The NginxHttpLimitZoneModule can control the number of concurrent connections based on the conditions.
For example, you can define the following code:
Http {
Limit_zone my_zone $ binary_remote_addr 10 m;
Server {
Location/somedir /{
Limit_conn my_zone 1;
}
}
}
"Limit_zone my_zone $ binary_remote_addr 10m" means defining a storage region named my_zone, the content in my_zone is a remote IP address, and the size of my_zone is 10 M; "location/somedir/" means to apply rules to the somedir directory; "limit_conn my_zone 1" indicates that only one connection can be established for the IP address of the my_zone record area defined above in the specified directory.

The NginxHttpLimitReqModule can control the request Frequency Based on the conditions.
For example, you can define the following code:
Http {
Limit_req_zone $ binary_remote_addr zone = my_req_zone: 10 m rate = 1r/s;
...
Server {
...
Location/somedir /{
Limit_req_zone zone = my_req_zone burst = 2;
}
"Limit_req_zone $ binary_remote_addr zone = my_req_zone: 10 m rate = 1r/s" indicates a storage region named my_req_zone. The content of my_req_zone is a remote IP address, the size of my_req_zone is 10 MB, and the average Request Rate in my_req_zone can only be 1 second. "location/somedir/" means to apply rules to the somedir directory; "limit_req_zone zone = my_req_zone burst = 2" indicates the maximum burst Request Rate of 2 IP addresses recorded in the my_req_zone record area in the directory specified by the request per second.
When a connection triggers an appeal rule, Nginx reports "503 Service Temporarily Unavailable" error to stop the user request. A 503 error is returned, which has little impact on the server and only occupies one nginx thread. It is relatively cost-effective.

To test the effect, I put the above Code into the Nginx configuration file, and wrote a PHP file to display phpinfo. In addition, I wrote an html file, which embedded multiple iframe to call the PHP file. When I open this html file, we can see that only one PHP file in the iframe is normally displayed, and other iframe are displayed with 503 errors.


Application Example (Discuz !)
Discuz! Is to use a large number of php Forum programs. Take Discuz! 7.0 as an example, the program directory contains a large number of PHP files that can be directly accessed, but index is the most vulnerable to attacks. php (homepage), forumdisplay. php (panel display), viewthread. php (post display ). Attackers usually initiate a large number of requests to these pages, resulting in the depletion of the number of HTTP server connections, the mysql database stops responding, and the server crashes.
To prevent the above pages from being attacked, we can set the following rules for defense:
Http {
Limit_zone myzone_bbs $ binary_remote_addr 10 m;
Limit_req_zone $ binary_remote_addr zone = bbs: 10 m rate = 1r/s;
...
Server {
...
Location ~ ^/Bbs/(index | forumdisplay | viewthread). php $ {
Limit_conn myzone_bbs 3;
Limit_req zone = bbs burst = 2 nodelay;
Root html;
Fastcgi_pass unix:/dev/shm/php-cgi.sock;
Fastcgi_index index. php;
Fastcgi_param SCRIPT_FILENAME/usr/share/nginx/html $ fastcgi_script_name;
Include fastcgi_params;
}
}
}
After this rule is applied, the index under the bbs directory. php, forumdisplay. php and viewthread. php allows only three connections to one IP address on these pages, and only one request is allowed per second (burst requests can reach two ).
Although such a rule generally does not affect normal users (few people open three pages in one second), to prevent access by users who are quick at hand, you can customize the 503 page in nginx, and prompt the user on the 503 page, and then refresh automatically.
Customize the 503 page in Nginx:
Error_page 503/errpage/503.html;
503 page source code:
<Html>
<Head>
<Title> the page is about to be loaded... </title>
<Meta http-equiv = content-type c>
<Meta name = "ROBOTS" C>
</Head>
<Body bgcolor = "# FFFFFF">
<Table cellpadding = "0" cellspacing = "0" border = "0" width = "700" align = "center" height = "85%">
<Tr align = "center" valign = "middle">
<Td>
<Table cellpadding = "10" cellspacing = "0" border = "0" width = "80%" align = "center" style = "font-family:
Verdana, Tahoma; color: #666666; font-size: 11px ">
<Tr>
<Td valign = "middle" align = "center" bgcolor = "# EBEBEB">
<Br/> <B style = "font-size: 16px"> the page is about to be loaded. </B>
<Br/> the page refresh speed is too fast. Please be patient. The page will be loaded soon...
<Br/> [<a href = "javascript: window. location. reload (); "> <font color = #666666> reload now </font> </a>]
<Br/>
</Td>
</Tr>
</Table>
</Td>
</Tr>
</Table>
</Body>
</Html>

<SCRIPT language = javascript>
Function update ()
{
Window. location. reload ();
}
SetTimeout ("update ()", 2000 );
</Script>

2. Passive defense
Although the active defense has defended against most http get flood attacks, attackers will always find your weak links to launch attacks. So here we will also introduce some methods of passive defense.
1) IP Address
Visitors can access the website through a browser. Generally, there are no more than 20 connections established with the server. We can use scripts to prohibit access from IP addresses with excessive connections.
The following script uses the netstat command to list all connections. an IP address with the highest number of connections is blocked by iptables if the number of connections exceeds 150:
#! /Bin/sh
Status = 'netstat-na | awk' $5 ~ /[0-9] +: [0-9] +/{print $5} '| awk-F ": "-- '{print $1}' | sort-n | uniq-c | sort-n | tail-n 1'
NUM = 'echo $ status | awk' {print $1 }''
IP = 'echo $ status | awk' {print $2 }''
Result = 'echo "$ NUM> 150" | bc'
If [$ result = 1]
Then
Echo IP: $ IP is over $ NUM, ban it!
/Sbin/iptables-I INPUT-s $ IP-j DROP
Fi

Run crontab-e and add the above script to crontab for automatic operation every minute:
* ***/Root/xxxx. sh
Use the AB tool provided by apache to test server pressure:
AB-n 1000-c 100 http://www.xxx.com/bbs/index.php
After the test is complete, we can see the prompt that the IP address is blocked in the system:
[Root @ xxxxxx ~] # Tail/var/spool/mail/root
Content-Type: text/plain; charset = ANSI_X3.4-1968
Auto-Submitted: auto-generated
X-Cron-Env: <SHELL =/bin/sh>
X-Cron-Env: <HOME =/root>
X-Cron-Env: <; PATH =/usr/bin:/bin>
X-Cron-Env: <LOGNAME = root>
X-Cron-Env: <USER = root>

IP: 58.246.xx.xx is over 1047, ban it!
So far, the http get flood defense has been successful again.

2) shield requests based on the signature (better CC attacks)
Generally, the attack request packets initiated by the same CC attack tool are the same and different from normal requests.
When the server encounters a CC attack, we can quickly view the log and analyze the request features, such as User-agent. The following is the User-agent of a CC attack.
Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE 3.01) Cache-Control: no-store, must-revalidate
Almost no normal browser will include the keyword "must-revalidate" in the User-agent. Therefore, we can filter all requests with "must-revalidate" in the User-agent to reject access:
If ($ http_user_agent ~ Must-revalidate ){
Return 403;
}

This article mainly introduces http get flood defense in nginx. If something is wrong, I hope you can raise it to me. At the same time, we also hope that you can put this idea into common web servers such as apache and lighttpd.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.