Nginx is the fastest growing web server in the industry and currently holds 31% of the market share.
It was originally released in 2004 and has since earned an excellent reputation and serves the servers of many high-load Russian sites such as Yandex, VKontakte, Mail.Ru, Rambler, etc.
There’s a reason for this – Nginx is fast.
In this article, I will share some important guides for securing an Nginx web server. So, let’s begin.
SSL / TLS
SSL Certificate Implementation
The first step in web security is to implement SSL so that you can access web applications over https and add a layer of encryption when communicating.
- Use OpenSSL to generate CSR with 2048 bits and sha-2
openssl req -nodes -new -sha256 -newkey rsa:2048 -keyout bestflare.key -out bestflare.csr
- The above command will generate CSR files and key files on current job directly. Don’t forget to change the file name .csr and .key .
Get a CSR signed by a CA, and once you get a certificate, you can implement it in Nginx as shown below.
- Login to nginx server
- Go to conf folder where you have ssl.conf file .
Note. For a default installation on Linux, this file will be located in /etc/nginx/conf.d.
- Edit the file and add the following to allow Nginx to listen on port 443
server {
listen 443 ssl;
server_name bestflare.com;
ssl on;
ssl_certificate /opt/cert/bestflare.pem;
ssl_certificate_key /opt/cert/bestflare.key;
}
Note : don’t forget to change the path to the certificate and key file.
- Save your configuration and restart Nginx. The SSL certificate has been successfully deployed.
Disable SSL 3 and leave only TLS
SSL 3 is vulnerable and we will only allow secure TLS.
- Edit ssl.conf file and add below in server block
ssl_protocols TLSv1.2;
Save the ssl.conf file and restart Nginx
Disable weak encryption suites
Weak cipher suites can lead to vulnerabilities such as an outage and therefore we only need to allow strong ciphers.
- Add the following to the server block in your ssl.conf file
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA HIGH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
- Save the file and restart Nginx
Install Chain Certificate
The lack of a chain certificate also affects the overall rating, and this can lead to an error when viewed in a modern browser like Chrome. You need to get a chain certificate.
- Add the contents of the chain certificate to the site certificate as shown below. In my example, this would be /opt/cert/bestflare.pem
- Save the file and restart Nginx
Web Application Security
The default Nginx configuration is not perfect and can have many vulnerabilities, so we are hardening them to make it secure.
Disable unwanted HTTP methods
In most cases, you just need to receive an HTTP GET, HEAD & POST request in your web application. Allowing TRACE or DELETE is risky as it could allow a cross-site tracking attack and potentially allow a hacker to steal cookie information.
- Modify default.conf and add the following below the server block
if ($request_method !~ ^(GET|HEAD|POST)$ )
{
return 405;
}
Save the file and restart Nginx. Now 405 Not Allowed will be displayed if someone tries to use TRACE, DELETE, PUT, OPTIONS.
Chandans-iMac:~ chandan$ telnet bestflare.com 80
Trying 128.199.100.162...
Connected to bestflare.com.
Escape character is '^]'.
TRACE / HTTP/1.1
Host: testing
HTTP/1.1 405 Not Allowed
Server: nginx
Date: Sat, 11 Jul 2015 06:04:34 GMT
Content-Type: text/html
Content-Length: 166
Connection: close
Clickjacking attack
You can enter the X-FRAME-OPTIONS HTTP header in order to prevent an attack using the Click-Jacking .
This is achieved by adding below to the nginx.conf file
add_header X-Frame-Options "SAMEORIGIN";
The header will tell the browser to load resources ONLY from the same source.
X-XSS Protection
Implement an X-XSS protected HTTP header to prevent cross-site scripting attacks.
Modify your default.conf or ssl.conf file to add the following
add_header X-XSS-Protection "1; mode=block";
- Save the config file and restart Nginx.