Tips and Tricks to Secure Your Nginx Web Server

On this page

Nginx is an open source, lightweight, high-performance the fastest growing web server around the world. Nginx runs on Linux, Windows, Mac OS, and Solaris operating system. NGINX continues to rise in popularity, so means more and more NGINX deployments need to be secured.

In this tutorial, we will explain some popular Nginx server security tips and tricks.

Requirements

A server running Ubuntu 18.04 or Debian 9.

A root password is set up on your server.

Install Nginx

First, you will need to install Nginx to your system. You can install it by running the following command:

apt-get install nginx -y

Once the Nginx has been installed, you can check the status of Nginx with the following command:

Update Nginx

You will need to update your Nginx web server as there are many performance enhancement, new features and security fixes are being added. Most modern Linux distributions will not come with the latest version of nginx into their default package lists. So you will need to upgrade the latest version of nginx via a package manager. You can update your Nginx web server with the following command:

apt-get update -yapt-get install nginx --reinstall -y

Prevent Information Disclosure

First, you will need to prevent the Nginx to disclose their version information.

Secure Nginx with TLS

TLS (Transport Layer Security) is the successor to SSL (Secure Socket Layer). It provides stronger and more efficient HTTPS and contains more enhancements such as Forward Secrecy, compatibility with modern OpenSSL cipher suites, and HSTS. This tutorials shows how to enable a self-signed SSL Certificate in Nginx. If you want to use a let's Encrypt certificate instead, take a look here: https://www.howtoforge.com/tutorial/nginx-with-letsencrypt-ciphersuite/

Generating RSA private key, 1024 bit long modulus
...++++++
.............................++++++
e is 65537 (0x010001)
Enter pass phrase for nginx.key:
Verifying - Enter pass phrase for nginx.key:
[email protected]:~# openssl req -new -key nginx.key -out nginx.csr
Enter pass phrase for nginx.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:Gujarat
Locality Name (eg, city) []:Junagadh
Organization Name (eg, company) [Internet Widgits Pty Ltd]:IT
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:HITESH
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:admin
An optional company name []:IT

Save and close the file, when you are finished. Then, restart Nginx service to apply these changes:

systemctl restart nginx

Next, open your web browser and type the URL http://your-server-ip/test. You will be prompt to enter username and password to access the test directory as shown in the following page:

Congratulations! you have successfully secured your Nginx server on Ubuntu 18.04 server. I hope this will help you to protect your application hosted on the Nginx web server. Feel free to ask me if you have any questions. For more information, you can refer to the Nginx security doc.

This is NOT securing an nginx server. SSL is not security, it is for privacy only.

Using Let's Encrypt would be much better. To accomplish that, acme.sh is much easier to use for requesting and deploying the certs. There are many how-tos for that.

I hoped to learn about deploying u2f for 2FA with this article and for methods to dynamically block myphpadmin requests. BTW, if you use myphpadmin, please only allow localhost connections - for the users to ssh into the machine with a tunnel first. Actually, it would be good to block all .php requests from any outside country, IMHO.

Also blocking WP admin requests and putting those source IPs into a gulag would be helpful.

Or perhaps how to prevent brute force attacks against the normally terrible end-user passwords with fail2ban? A nice regex for this would be good.

Security is more than just blocking internet access to an internet service.