NAXSI: integrate a WAF for Nginx
Contents
Software version | 0.50 |
---|---|
Operating System | Debian 7 |
Website | NAXSI Website |
Last Update | 10/04/2014 |
Others | Dotdeb |
1 Introduction
NAXSI[1] means Nginx Anti Xss & Sql Injection.
Technically, it is a third party nginx module, available as a package for many UNIX-like platforms. This module, by default, reads a small subset of simple rules (naxsi_core.rules) containing 99% of known patterns involved in websites vulnerabilities. For example, '<', '|' or 'drop' are not supposed to be part of a URI.
Being very simple, those patterns may match legitimate queries, it is Naxsi's administrator duty to add specific rules that will whitelist those legitimate behaviours. The administrator can either add whitelists manually by analyzing nginx's error log, or (recommended) start the project by an intensive auto-learning phase that will automatically generate whitelisting rules regarding website's behaviour.
In short, Naxsi behaves like a DROP-by-default firewall, the only job needed is to add required ACCEPT rules for the target website to work properly.
2 Installation
To install NAXSI, we're going to use DotDeb packages to get a recent version of NAXSI and Nginx. Then you're ready to install:
aptitude |
aptitude install nginx-naxsi python-twisted python-mysqldb nginx-naxsi-ui |
3 Configuration
There are several types of installation and mode. You may for example want:
- Integrate NAXSI as a frontal proxy
- Integrate NAXSI directly on your current Nginx web server
3.1 Global configuration
If you want to enable NAXSI module on your Nginx, simply uncomment this line:
/etc/nginx/nginx.conf |
[...] ## # nginx-naxsi config ## # Uncomment it if you installed nginx-naxsi ## include /etc/nginx/naxsi_core.rules; [...] |
Here is the configuration:
- LearningMode: this is the learning mode. For a first step, do not activate it
- SecRulesEnabled: this will load default rules
- DeniedUrl: where blocked requests should be send (generally used for learning mode)
3.1.1 With proxying
If you don't want to touch to your current setup (Apache for example), you can add Nginx as a reverse proxy and add Naxsi with it:
Now restart Nginx!
3.1.2 Without proxying
If you want to install NAXSI directly on your current Nginx installation, here are the
Now restart Nginx!
3.2 Fail2ban integration
You can mix to fail2ban to definitively block IPs for attackers. How to do it? First install fail2ban:
aptitude |
aptitude install fail2ban |
Then add this NAXSI filter:
/etc/fail2ban/filter.d/nginx-naxsi.conf |
[INCLUDES] before = common.conf [Definition] failregex = NAXSI_FMT: ip=<HOST> ignoreregex = |
When it will find "NAXSI_FMT: ip=" followed by an IP address, it will inform fail2ban daemon that this filter rule match.
And add a section within /etc/fail2ban/jail.conf with:
/etc/fail2ban/jail.conf |
[nginx-naxsi] enabled = true port = http,https filter = nginx-naxsi logpath = /var/log/nginx/*error.log maxretry = 3 |
It will ask to fail2ban to watch at the Nginx errors logs. Each time the filter will match, it will increment a number since it reaches the maximum. Then fail2ban will ask to iptables to block the IP source.
4 Test NAXSI
And try to go to your URL website in adding "?a=%3C" (ex: http://www.deimos.fr/?a=%3C). You should see something like this in your logs:
2014/04/04 20:13:26 [error] 4256#0: *7 NAXSI_FMT: ip=192.168.0.157&server=192.168.0.84&uri=/<>&learning=0&total_processed=47&total_blocked=1&zone0=URL&id0=1302&var_name0=, client: 192.168.0.157, server: localhost, request: "GET /%3C%3E HTTP/1.1", host: "192.168.0.84"
You can see "NAXSI_FMT" which indicates that NAXSI has correctly blocked it!
5 Reporting
You can generate reporting by installing nx_util:
aptitude install git python-geoip git clone https://github.com/nbs-system/naxsi.git cd naxsi/nx_util/ python setup.py install |
You're now ready to generate the report from error logs:
nx_util.py |
/usr/local/bin/nx_util.py -c /usr/local/etc/nx_util.conf -v3 -l /var/log/nginx/*error.log -H /usr/share/nginx/html/naxsi.html |
And if you look at the html result: