Nginx Web Server is one of the two most widely used web servers in the world. It cemented its position as the perfect web server application since its inception 15 years ago. Nginx is known for its superior performance, which is roughly 2.5 times faster than Apache. It is best suited to websites that deal with a bulk amount of static assets but can also be used for general-purpose websites. It has outgrown its intended use a long time ago and is now used for a plethora of tasks like reverse proxying, caching, load balancing, media streaming, and more.
Facts About Nginx Web Server
Nginx is pronounced as Engine X and has diverse use cases in the modern web scene. It can be used for powering a wide array of web services such as microservices, cloud computing, and API gateways alongside its standard role as a web server. We’ll continue our discussion assuming the Nginx web server is running on Linux or similar UNIX systems.
1. The Basics of Nginx
It’s necessary you get the basics right before moving forward with any technical topic. So, here we present some fundamental things regarding Nginx. There are several flavors of this application, including paid and free variations. The open source Nginx server is, however, the most used by developers simply because it offers almost every functionality you could think of and doesn’t come with a price tag.
Once installed, you can run the sudo service Nginx to start to fire up your server. The server configuration files are stored in either /usr/local/nginx/conf/ or /etc/nginx/ directories. The web documents are stored in either /usr/local/nginx/html/ or /var/www/html directories. You can stop a running server by issuing the command sudo nginx -s stop.
2. Turning On SELinux
SELinux(Security-Enhanced Linux) is a compelling feature of the Linux kernel, which provides greater control over system security via access control security policies. It’s a common practice to enable SELinux in systems that intend to run dedicated web servers. You need to utilize the getsebool -a command for this.
$ sudo getsebool -a | less $ sudo getsebool -a | grep off $ sudo getsebool -a | grep on
The above commands will provide you with information about what boolean settings are turned on and off. For maximum security, you should disable all entities that aren’t required by your system. These settings are known collectively as SELinux booleans. Setting appropriate values for these variables will make your system much more secure to prevent standard web attacks.
3. Removing Unwanted Nginx Modules
Despite the lightweight nature of the Nginx default server, it is always a good idea to remove any unwanted modules that your server does not need. This will significantly minimize the memory footprint and make your server faster than usual. Additionally, it limits the capabilities of your server, so even if a malicious user gains access to your server, it will take a lot of time and skill to gain total control of the system itself.
The below commands demonstrate how to disable SSI and the auto index module that is installed by default with your Nginx binary.
sudo ./configure --without-http_autoindex_module --without-http_ssi_module sudo make sudo make install
You can use the following command to view the modules that can be turned off when compiling your Nginx server.
sudo ./configure --help | less
4. Minimizing Networking Privileges
Minimizing the networking privilege of your web server also helps in increasing security. You can leverage the mount options for this job. Essentially, this means that you can serve all your web pages in separate partitions. To do this, you’ll need to create additional partitions and mount them at the /nginx location. Make sure to mount them with noexec, nodev, and nosetuid permissions.
You can do this by editing the file /etc/fstab. Edit this with your favorite editor and add the following at the end of the file.
LABEL=/nginx /nginx ext3 defaults,nosuid,noexec,nodev 1 2
If your system is running on a different filesystem, replace the ext3 with the name of that filesystem. You will require sudo privileges to do this.
5. Hardening Network Settings for Nginx
You can further solidify the security of your system by configuring some kernel and networking settings. Edit the /etc/sysctl.conf file and add the following lines to harden your server’s system.
# prevent smurf attacks net.ipv4.icmp_echo_ignore_broadcasts = 1 # stopping being a router net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # prevent alteration of routing tables net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0
There are a plethora of available options you can use to secure your system. They will come in handy in case somebody breaches your server’s security.
6. Changing the Nginx Version Header
Changing the version header of your Nginx default server is a great way to prevent wannabe hackers from breaking into your system. Many applications can be fed fuzzy data to gain the version header of the server software. Malicious users often do this to find out exact server information so that they can target and dig specific vulnerabilities for them.
Find the below lines from the file src/http/ngx_http_header_filter_module.c.
static char ngx_http_server_string[] = "Server: nginx" CRLF; static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
Replace them with the following lines.
static char ngx_http_server_string[] = "Server: Ninja Web Server" CRLF; static char ngx_http_server_full_string[] = "Server: Ninja Web Server" CRLF;
This shows false information about the server version to potential attackers.
7. Preventing Buffer Overflows
Buffer overflows occur when code snippets write data beyond its boundary. It’s a classic software engineering problem that is leveraged by experienced hackers. If devised successfully, buffer overflow attacks can allow unwanted parties to enter and take control of your system. You can prevent these attacks to a large extent by limiting buffer sizes for all clients. Add the following to your nginx.conf file.
# limit buffer sizes client_body_buffer_size 1K; client_header_buffer_size 1k; client_max_body_size 1k; large_client_header_buffers 2 1k; # set timeouts client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10;
These options essentially change the default value of these parameters and decrease the attack surface. You can play with them to find out what suits your Nginx Web Server.
8. Controlling Simultaneous Connections
No matter whether you’re running the Nginx default server or something else, it’s always a good practice to limit the number of simultaneous connections. It can be useful in many situations, such as preventing Denial of Service attacks and better load balancing. The NginxHttpLimitZone module allows admins to limit the simultaneous connections for specific sessions or IP addresses.
limit_zone slimits $binary_remote_addr 5m; limit_conn slimits 5;
Add the above lines in your nginx.conf file. It limits the number of allowed simultaneous connections to 5 per IP. You can easily replace this value to fit your requirements.
9. Filtering Domain Access
One of the most common types of problems faced by modern Nginx Web Servers is botnets. They often scan servers randomly and try to find all associated domains. You can deny them easily by adding the following lines to your nginx.conf file.
# encompass client requests to specified domains if ($host !~ ^(url.domain|www.url.domain|url.subdomain.domain)$ ) { return 444; }
Adding these lines to this file allows client requests for only the mentioned domains. You can specify multiple domains by utilizing the or “|” operator.
10. Limiting Available Methods
There are several HTTP methods used for fetching web pages based on user requests. Some of them are GET, POST, PUT, and DELETE. However, there are a bunch of additional methods. It’s always a good idea to restrict these methods for a user. This will help in decreasing unwanted data breaches and adds an extra layer of security. Add the following lines to your Nginx configuration.
# allow only GET && HEAD && POST if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; }
Now, users can’t perform a delete or search request on your server. Only the GET, HEAD, and POST methods are available to them. You can find more information about HTTP methods here.
11. Restricting User Agents
User agents are computer programs that allow users to interact with a service. Ubuntu web browsers are the primary web user agents in my system.
Sometimes, you may want to restrict specific user agents from accessing your server, like those headless browsers that are continually looking to scrape data from your website. This also comes in handy when blocking botnets since they often use the same user agent.
# block download agents if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; }
Adding these to your Nginx configuration will block known download agents like wget and BBBike. The below lines will block some known robots called msnbot and scrapbot.
#block robots if ($http_user_agent ~* msnbot|scrapbot) { return 403; }
You can block any user agents you want. However, be cautious, or else you might block legitimate traffic to your Nginx web server.
12. Blocking Referral Spam
Referral Spam is a common problem faced by many web servers today. It is a technique used to advertise specific websites to the search engine so that they get more traffic to their site. It is particularly dangerous for high-load web servers since it may cause severe damage to a site’s ranking. Thankfully, you can block most of these spams by adding only a few lines to your Nginx configuration.
#deny certain referers if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) { # return 404; return 403; }
Add the above lines to your nginx.conf file for blocking some of the most common referral spam. You can add more words to these lines as required.
13. Preventing Image Hotlinking
Image hotlinking has become a common practice for many web admins. In this practice, admins often use personalized images from your webserver to serve their client requests. This can be seriously harmful if not taken care of, as your web server may be responsible for delivering image assets requested by users of another web server. You can easily prevent this and save your precious bandwidth, as shown below.
# stop deep linking or image hotlinking location /images/ { valid_referers none blocked www.example.com example.com; if ($invalid_referer) { return 403; } }
Adding these lines to your Nginx configuration file will block the image requests from the mentioned web server. This way, your Nginx default server will only deliver images to authentic client requests. Additionally, you may want to use the Nginx map to block image hotlinking for a large number of domains.
14. Restricting Directory Access
You can often find tons of web pages that don’t restrict their directories. They are exceptionally vulnerable to malicious users since they allow them to traverse the site as they want, which often leads to further escalation of site privileges. The below snippet will show you how to block specific users, allow particular IP ranges, and deny all others to the directory /docs/.
location /docs/ { # block one user deny 192.168.1.1; # allow anyone in 192.168.1.0/24 allow 192.168.1.0/24; # drop rest deny all; }
Add these to your Nginx configuration and replace /docs/ with directories that contain sensitive information. You may also protect your directories with passwords, as shown below. First, create a password file and add a USER
$ sudo mkdir /usr/local/nginx/conf/.htpasswd/ $ sudo htpasswd -c /usr/local/nginx/conf/.htpasswd/passwd USER
Now add these lines to the nginx.conf file.
# password rotect /personal-images/ and /delta/ directories location ~ /(personal-images/.*|delta/.*) { auth_basic "Restricted"; auth_basic_user_file /usr/local/nginx/conf/.htpasswd/passwd; }
15. Configuring SSL for Nginx Web Server
SSL(Secure Sockets Layer) has become the de-facto security standard of modern web servers. Any site that doesn’t implement this technology is deemed unsafe by many security professionals. Thankfully, it’s straightforward to configure and maintain SSL security for Nginx servers.
There are many ways to set SSL for a website. Admins can create self-signed SSL certificates, use popular certificate authorities, or set SSL reverse proxies. If you’re relatively new to web server administration, we advise you to utilize the popular Let’s Encrypt certification. It’s a free and easy-to-use certification authority that provides secure SSL/TLS certificates. We’ll show you how to do this in a separate guide.
16. Increasing PHP Security
PHP is one of the most used server-side languages and serves a considerable amount of webpages on the internet. It is, however, quite old and prone to several security vulnerabilities. So, if you’re using PHP on your Nginx server, you should always be cautious and implement specific security standards. For example, adding the below lines to your /etc/php.ini file will enhance security by a significant factor.
# reject crucial functions disable_functions = phpinfo, system, mail, exec # max execution time for scripts, in seconds max_execution_time = 30 # max memory limit for scripts, in MB memory_limit = 4M # max allowable POST data post_max_size = 4M # restrict PHP information expose_php = Off # log errors log_errors = On # enable SQL safe mode sql.safe_mode = On
There are many more security-enhancing instructions you can add to this file to make your server harm-resistant.
17. Enhancing Nginx Default Server’s Security
Linux users can easily enhance the overall security of Nginx servers by using manual configuration. As mentioned earlier, you should turn on SELinux in any machine that runs Nginx for optimum protection. Setting up the correct permissions on /nginx is also extremely important. To find what permissions users have on your Nginx documents, run the below command.
$ sudo find /nginx -user nginx $ sudo find /usr/local/nginx/html -user nginx
Make sure only the root or owner of these documents have write access to them. It can be a lifesaver in case of future break-ins since attackers will require more time and expertise to gain further privileges to the machine. Use the below command to remove any unwanted archives created by vi or other Linux text editors.
$ sudo find /nginx -name '.?*' -not -name .ht* -or -name '*~' -or -name '*.bak*' -or -name '*.old*' $ sudo find /usr/local/nginx/html/ -name '.?*' -not -name .ht* -or -name '*~' -or -name '*.bak*' -or -name '*.old*'
18. Auditing Nginx Logs
Checking the log files of your Nginx server will provide you with valuable information such as users’ interests, unwanted authentication attempts, and so on. The ability to monitor server logs appropriately is a helpful asset to webmasters for this reason.
You can find the log files of your server in the /usr/local/nginx/logs directory. The below commands show us how to grep them for sensitive information.
$ sudo grep "/login.php??" /usr/local/nginx/logs/access_log $ sudo grep "...etc/passwd" /usr/local/nginx/logs/access_log $ sudo egrep -i "denied|error|warn" /usr/local/nginx/logs/error_log
You can also install or build specific auditing applications that will check Nginx logs in real time and keep you informed about what’s going on in your server.
19. Running Nginx in Containers
Most professionals advise users to run their Nginx server from inside a dedicated container. Containers are isolated environments on the server machines that are built to keep processes separate from each other. You can easily install and run your Nginx server in containers like LXD, Docker, FreeBSD jails, XEN, and other Linux virtual emulators. These are collectively known as chroot jails among webmasters.
A dedicated container for your server will contain all the resources required to run the server and handle client requests. The advantage you get is the isolation of this server from the rest of your machine. So, even if someone gains unauthorized access to your server through some loopholes, they won’t be able to control your system core.
20. Some Helpful Suggestions
You can easily configure the different aspects of your Nginx web server by modifying the centralized configuration file. There are plenty of things to do. For instance, use the following to avoid clickjacking.
add_header X-Frame-Options SAMEORIGIN;
The next line will disable content types sniffing by some browsers.
add_header X-Content-Type-Options nosniff;
To enable cross-site scripting (XSS) filters, you can use
add_header X-XSS-Protection "1; mode=block";
You can find numerous helpful features in the Nginx documentation. However, make sure you understand what they do before applying anything. Otherwise, your site may face downtime due to misconfiguration.
Ending Thoughts
There are too many reasons for the popularity of Nginx web servers. It has become the best server software due to its rich feature set and a seemingly unlimited number of configuration abilities. We often see many admins merely installing and using the Nginx default server. They’re missing a lot of features and flexibility offered by Nginx in this way. That’s why our editors have taken the liberty to outline these best practices before you. Hopefully, we were able to fulfill your interest and help you in learning something new.
At point 4, to mount the partition with the new options without rebooting, you can use: sudo mount -a. Then to verify the mount options, ensure that the partition is mounted with the correct options, doing: mount | grep /nginx. You should see output similar to : /dev/sbx on /nginx type ext3 (rw, nosuid, nodev, noexec). At first try I had to chroot into my system to fix fstab cause I made a typo. Make sure you edit fstab well before reboot. 👍
great article. I liked how the author described most things from a security POV
Great dive into Nginx. Been using it for years and im bookmarking this to improve my best practices.
Thanks for going into details, and high level tips.