NGINX: Reject Unwanted Traffic

Awhile back, I posted a guide about Migrating from Apache to NGINX and in one of the steps I mistakenly wrote that you should remove the default NGINX config file. At the time, I believed this would block any unwanted traffic to your web server such as web traffic directed at the server's IP address, but I've since learned that NGINX will actually redirect that traffic to the first server block it loads in your other config files.

If you really want to block unwanted traffic to your NGINX server, you need to reconfigure the default NGINX config to explicitly do so which I'll be showing you in this guide.

*NOTE: I've updated the Migrating from Apache to NGINX guide to reference this article. My apologies to anyone who was mislead by my oversight.


Backup the default..default config

The first thing you should do is backup the default config located at /etc/nginx/sites-available/default just in case you have the need to reinstate or refer to it later.

sudo mv /etc/nginx/sites-available/default /etc/nginx/sites-available/default.ORIG

Create the new default..default config

Now we'll create our own default config which will reject any web traffic targeted at the server's IP or domains not hosted by the server.

sudo nano /etc/nginx/sites-available/default

Inside the nano text editor, copy the following into the default config file.

server {
    listen 80 default_server;
    listen 443 default_server ssl;

    return 444;

    ssl_ciphers aNULL;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

A little explanation on what this config does, in short, it will intercept any unwanted web traffic directed at the server's IP or any domain that isn't explicitly hosted by NGINX and return a status code of 444.

Status code 444 is an NGINX specific code which instructs the server to close the connection without sending a response back to the client. This is better than returning a status code of 403 or 404 as not responding to the client saves your server resources.

The ssl cipher & the self-signed certificate in the config are only needed because NGINX requires them when configuring an SSL listener. No clients will actually ever see this cert as the connection will be dropped as soon as it's attempted.

*NOTE: If the ssl-cert-snakeoil pem and key are missing from your server, they can be created automatically if you install the ssl-cert package. Just run sudo apt install ssl-cert.

Let NGINX know about it

After creating the default config, you'll want to enable if it's not enabled already.

sudo ln -s ../sites-available/default /etc/nginx/sites-enabled/default

You'll get an error if the default config is already enabled.

A Quick Check & Bounce

Now run a quick check of the default config.

sudo nginx -t

As long as there are no errors, you're good to restart NGINX and start rejecting that unwanted traffic.

sudo systemctl restart nginx

*NOTE: If your server doesn't run systemd, your restart command may be different. You may need to either run /etc/init.d/nginx restart or service nginx restart instead.

Please Share Me, I'm Lonely