NGINX — The Right Way

Ankit Ojha
5 min readJul 14, 2022

--

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 :)

--

--

Ankit Ojha

DevOps Engineer | SRE | Cyber Security | Linux | Cloud Enthusiast