Configuring NAXSI (WAF)
in my previous post the installation of NGINX and NAXSI was described. After successful installation it is time to start the configuration.
as a first step copy core rules, to Nginx config directory.
Configring NGINX
sudo /src/naxsi-0.56/naxsi_config/naxsi_core.rules /etc/nginx/
than create your specific config-file
sudo vi /etc/nginx/naxsi.rules
and add the block of code below that defines some basic protection
SecRulesEnabled;
# LearningMode;
DeniedUrl "/RequestDenied";
error_log /var/log/nginx/naxsi_www.error.ch.log;
## Check Naxsi rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
now it is time to configure NGINX to use NAXSI. This will be done in /etc/nginx/nginx.conf
.
[...]
[...]
http {
[...]
include /etc/nginx/naxsi_core.rules;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
[...]
}
Then in the Server Blocks (Virtual Hosts) config (/etc/nginx/sites-available/yourSite
) include the naxsi.rules
.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.error.ch;
ssl_certificate /etc/letsencrypt/www.error.ch/fullchain.cer;
ssl_certificate_key /etc/letsencrypt/www.error.ch/www.error.ch.key;
include /etc/nginx/snippets/ssl-params.conf;
location / {
include /etc/nginx/naxsi.rules;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
client_max_body_size 50m;
}
After a restart of NGINX the rules are loaded and active.
Testing
the most simple test to see if the WAF is working, is to send a GET request towards the server including some type of SQL Injection.
https://www.error.ch/?TypeId=1 or '1'='1'
will do.
the expected result is that the browser will be redirected to https://www.error.ch/RequestDenied
as configured in naxsi.rules
False positives
For sure the one or other legitimate request will be blocked. To handle false-positives Naxsi logs need to be analyzed and whitelist rules need to be created. Thanks to nxutli this does not cause us any headaches.
cd /opt
git clone https://github.com/prajal/nxutil.git
cd nxutil
python setup.py install
with the command
python nx_util.py -l /var/log/nginx/naxsi_www.error.ch.log -o -p 1
the logfile gets processed and you'll see an output like the one below.
########### Optimized Rules Suggestion ##################
# total_count:62 (13.57%), peer_count:1 (100.0%) | double quote
BasicRule wl:1001 "mz:BODY";
# total_count:58 (12.69%), peer_count:1 (100.0%) | open square backet ([), possible js
BasicRule wl:1310 "mz:BODY";
# total_count:52 (11.38%), peer_count:1 (100.0%) | backslash
BasicRule wl:1205 "mz:BODY";
# total_count:43 (9.41%), peer_count:1 (100.0%) | https:// scheme
BasicRule wl:1101 "mz:BODY";
# total_count:42 (9.19%), peer_count:1 (100.0%) | simple quote
BasicRule wl:1013 "mz:$BODY_VAR:excerpt";
include this whitelist rules into your /etc/nginx/naxsi.rules
and the requests won't be blocked anymore.
managed whitelists
on GitHub you'll also find NAXSI rules provided and maintained by the community.