Home Linux Top 15 Nginx Server Security Hardenings

Top 15 Nginx Server Security Hardenings

by Lakindu Jayasena
3.5k views 13 mins read
Nginx Security Hardenings

Nginx is the most widely used free and open-source web server nowadays. It is lightweight, fast, robust, low resource consumption, and supports the major operating systems. But with the default configurations are not secure and need some extra tweaks to protect the web server and give it the much-needed security to prevent attacks and breaches. In this article, I will give you tips on Nginx server security, showing how to secure your Nginx installation.

If you did not read my previous posts regarding Nginx Best Practices on Initial Setup and Nginx Performance Tuning, please first go and read them to get a basic idea about the Nginx web server and its configurations.

Install the SSL/TLS Certificate

HTTP is a plain text protocol and it transfers the data t between the client and the server in clear text hence, an important step in web server security is to have an SSL/TLS certificate. The SSL/TLS certificate is a cryptographic digital certificate that encrypts the traffic between the client (web browser) and the server. By doing the encryption is secured and kept safe from attackers who might try to eavesdrop and steal confidential information such as usernames, passwords, and credit card information using man in the middle attacks.

For your website, you can use freely available certificates like LetsEncrypt, ZeroSSL, SSL For Free and etc… which valid for 90 days, and every 90 days you have to renew it. Or else you can buy a paid certificate from DigiCert, Comodo like well-known sites.

In Nginx server you can configure SSL/TLS certificate as follows:

 server { listen 443 ssl; ssl_certificate /etc/nginx/ssl/bundle.pem; ssl_certificate_key /etc/nginx/ssl/mytechnix.com.key; } 

Once you have it installed, you can verify the strength of the SSL encryption by testing your domain on SSL Labs. The results are shown below.

Disable Weak and Old SSL/TLS Protocols

SSL and its successor, TLS are widely used protocols designed to secure the transfer of data between the client and the server through encryption, integrity, and authentication protection. Having weak SSL/TLS protocols (SSLv2.0, SSL v3.0, TLSv1.0, and TLSv1.1) may vulnerable and lead to attacks such as BEAST (Browser Exploit Against SSL/TLS), POODLE (Padding Oracle On Downgraded Legacy Encryption) and CRIME (Compression Ratio Info-leak Made Easy) attacks. Therefore recommend to use newer and secure SSL/TLS protocols.

To configure it, add the following directive inside the server section of the Nginx configuration file:

 ssl_protocols TLSv1.2 TLSv1.3; 

Disable Weak Cipher Suites

A cipher suite is a combination of algorithms that provide encryption, authentication, and integrity. To secure the transfer data, TLS/SSL uses one or more cipher suites. These are using during the SSL/TLS negotiation as well as for the transfer of data.

EncryptionRC4, 3DES, AES
Message Integrity HMAC-SHA256, HMAC-SHA1, HMAC-MD5
AuthenticationRSA, DSA, ECDSA
Key ExchangeRSA, Diffie-Hellman, ECDH, SRP, PSK

Weak and old cipher suite configurations may provide a false sense of security and make your website vulnerable to attacks. If you use them, the attacker may intercept or modify data in transit.

Depending on your use case or OpenSSL and Nginx versions, you may need to use different cipher suite configurations. Therefore you may use the Mozilla SSL Configuration Generator to obtain an optimal cipher suite using different browsers like modern, intermediate, or old.

In the Nginx configuration, you can change it on inside server block:

 ssl_prefer_server_ciphers on; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; 

Use Secure Key Exchange Mechanism

The purpose of the DH parameter allows exchanging a secret that will be used to encrypt a transcript of messages within a session. Ephemeral DH offers forward security, meaning that the session key is deleted upon session termination. Hence an attacker could not retrieve the messages exchanged between two parties for more than the last session.

Generate Unique DH Group with at least 2048 bits by using OpenSSL:

 openssl dhparam -out /etc/ssl/dhparam.pem 2048 

Now in your server block, add this line:

 ssl_dhparam /etc/ssl/dhparam.pem; 

Remove Unwanted HTTP Methods

Commonly used HTTP methods are GET and POST. Allowing other methods like TRACE, DELETE, PUT and OPTIONS are risky because that can allow attackers to launch Cross-Site Tracking attacks and steal the cookie information from your website. So it is recommended to disable unwanted & unused HTTP methods.

If you add the following directive inside the location block of the Nginx virtual configuration file, the server will only allow GET, HEAD, and POST methods only.

 location / { limit_except GET HEAD POST { deny all; } } 

Another approach is you can add as a condition inside the server block in the Nginx configuration file and it will allow only GET, HEAD, and POST methods and filter out any other HTTP methods by issuing a 444 No Response status code.

 if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } 

Control Buffer Overflow Attacks

Buffer is a small storage location inside system memory that temporally accommodates data as is it begin transfers from one memory location to another. When the data size exceeds the capacity of the buffer size, a buffer overflow occurs. So the attacker can exploit this vulnerability to inject malicious code that can compromise a system. As security practice, it is recommended to do a few tweaks to the Web server to mitigate these types of issues by adding the lines of code below to the nginx.conf file.

 client_body_buffer_size 1K; client_header_buffer_size 1k; client_max_body_size 1k; large_client_header_buffers 2 1k; 

CSP and XSS Protection

The Content Security Policy (CSP) is an extra layer of security that helps to mitigate certain attacks such as XSS and script injection attacks or packet sniffing attacks. CSP can tell the browser that it can only download content from the domains you explicitly allow, including Javascript and CSS files. You can add a CSP header as follows.

 add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; 

Cross-Site Scripting (XSS) is another type of web attack that allows attackers to inject and execute malicious code or browser-side script into the trusted website. As an instance when a visitor came to the site, the script is downloaded and can access various web browser resources such as cookies and session tokens and etc.

