Serve NGINX the Right Way

A few things to consider when configuring NGINX Web Server

A brief history of the . . . Web

Few decades ago, 31 years to be precise, the World Wide Web was invented by an English engineer, Tim Berners-Lee. During the course of developing the first web page, he wrote the first ever web serverhttpd”. Fast forward to today, in the 21st century… it seems almost impossible to live without the Web. It remains one of the greatest inventions of all time even though it is just few decades old. Follow this link to learn more about how the Web work.

“The Web as I envisaged it, we have not seen it yet. The future is still so much bigger than the past.” — Tim Berners-Lee

Web Servers Explained.

Web Servers are simply computer programs that delivers websites. They communicate with web browsers using Hypertext Transfer Protocol (HTTP). In most cases, the contents (such as text, video, images, stylesheets, application data etc.) of websites are encoded in Hyper Text Markup Language (HTML).

Any computer that host websites must have a web server software. There are several web servers out there, some of which run across multiple platforms, such as Windows, Linux or OSX. The leading includes Apache, Microsoft Internet Information Server (IIS) and Nginx. In a recent study, statistics shows that open source web servers power over 80% of websites and web applications. According to Netcraft, the most popularly used open source web server is Nginx.

Image for post
Image for post
March 2020 Web Server Survey — Netcraft

This article focuses on how to use and properly configure one of prominent web server, NGINX.

The NGINX Web Server

Nginx (pronounced as engine-x) is a popular, a high performance HTTP and reverse proxy web server originally written by Igor Sysoev. When setting-up and configuring web servers, there are several things to consider depending on the scenario. Important criteria are performance and security.

Image for post
Image for post
Image from Kinsta

To install the open source NGINX software, follow the steps below; click this link for more information.

$ sudo apt-get update
$ sudo apt-get install nginx

Once installed, navigate to nginx config directory. Remove the default configuration file (/etc/nginx/conf.d/default.conf).

$ cd /etc/nginx/conf.d# create a file called test1.conf
$ touch /etc/nginx/conf.d/test1.conf

Now include the following configuration inside the test1.conf file.

server { 
# allow both http and https
listen 80;
listen 443 ssl;
server_name example.com; root /home/ubuntu/public_html;

# ...

# more nginx configuration...
# ...

location / {
proxy_pass http://localhost:8080/;
}
}

Some NGINX performance and security practices

Improve your NGINX performance and security with the following:

There is no reason to use HTTP. Force everyone to use HTTPS by default. Insert the below configuration just top of the test1.conf file.

server {
listen 80;
server_name
example.com;
return 301
https://$server_name$request_uri;
}
server {
# use https by default
listen 443 ssl;

...
}

By default, Nginx allows for a wide variety of cryptographic ciphers to be used in TLS connections. Some of these ciphers are legacy offerings that are weak or prone to attack (eg. logjam), and should be therefore removed. However, removing the default cipher may cause some connectivity problems for older platforms such as Windows XP or older versions of Internet explorer.

Check MozillaWiki — Security/Server Side TLS to see which ciphers are suitable.

To maintain a high-performance environment, it is recommended to cache existing TLS connections so that each new request from a client (i.e web browser) does not need to perform the full TLS handshake.

ssl_session_cache shared:SSL:50m;
ssl_session_timeout 5m;

Most modern web browsers already supports TLSv1.2 and above.

ssl_protocols TLSv1.2;

One of the best practices added not so long ago is to secure Diffie-hellman. Generate Unique DH Group by using OpenSSL;

openssl dhparam -out /path/to/dhparams.pem 4096

Modify test1.conf (for all configuration, edit /etc/nginx/nginx.conf) and add the following to the server block;

ssl_dhparam /path/to/dhparams.pem;

The most common methods on the Internet are GET and POST. Web server methods are defined in RFC 2616. In most cases, web servers require not all methods, but only a few of them. Others methods that are not required should be disabled. The following will filter and only allow GET, HEAD and POST methods:

# Only allow these request methods
# Do not accept DELETE, SEARCH and other methods
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405;
}

To set for all clients, edit /etc/nginx/nginx.conf and set the buffer size limitations.

# Size Limits & Buffer Overflowsclient_body_buffer_size  1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
  1. client_body_buffer_size 1k — (default is 8k or 16k) The directive specifies the client request body buffer size.
  2. client_header_buffer_size 1k — Directive sets the header buffer size for the request header from client. For the overwhelming majority of requests a buffer size of 1K is sufficient. Increase this if you have a custom header or a large cookie sent from the client.
  3. client_max_body_size 1k– Directive assigns the maximum accepted body size of client request, indicated by the line Content-Length in the header of request. If the size is greater than the given one, then the client gets the error “Request Entity Too Large” (413). Increase this when you are getting file uploads via the POST method.
  4. large_client_header_buffers 2 1k — Directive assigns the maximum number and size of buffers for large headers to read from client request. By default the size of one buffer is equal to the size of page, depending on platform this either 4K or 8K, if at the end of working request connection converts to state keep-alive, then these buffers are freed. 2x1k will accept 2kB data URI. This will also help combat bad bots and DoS attacks.

To learn more about buffer overflow attacks, click here.

You can limit access to directory by ip address to /docs/ directory:

location /docs/ {
# block one workstation
deny 192.168.1.1;

# allow anyone in 192.168.1.0/24
allow 192.168.1.0/24;

# drop rest of the world
deny all;
}

You can inject X-FRAME-OPTIONS in HTTP Header to prevent a clickjacking attack.

add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options nosniff;

Inject HTTP Header with X-XSS protection to mitigate Cross-Site scripting attack.

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

Last but not least, make sure to continuously keep Nginx and all software up to date, all the time. Apply patches according to version or distribution of the softwares. Use the code below, if your server is running on a Debian or Ubuntu Linux (apt-get command/apt command to apply patches):

$ sudo apt-get update
$ sudo apt-get upgrade

Additional Security Measures

A WAF (web application firewall) is a software designed to helps protect web applications by filtering, monitoring and inspecting HTTP/HTTPS traffic, deny malicious requests, and generally act as an additional layer of security.

Nginx Amplify is a native tool for monitoring Nginx. It is a SaaS tool that can be used to monitor up to five servers for free (subscriptions are available for larger numbers of servers).

Check Nginx and audit log files. Log will provide some understanding on what sort of attack was thrown. Analysing the logs will let you know if the current security protocol is enough or if the server requires fortification.

Following the steps and configuration above will surely improve the performance and security of your Nginx web server. Nevertheless, there are several more tactics and techniques out there you can implore.

Some additional resources:

Reference

Software engineer, runner, hiker, fitness enthusiast. https://namieluss.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store