No announcement yet.

How to Install Naxsi WAF for Nginx and Virtualmin on Ubuntu 16.04

  • Filter
  • Time
  • Show
Clear All
new posts

  • How to Install Naxsi WAF for Nginx and Virtualmin on Ubuntu 16.04

    Protect your websites from Cross-site scripting and SQL Injection. Install and configure Naxsi Web Application Firewall for Nginx and Virtualmin

    A web application firewall AKA WAF is a must have piece of software for any website. They help protect websites against application specific attacks. Which unfortunately out of the scope of traditional firewall software like UFW or iptables. There are a few WAF software out there. I like Naxsi because it’s easy to setup and use. Also it’s free. So today we’ll install Naxsi WAF for Nginx and Virtualmin on Ubuntu 16.04.

    Naxsi is specially designed for Nginx. It is a third-party module for Nginx. According to the developers, Naxsi doesn’t rely on a signature base like an antivirus, and thus cannot be circumvented by an “unknown” attack pattern. It has simple rules that can prevent 99% of known patterns involved in website vulnerabilities. This tutorial will help you install Naxsi WAF for Nginx and Virtualmin on Ubuntu 16.04 and protect all your hosted websites against application specific attacks.

    It doesn’t matter if you already have websites hosted on your VPS or not. But you need to pay extra attention to details if you’re going to do this on a production server. And you should also know the risks. Because we’re about to recompile nginx.

    Recompile Nginx with Naxsi WAF

    Let’s start by installing dependencies,
    apt install libpcre3-dev libssl-dev libxml2-dev libxslt-dev libgd-dev libgeoip-dev

    Virtualmin installation script installs Nginx version bundled with Ubuntu 16.04. Which is Nginx v1.10.3 at the moment of writing. You can check Nginx version currently installed with following command.
    nginx -v

    Once you have the nginx version to recompile, navigate to opt directory.
    cd /opt

    Download nginx. You need to change nginx version number on following command if it’s different from the one installed on your system.

    Extract downloaded file,
    tar -xvzf nginx-1.10.3.tar.gz

    Now download Naxsi,
    git clone

    Navigate to extracted nginx directory,
    cd nginx-1.10.3

    Now it’s time to recompile nginx with Naxsi. But before that, we need to find original configure arguments for nginx. Following command should do it.
    nginx -V

    You need to copy these configure arguments to a text editor. Because we need to make some adjustments to these arguments and build a new configure command. Following are the adjustments you need to do.
    1. Add ./configure to the beginning of configure arguments.
    2. Remove all dynamic modules. These are the arguments that begin with –add-module=
    3. Add new argument –sbin-path=/usr/sbin/nginx towards the beginning.
    4. Add new argument –add-module=/opt/naxsi/naxsi_src/ towards the beginning.

    The two new arguments we added enable Naxsi and make sure Nginx paths are kept same as before. Keeping nginx paths same as before make sure Virtualmin compatibility with recompiled nginx. My configure command looks something like below after the adjustments.

    ./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --add-module=/opt/naxsi/naxsi_src/ --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/ --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads

    Once you have your configure command ready, go ahead and stop nginx.
    service nginx stop

    And then execute the configure command. Once it’s completed, install nginx with following commands.
    make install

    Now start nginx,
    service nginx start

    Check the configure arguments again and verify changes are there.
    nginx -V

    If everything is okay, lock nginx so the package manager won’t overwrite our custom binary.
    apt-mark hold nginx

    That’s it for installation. Now let’s configure and enable Naxsi.

    Configure Naxsi WAF with Nginx on Ubuntu 16.04

    Naxsi WAF is installed but not enabled yet. We need to copy it’s core ruleset to nginx config directory first.
    cp /opt/naxsi/naxsi_config/naxsi_core.rules /etc/nginx

    Now enable Naxsi WAF by including core rules on the http block of nginx main configuration. So open nginx main configuration file.
    nano /etc/nginx/nginx.conf

    Add following line within the http {} block.

    include /etc/nginx/naxsi_core.rules;

    Here’s how it looks on my VPS,


    Save and close the file. Next we’ll create a new file to hold Naxsi options for
    nano /etc/nginx/

    Paste the following options,

    # Sample rules file for vhost.
    DeniedUrl "/RequestDenied";
    ## check rules
    CheckRule "$SQL >= 8" BLOCK;
    CheckRule "$RFI >= 8" BLOCK;
    CheckRule "$TRAVERSAL >= 4" BLOCK;
    CheckRule "$EVADE >= 4" BLOCK;
    CheckRule "$XSS >= 8" BLOCK;
    error_log /var/log/virtualmin/example.com_log;

    These options enable Naxsi WAF in learning mode. You need to put a # in front of the line that says LearningMode; to disable learning mode and start blocking connections.

    The file has to be loaded on a per location basis for a server block. Server blocks are inside each domain’s configuration file. Let’s enable Naxsi for,
    nano /etc/nginx/sites-available/

    And add following line to the main location block,

    include /etc/nginx/;
    Here’s how my main location block looks like after including


    Save the file and restart nginx,

    service nginx restart

    That’s it. You need to include a file in each server block to enable Naxsi for that server block. All events will be recorded to the error log file specified in file. You can have separate rules file per each server block. That way you’ll get separate error logs for each of your domains and toggle Learning Mode On and Off for each individual domain.

    That concludes the instructions to install Naxsi WAF for Nginx and Virtualmin.
    Last edited by hotfuzz; 09-22-2019, 02:31 PM.