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:
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup-original
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 -v
Or pipe the above to grep to find it faster:
nginx -V 2>&1 | grep -o with-http_stub_status_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.”
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”:
server { listen 80; listen [::]:80; server_name localhost; ## # Status Page Settings ## location /status_page { stub_status on; allow 127.0.0.1; allow ::1; deny all; }
}
Note: you will need sudo privileges to modify this file. Now test your configuration:
sudo nginx -t
If all is well, send your server a reload signal:
sudo systemctl reload nginx
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:
curl localhost/status_page
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.
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:
limit_req_zone $binary_remote_addr zone=speedbump:10m rate=10r/s;
“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:
limit_req zone=speedbump burst=20;
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:
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:
location / { deny 123.123.123.0/28; # ...
}
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:
location /xmlrpc.php { deny all;
}
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.