To prevention measures against such type of attack is to append the line below in the nginx.conf file.

 add_header X-XSS-Protection "1; mode=block"; 

Avoid Click-jacking Attacks

Click-jacking is another well-known web application vulnerability. This vulnerability is used by the attacker to force the user to click without the user’s consent, leading to redirecting to an unknown website. The X-Frame -Option in HTTP response header can be used to indicate whether or not a web browser should load a page in frame or iframe.

Therefore append the X-Frame-Options in the HTTP header in the nginx.conf file as shown below. This will instruct a browser to load the resources only from the same origin.

 add_header X-Frame-Options "SAMEORIGIN"; 

Disable content-type Sniffing

Content sniffing, also known as MIME (Multipurpose Internet Mail Extensions) sniffing, is the technique used for inspecting the content of a byte stream to determining the file format of the data within it. This can also cause a security vulnerability because an attacker can leverage MIME sniffing to send an XSS (Cross-Site Scripting) attack.

As an example, if your site allows users to upload media content like images, an attacker might be able to upload a malicious image file that contains some JavaScript code. When a browser do content sniffing might then be tricked into executing that malicious file. To prevent content sniffing attacks, set the X-Content-Type-Options response header to nosniff and this tells browsers to avoid guessing response types and to depend only on the Content-Type header.

 add_header X-Content-Type-Options nosniff; 

Prevent Image Hotlinking

Hotlinking means someone from an external party makes a link to your site images and display it on their own site. This may result in an increase in your bandwidth use (which you pay for) while the other person happily displays the image.

As an example, let’s assume you have a directory named images inside your document root which stores all the images you used in your site. To prevent other parties from using your images, you will need to insert the following location block inside your virtual host configuration.

 location /images/ { valid_referers none blocked www.mytechnix.com mytechnix.com; if ($invalid_referer) { return 403; } } 
 #You can also specify the image extensions as shown: valid_referers blocked www.mytechnix.com mytechnix.com; if ($invalid_referer) { rewrite ^/images/uploads.*\.(gif|jpg|jpeg|png)$ http://www.mytechnix.com/banned.jpg last } 

HTTP Strict Transport Security

HSTS feature allows clients (web browsers) to only connect using HTTPS, but this is a different concept from the return and redirect methods explain in earlier posts. When the browser receives the HSTS header, it will not try to contact the server using HTTP for a specified period of time also prevent users from accepting insecure SSL certificates.

To enable HSTS add the following headers to your Nginx configuration file:

 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; 

Allow access to domain name only

If bot making random server scans for all domains, just deny it. You must allow only for configured virtual host domain and you don’t want to allow requests using IP address. Then you can include the following section inside the virtual host configurations.

 if ($host !~ ^(mytechnix.com|www.mytechnix.com)$ ) { return 301 https://mytechnix.com$request_uri; } 

Deny automated user agents

To keep protect your server from bots, scripts, and other automated methods of web page retrieval, explicitly deny those user agents. As an example applications like wget can retrieve entire document root directory structure, making them useful DoS attackers or simply accessing secured files on the website.

Append the following line in the nginx.conf file to prevent this:

 if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; } 

Prevent Server Information Disclosure

The default configuration of the Nginx server, server_tokens directive displays the Nginx version number on all automatically generated error pages and as well as the HTTP response header. This could cause information disclosure to unauthorized parties and they can gain knowledge about the version of Nginx which lead to narrows the focus for anyone trying to attack. Add the following line to your nginx.conf file to disable publishing this kind of info.

 server_tokens off; 

Keep Nginx Up to Date

Last but not least, recommended to keep your Nginx server updated to the latest and stable version as there are a lot of performance improvements, security fixes, and new features are being added. Nginx security advisories can be found here and the latest updates can be found here.

Configuration File as a Summary

If you followed all above steps, you should end up with a final configuration like the following one:

 #Mian nginx.conf File #====================== #Prevent Server Information Disclosure server_tokens off; #Avoid Click-jacking Attacks add_header X-Frame-Options SAMEORIGIN; #Disable content-type Sniffing add_header X-Content-Type-Options nosniff; #CSP and XSS Protection add_header X-XSS-Protection "1; mode=block"; add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; #HTTP Strict Transport Security add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; #Control Buffer Overflow Attacks client_body_buffer_size 1K; client_header_buffer_size 1k; client_max_body_size 1k; large_client_header_buffers 2 1k; 

 #Virtual Host Configuration File #=============================== server { listen 80 default_server; listen [::]:80 default_server; server_name mytechnix.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name mytechnix.com; #Install the SSL/TLS Certificate ssl_certificate /etc/nginx/ssl/bundle.pem; ssl_certificate_key /etc/nginx/ssl/mytechnix.com.key; #Use Secure Key Exchange Mechanism ssl_dhparam /etc/nginx/ssl/dhparam.pem; ssl_prefer_server_ciphers on; #Disable Weak and Old SSL/TLS Protocols ssl_protocols TLSv1.2 TLSv1.3; #Disable Weak Cipher Suites ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; #Remove Unwanted HTTP Methods if ($request_method !~ ^(GET|HEAD|POST)$ ){ return 444; } #Prevent Image Hotlinking location /images/ { valid_referers none blocked www.mytechnix.com mytechnix.com; if ($invalid_referer) { return 403; } } #Allow access to domain name only if ($host !~ ^(mytechnix.com|www.mytechnix.com)$ ) { return 301 https://mytechnix.com$request_uri; } #Deny automated user agents if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; } } 

That was a wrap-up of some of the important key measures you can take to secure your Nginx web server from common exploitation techniques. This will go a long way in secure your website content and protect the visitors on your site as well.

Related Articles

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.