NGINX — The Right Way
Introduction
Nginx (Engine-X) is the most popular open source web server. Nowadays, nginx is also used as a reverse proxy, HTTP cache, media streaming, load balancer and more.
It was originally created by a Igor Sysoev, a Russian engineer in October 2004. He created nginx as an attempt to solve the C10K Problem, which is a problem related to concurrently handling large number of connections “10K”.
Due to its robust ability to handle large number of concurrent connections, speed and many more, it is the web server of choice of various tech-giants like Google, Microsoft, Facebook, Apple, Twitter, Intel, Cisco, Adobe, VMWare and more.
Best Security Practices
We must secure our nginx web server properly before making it live. We must have a basic understanding of how nginx works and its configuration settings.
The main configuration file for nginx is nginx.conf which is located at /etc/nginx or /usr/local/etc/nginx depending on whether it is installed system-wide or for local user only.
We need to make some security checks in this main configuration file for best security practices. Also, for virtual hosts, we need to make changes to their configuration files, typically located inside the sites-enabled directory.
In this article, we are going through the best security practices that we can adopt while using NGINX.
Controlling Buffer Overflow Attacks
We can minimize the risks of such attacks by setting the buffer size limitations for all clients in nginx.conf file.
Following directives can be used for this:
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
where,
client_body_buffer_size: client request body buffer size (default 8k or 16k)
client_header_buffer_size: client request header buffer size (1k is enough)
client_max_body_size: max accepted body size of client request
large_client_header_buffers: max number and size of buffers for large header
Limit Available HTTP Methods
There are various HTTP methods like GET, POST, HEAD and many more. If any of the methods is not required by the server, we must disable it from configuration.
This can be done by modifying nginx.conf file and adding the following lines under server block:
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405; # METHOD NOT ALLOWED
}
Or, we can add the following condition in the location block of the virtual host configuration file to filter out HTTP methods.
location / {
limit_except GET HEAD POST { deny all; }
}
In the above example, we can see that request method any other than GET, HEAD and POST will be returned with 405 message.
Keep your software updated
We must update the webserver from time to time to get latest updates, enhanced performance and security patches. Updating the system will do the work.
sudo apt update && sudo apt upgrade # Ubuntu
sudo yum update && sudo yum upgrade # RHEL/CentOS
Use of SSL Certificates
HTTP protocol is a plain text protocol and thus anyone can eavesdrop the information from in between. We must make use of HTTPS protocol which can be achieved by using SSL certificates.
SSL certificates helps to secure the content by cryptographically encrypting it using various algorithms. We can generate a free SSL certificate for our domain through Let’s Encrypt.
To setup the free SSL certificate using Let’s Encrypt, use the following link:
https://www.nginx.com/blog/using-free-ssltls-certificates-from-lets-encrypt-with-nginx/
Disable ‘server_tokens’ directive
This directive shows the version of the nginx webserver that is in use. This information is present in the HTTP response in server header.
If this is enabled, there might be a chance of information disclosure. Thus, we must disable this directive in nginx.conf file by setting:
server_tokens off;
SSL and Cipher Suites Configuration
Using older SSL/TLS protocol (v1, 1.1, 1.2) may lead to attacks such as BEAST attack. Therefore, it is recommended to use newer version of TLS protocol by adding the following in nginx.conf file as:
ssl_protocols TLSv1.2 TLSv1.3;
Also, cipher suite configuration should also be done so that no vulnerable suites are supported. Cipher suites are the set of algorithms that help secure a network.
We can add the following directive that will let decide that the ciphers to be used are made on server-side and not on client-side.
ssl_prefer_server_ciphers on;
Configure log files
By default, all the server access and error logs are located inside /var/log/nginx directory as access.log and error.log files.
If we have to monitor the logs continuously for all virtual hosts, it is better to make a separate access and error log files for each host. This will help in discovering any error or attack attempt quickly and effectively.
We can do this by setting access_log and error_log directive in the vhosts file. They can be set within an http, server or location block.
access_log /var/log/nginx/<accessLogFileName>.log
error_log /var/log/nginx/<errorLogFileName>.log
Configuring security headers in NGINX
Various security headers can be included in the nginx configuration file to secure the web server from various attacks. Some of the security headers are:
X-Frame Options
This response header is used to prevent clickjacking attacks. Basically, this header indicates whether the browser is allowed to render the page in <frame> or <iframe>.
add_header X-Frame-Options "SAMEORIGIN";
Now, this will allow the browser to load the resources only from same origin.
X-Content-Type-Options
This header is used to protect against MIME sniffing.
add_header X-Content-Type-Options "nosniff" always;
Strict-Transport-Security
HTTP Strict Transport Security (HSTS) is a method to ensure that the website is only accessible using a secure HTTPS connection.
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
The above header caches the information for the max-age period (typically 31536000 seconds ~ 1 Year). Also, the option includeSubdomains tells the browser that this policy is also applied to all of its subdomains too.
Content-Security-Policy
The CSP header enables us to control the resources which a user agent is allowed to load for a page.
add_header Content-Security-Policy "upgrade-insecure-requests;"
upgrade-insecure-requests directive instructs to treat all insecure URLs of the website (HTTP) as though they are replaced over HTTPS. Various other directives can also be used with CSP.
X-XSS-Protection
This header helps to prevent against Cross-site Scripting Attacks (XSS).
add_header X-XSS-Protection "1; mode=block";
The NGINX server is now properly secured and ready to serve. However, there are many other security headers and directives in nginx to use according to the need.
Happy Learning :)