How to Prevent a DDoS Attack with Nginx

Nginx Prevent Ddos Attack Featured

Distributed Denial of Service or “DDoS” attacks sequester a server’s resources through abusive digital communication tactics. These types of attacks are the computer world’s organized raid. Numerous bothersome anti-like actions combine to create formidable enough threat to halt a seasoned server in its tracks. Worst of all, there happen to be multiple means of waging such guerilla web warfare against unsuspecting servers. Luckily, servers can be configured to fight back.

Nginx, a highly popular server system for Unix machines, comes with enough built-in functionality to greatly limit the effectiveness of DDoS attacks.

Here are a few effective options for handling such threats on an Nginx-powered server:

Back Up Your Configuration File

Before you change any settings, make sure you make a quick backup of your server’s configuration. The following command works for this:

Nginx Copy Config

Once done, you’re ready to move on.

Checking Traffic

Keeping an eye on your server’s traffic makes it easier to optimize security and implement additional tactics down the line. Nginx has a module made specifically for this.

Set Up a Status Page

Nginx typically comes with a module named “stub status” (http_stub_status_module) that allows for this kind of functionality to be integrated into your server environment rather easily. First, check for it using the following command:

Nginx Find Module

Or pipe the above to grep to find it faster:

Nginx Grep Module

If your output looks like the output above, you’re good to go; otherwise, you will need to reinstall or recompile your Nginx installation with the module included.

Setting up a status page you can check is simple, but you’ll also need to limit access to it to just the minimum (your machine) to keep it secure. Start by opening your server’s main config file found at “/etc/nginx/nginx.conf.”

Nginx Config File

Open it and add the following code to the “http directive” to activate the module, substituting your own info instead of “localhost,” “/status_page” and “127.0.0.1”:

Note: you will need sudo privileges to modify this file.

Nginx Status Code

Now test your configuration:

Nginx Test Config

If all is well, send your server a reload signal:

Nginx Reload Server

To access your status page, visit your server_name location followed by “/status_page” in a web browser or by using a command-line tool like curl. (This is helpful if your browser’s cache doesn’t update automatically.) The following is the curl command to access the page in our examples:

Nginx Curl Status

In the browser, the above looks like the following image.

Nginx Browser Status

Check Access Logs

If you notice abnormal traffic when checking the status page configured above, it may be a good idea to check out the server’s access log. This can be found at “/var/log/nginx/access.log.” The log lists HTTP methods used, date/time of access attempts, user agents and the pages accessed.

Nginx Access Log

Limiting Connections

Among the many useful tactics worth trying for staving off DDoS attacks, one of the simplest and most effective is the limiting of incoming traffic rates.

Ideally, you should curb access just enough to prevent malicious bots from overpowering your server at inhuman rates while maintaining reasonable rates for human clients. In Nginx, this can be accomplished with the limit_req_zone and limit_req directives. The following code sets memory and rate constraints for use in any location that your server is configured to show:

“Zone” specifies the name and size (in Megabytes in this case) of the space in memory where user requests are stored. “Rate” establishes the total number of requests Nginx will accept every second (10 in this example). Think of this code as a rule and the code that follows as the use of that rule:

The code above actually does a bit more than just implement our limiting rule; it also adds a small queue of up to twenty requests to softly handle legitimate connections that show up a little quicker than normal, exceeding both the rule and the queue results in a 503 error for the client. Here’s what both directives look like in nginx.conf:

Nginx Limit Code

Blacklisting IP Address

If you can get ahold of the IP address that is DDoSing your server, you can simply blacklist it and drop any connection originating from this IP address.

Add the following code to your server directive:

Blocking request to certain files

If the DDoS attack is targeting certain files on your server – for example, the xmlrpc.php file on WordPress (this is a heavily targeted file in most WordPress servers) – you can block all requests to it. Add this code to your server directive:

Follow the above procedure, and you will be able to limit most DDoS attacks. Be sure to check out the Nginx documentation for additional security options you can put in place.

3 comments

  1. I suppose none of the thousands of people whose servers fell victim to DDoS attacks used Nginx. That’s like saying that you got infected with a virus because you did not use Kaspersky or Norton. Nginx is not the end all be all in server protection. It is only one of many products.

    BTW – your color scheme for displaying examples makes the text very hard to read

  2. IMHO, using webservers, AV and other reactive techniques to go against bad guys is the wrong approach.
    DDoS etc. should be catched at the Firewall level.
    On the other hand, what one can also do is to use the system response codes to catch the script kiddies and bad guys,.
    By default, one webpage serves well known webpages. If someone access a page causing a 404 or 403, send it to the blacklist. If someeone uses a wrong type in a GET/POST request, it is not because the app has an issue but because a script kiddie sent a probing argument. Send it to the blacklist too.,
    Only these 2 things already catch around 200 to 500 site-probing scripts a day, thus enter 200 to 500 IP addresses to my dynamic blacklist. That really Helps

  3. “If you can get ahold of the IP address that is DDoSing your server, you can simply blacklist it and drop any connection originating from this IP address.”

    The first D in DDoS stands for Distributed…

    Not only do DDoS attacks not come from a single IP, by definition, but most often, they would come from a botnet, where the source IPs are not even close to being in the same subnet, so blocking subnets is less than useless, as is trying to block things by manually entering each address that’s attacking you into your nginx config file, one at a time. As Smurphy pointed out, this is better handled by a firewall, which can dynamically block requests. At best, you can stop a persistent DoS attack with your suggestion.

Leave a Comment

Yeah! You've decided to leave a comment. That's fantastic! Check out our comment policy here. Let's have a personal and meaningful conversation.