Security

How to install and enable ModSecurity with NGINX on Ubuntu Server

If you're looking for a more secure NGINX installation, Jack Wallen shows you how to install it with ModSecurity, for a hardened web server.

Image: Jack Wallen

ModSecurity is toolkit for real time web application monitoring, logging, and access control. This open source Web Application Firewall (WAF) module does an outstanding job of protecting web servers (Apache, NGINX, and IIS) from attacks that target potential vulnerabilities in various web applications. ModSecurity handles tasks like:

  • Real-time application security monitoring and access control
  • Full HTTP traffic logging
  • Continuous passive security assessment
  • Web application hardening

I want to walk you through the process of installing both ModSecurity and NGINX, so you can ensure your web server is better capable of standing up against certain attacks. The installation process is a bit complicated and handled completely through the command line. I'll be demonstrating on the Ubuntu Server 16.04 platform, installing the latest releases of each. During the installation, you will want to check with each to make sure the instructions below match the latest release available (and modify the steps as needed). As of this writing, the latest release of NGINX is 1.13.4.

With that said, let's begin.

Installing dependencies

The first thing we'll do is install the necessary dependencies. Before we do that, it's important to stop and disable Apache. If Apache is running, NGINX cannot start. To disable Apache, issue the following commands;

sudo systemctl stop apache2
​sudo systemctl disable apache2

Do note, the above commands will not remove Apache, rather they will simply stop the server and then disable it from starting at boot. With that out of the way, let's install the dependencies. Go back to your terminal window and issue the command:

sudo apt-get install -y git build-essential libpcre3 libpcre3-dev libssl-dev libtool autoconf apache2-dev libxml2-dev libcurl4-openssl-dev automake pkgconf

Compile ModSecurity

The first thing to do is to download the nginx_refactoring branch of ModSecurity. This is done with the following commands:

cd /usr/src
​git clone -b nginx_refactoring https://github.com/SpiderLabs/ModSecurity.git

With the download complete, it's time to compile with the commands:

cd ModSecurity
​./autogen.sh./configure --enable-standalone-module --disable-mlogcmake

Compile nginx

Next we download and compile NGINX. This is where it's important to make sure you're downloading the latest version (find out here). As I'll be working with NGINX 1.13.4, the command to download will be:

cd /usr/src
​sudo wget http://nginx.org/download/nginx-1.13.4.tar.gz

Now we extract the file with the command:

sudo tar xvzf nginx-1.13.4.tar.gz

Before we compile, let's change to the root user with the command sudo -s. Once you have root privileges, the commands to compile are:

cd nginx-1.13.4/
​./configure --user=www-data --group=www-data --add-module=/usr/src/ModSecurity/nginx/modsecurity --with-http_ssl_module
​make
​make install

Now we must modify the default nginx user with the command:

sed -i "s/#user nobody;/user www-data www-data;/" /usr/local/nginx/conf/nginx.conf

Test the installation with the command:

/usr/local/nginx/sbin/nginx -t

You should have returned a successful test (Figure A).

Figure A

Figure A

NGINX tests out fine.

Creating a systemd unit file

We need to make sure NGINX can start at boot. To do this, we'll create a new systemd file with the command sudo nano /lib/systemd/system/nginx.service with the following contents:

[Service]
Type=forking
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
KillStop=/usr/local/nginx/sbin/nginx -s stop

KillMode=process
Restart=on-failure
RestartSec=42s

PrivateTmp=true
LimitNOFILE=200000

[Install]
WantedBy=multi-user.target

Save and close that file. To start, stop, and restart nginx, the commands will now be:

sudo systemctl start nginx.service
sudo systemctl stop nginx.service
sudo systemctl restart nginx.service

Save and close that file. To start, stop, and restart NGINX, the commands will now be:

sudo systemctl start nginx.service
​sudo systemctl stop nginx.service
​sudo systemctl restart nginx.service

Configure ModSecurity and NGINX

Now it's time to configure. The first thing we'll do is configure NGINX. Issue the command sudo nano /usr/local/nginx/conf/nginx.conf. Within this file, look for the section:

location / {
    root   html;
    index  index.html index.htm;
}

Change the above section to:

location / {
    ModSecurityEnabled on;
    ModSecurityConfig modsec_includes.conf;
    root   html;
    index  index.html index.htm;
}

Save and close that file.

Next we enable the OWASP core rules. To do this, issue the command sudo nano /usr/local/nginx/conf/modsec_includes.conf and add the following content:

include modsecurity.conf
include owasp-modsecurity-crs/crs-setup.conf
include owasp-modsecurity-crs/rules/*.conf

Save and close that file.

For our next step, we're going to import the necessary ModSecurity configuration files. To do this, issue the following commands:

sudo cp /usr/src/ModSecurity/modsecurity.conf-recommended /usr/local/nginx/conf/modsecurity.conf
sudo cp /usr/src/ModSecurity/unicode.mapping /usr/local/nginx/conf/

Enable the SecRuleEngine option in the modsecurity.conf file with the command:

sudo sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /usr/local/nginx/conf/modsecurity.conf

Finally, add the OWASP ModSecurity Core Rule Set with the commands:

cd /usr/local/nginx/conf
sudo git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
sudo cd owasp-modsecurity-crs
sudo mv crs-setup.conf.example crs-setup.conf
sudo cd rules
sudo mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
sudo mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

Opening the firewall

Before we test NGINX/ModSecurity, we need to open up our firewall with the commands:

sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw default deny
sudo ufw enable 

Testing the setup

Finally, we can test our setup. On your server, issue the command:

sudo tail -f /usr/local/nginx/logs/error.log

Open up a browser and point it to:

http://SERVER_IP/?param="><script>alert(1);</script>

Where SERVER_IP is the IP address of your server.

Watch the tail from your command window as your browser loads the NGINX welcome screen. Errors should appear and be outputted in the tail (Figure B).

Figure B

Figure B

ModSecurity is working!

Congratulations, you now have NGINX running ModSecurity.

Also see

About Jack Wallen

Jack Wallen is an award-winning writer for TechRepublic and Linux.com. He’s an avid promoter of open source and the voice of The Android Expert. For more news about Jack Wallen, visit his website jackwallen.com.

Editor's Picks

Free Newsletters, In your Inbox