Tips / Nginx

Nginx Security – The definitive Guide to secure your Nginx server

This Nginx Security tutorial will help you to get a deep level of security on your Nginx server, you will lear how to harden Nginx. It was created with the intention of helping people to avoid security issues at the time they learn how to secure Nginx. If you ever experienced some security issues in your nginx server, this is the definitive guide for you.

Let’s start with our Nginx Security Guide  step by step:

1) Keep Nginx version up to date: this ensures you are running latest version to prevent any security vulnerabilities and bugs that may affect your web server performance/security:

CentOS based systems:

yum update nginx

Ubuntu and Debian:

apt-get upgrade nginx

From source: download latest version from and run:

make install

2) Configure server_tokens: this is called security through obscurity, it’s not security by itself, but I will help you to prevent your attackers to find out which nginx version you are running. Place this inside your nginx.conf:

server_tokens off;

3) Change Nginx response name: with the previous step you can easily hide Nginx version. However, what if you want to hide Nginx name from the web server headers at all… Is it possible, in that case what you need is to change Nginx Version header. You can do it with the above steps:

Edit  the file src/http/ngx_http_header_filter_module.c:

pico +48 -w src/http/ngx_http_header_filter_module.c

Find this lines:

static char ngx_http_server_string[] = "Server: nginx" CRLF;
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;

Change them as follows:

static char ngx_http_server_string[] = "Server: Ninja Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Ninja Web Server" CRLF;

Save and close the file. You are ready to compile Nginx web server.

4) Control Nginx Simultaneous Connections: there is an easy way to control simultaneous connections for sessions or ip address using NginxHttpLimitZone module.

Control using limit_conn directive: this directive assigns the maximum number of simultaneous connections for one session. Once the number is exceeded you may get some “Service unavailable” (503) errors. In this example this allows no more than one simultaneous connection from one address.

limit_zone one $binary_remote_addr 10m 
server {
  location /downloads/ {
  limit_conn one 1;

>> Read more at website

5) Deny Certain User-Agents or Bots: denying user-agents and bots in Nginx it is very easy and can be performed anytime, you can easily block any bots, spammers web-scanners that may attack your server:

## Block download agenta
     if ($http_user_agent ~* LWP::Simple|wget|libwww-perl) {
              return 403;
## Block some nasty robots
     if ($http_user_agent ~ (msnbot|Purebot|Baiduspider|Lipperhey|Mail.Ru|scrapbot) ) {
              return 403;

6) Blocking Referral Spam: this kind of spam can harm your website SEO status and generate negative reputation in your website traffic. With this method you can block most referer spammers with just one easy line:

## Deny referal spam
     if ( $http_referer ~* (jewelry|viagra|nude|girl|nudit|casino|poker|porn|sex|teen|babes) ) {
     return 403; 

7) Block attackers based on GeoIP countries: a good but drastic way to cut down your attackers is blocking using geoip database, so, in this way let’s suppose you are having a heavy attack from china, russia or another country, you can easily block your incomingo connections using GeoIP database provided by MaxMind.

Note: for this to work you need to have GeoIP support enabled on Nginx.

Specify where the GeoIP database is located on your system, you can place this directive inside your http {} configuration block:

geoip_country /etc/nginx/GeoIP.dat;

Next, let’s tell Nginx which countries are gonna be blocked:

if ($geoip_country_code ~ (CN|KR|UK) ) {
  return 403;

This example shows how to block China, Korea and United Kingdom. This security measure should only if you are going under heavy attack (but remember attackers can use proxys too) or if you are 100% sure you don’t recieve any legitimate traffic from those countries.

>>  Remember we have other ways to block countries using firewalls: How to Block a Country using CSF Firewall on Linux

8) Install Mod_Security: it’s one of the newest security features you can apply to your servers, it must be compiled from source, mod_security itself, and then you must add it to your nginx modules re-compiling again. You can follow this instructions to make it work easily

Download, compile and install mod_security

git clone mod_security
cd mod_security
./configure --enable-standalone-module

Compile Nginx from source with modsecurity

tar -xvpzf nginx-1.4.2.tar.gz
cd nginx-1.4.2
./configure --add-module=../mod_security/nginx/modsecurity
make install

>> A detailed guide about this tutorial can be found here: How to install ModSecurity on Nginx

9) Install a SSL certificate on your website sensitive area. If you have any kind of important information such as credit cards, user data or e-commerce stuff, keep them secure by encripting your http connection. The easiest way to install a SSL certificate is to get one from a SSL registrant, then generate the keys in your server and share it with your SSL registrant, then finally install the CRT code on your server and get the SSL online. Example:

Generate key and csr file for your domain

openssl req -nodes -newkey rsa:2048 -keyout /etc/nginx/ssl.key/ -out /etc/nginx/

Send the CSR code to the SSL provider, and then your SSL provider should give you a CRT code, once you got that CRT text, create a new file:

nano -w /etc/nginx/ssl.crt/

Configure SSL support for Nginx

listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl.crt/;
ssl_certificate_key /etc/nginx/ssl.key/;

>> Read more at this how to: How to install a SSL Certificate on Nginx

10) Harden your Nginx SSL/TSL Configuration

You should tweak your Protocol Support, Cipher Suite Configuration, set strong DHE Parameters and enable HSTS mechaism in order yo gain more SSL security. You can see how to secure your Nginx SSL server here: Hardening Nginx SSL/TSL Configuration

11) Stop Hotlinking: don’t let other websites steal your content (images, media files, etc), that will cause additional load to your webserver and also more bandwidth consumption.

Use a location directive inside your Nginx configuration file:

location ~ .(gif|png|jpe?g)$ {
     valid_referers none blocked *;
     if ($invalid_referer) {
        return   403;

>> Read more at this tutorial: How to stop image Hotlinking on Nginx

12) Deny execution of scripts inside certain directories. This can be used to protect your websites from being hacked denying execution of scripts inside certain directories (such as tmp, cache, logs, etc), often the ones that need writing permissions. One easy way to secure is the following:

# deny scripts inside writable directories
    location ~* /(images|cache|media|logs|tmp)/.*.(php|pl|py|jsp|asp|sh|cgi)$ {
    return 403;
    error_page 403 /403_error.html;

>> Read more at: How to deny script execution inside writable directories


Do you know any other Nginx security tips? Please comment below and share it with our community.

Popular search terms:

  • nginx security
  • secure nginx
  • hardening nginx
  • compile nginx security

Esteban Borges

Linux Geek, Webperf Addict, Nginx Fan. CTO @Infranetworking

  • I wish you mentioned about Naxsi too.

  • admin

    Never knew about it, thanks for sharing, it looks interesting! Let me test it out and then I will add it.


  • love_decay

    tried compiling with naxsi but i kept getting errors

  • Range

    1, I got error: nginx: [emerg] “if” directive is not allowed here in /etc/nginx/nginx.conf
    How to fix it?

    2, Where to find ngx_http_header_filter_module.c
    I don’t see it at all