Security

5 tips for better NGINX security that any admin can handle

If you're about to deploy an NGINX server, you might want to take a few steps to make sure it is secure out of the gate. Jack Wallen offers up five easy tips that can give your security a boost.

NGINX continues to rise in popularity. According to the October, 2017 Netcraft stats, it has nearly caught up with Apache—meaning more and more people are making use of this lightweight, lightning fast web server. That also means more and more NGINX deployments need to be secured. To that end, there are so many possibilities.

If you're new to NGINX, you will want to make sure to deploy the server in such a way that your foundation is safe. I will walk through five ways to gain better security over NGINX that won't put your skills or resolve to too much of a test. These are tips every NGINX admin should know and employ:

1. Prevent information disclosure

Open up a terminal window and issue the command:

curl -I http://SERVER_ADDRESS

Chances are you'll see something similar to that shown in Figure A.

Figure A

Figure A

Our server information for all to see.

That information could invite attack. How? Because attackers can make use of that information to forge a hack for your system. To prevent that, we're going to configure NGINX to not display either the NGINX release or the hosting platform information. Open up the configuration file with the command sudo nano /etc/nginx/nginx.conf. Scroll down until you see the line:

# server_tokens off;

Uncomment that line by removing the # character, like so:

server_tokens off;

Save and exit the file. Once NGINX is reloaded with the command sudo systemctl reload nginx, the curl -I command will no longer show the NGINX version or the host platform (Figure B).

Figure B

Figure B

We've made it more challenging for a hacker to gain easy access to our server.

2. Hide php settings

If you make use of NGINX with PHP, you cannot hide the PHP information via the NGINX configuration file. Instead, you have to edit the php.ini file. Issue the command sudo nano /etc/php/7.0/fpm/php.ini and make sure expose_php is set to off. The configuration option falls around line 359. Once you've changed that configuration, save and close the file. Reload NGINX and your PHP information will be hidden from prying eyes.

3. Redirect server errors

Next we need to configure the error pages in the default sites-enabled configuration, such that error 401 (Unauthorized) and 403 (Forbidden) will automatically redirect to 404 (Not Found) error page. Many believe handing out errors 401 and 403 is akin to exposing secure information—so rerouting them to error 404 offers a bit of security-by-obfuscation, in similar fashion to hiding server information.

To do this, issue the command sudo nano /etc/nginx/sites-enabled/default. In the resulting configuration file, scroll down to the server { section and add the line:

error_page 401 403 404 /404.html; 

Save and close the file. Reload NGINX with the command sudo systemctl reload nginx and your server will now redirect 401 and 403 errors to 404 errors.

4. Secure sensitive directories

Say you want to block certain directories from all but specific addresses. Let's say you have a Wordpress site and you want to block everyone but your local LAN addresses from accessing the wp-admin folder. And let's say your local LAN IP address scheme is 192.168.1.0/24. To do this, issue the command sudo nano /etc/nginx/sites-enabled/default. Scroll down to the server { location and add the following under the location / directive:

location /wp-admin {
allow 192.168.1.0/24;
deny all;
}

Once you reload NGINX, if anyone attempts to access the wp-admin folder, they will be redirected to the error 403 page, unless you've configured NGINX to redirect to error 404—at which point it will redirect to the error 404 page.

5. Limit the rate of requests

It is possible to limit the rate NGINX will accept incoming requests. For example, say you want to limit the acceptance of incoming requests to the /wp-admin section. To achieve this, we are going to use the limit_req_zone directory and configure a shared memory zone named one (which will store the requests for a specified key) and limit it to 30 requests per minute. For our specified key, we'll use the binary_remote_addr (client IP address). To do this, issue the command sudo nano /etc/nginx/sites-enabled/default. Above the server { section, add the following line:

limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;

Scroll down to the location directive, where we added the wp-admin section. Within that directive, add the following line:

limit_req zone=one;

So our wp-admin section might look like:

location /wp-admin {
allow 10.10.1.0/24;
deny all;
limit_req zone=one;
}

Save and close the default file. Reload NGINX with the command sudo systemctl reload nginx. Your wp-admin section will now only allow 30 requests per minute. After that 30th request, the user will see the following error ( Figure B).

Figure B

Figure B

Our service has reached its rate limit.

You can set that rate limit on any directory that needs protected by such a mechanism.

NGINX a bit more secure

Congratulations, your NGINX installation is now a bit more secure. Yes, there are plenty more ways in which you can achieve even more security, but starting here will be serve as a great foundation.

Also see

nginxhero.jpg
Image: NGINX

About Jack Wallen

Jack Wallen is an award-winning writer for TechRepublic and Linux.com. He’s an avid promoter of open source and the voice of The Android Expert. For more news about Jack Wallen, visit his website jackwallen.com.

Editor's Picks

Free Newsletters, In your Inbox