Naxsi, du WAF pour votre Nginx

Quand je dis WAF, je parle bien sûr de Web Application Firewall , pas de Wife Acceptance Factor , (quoi que parfois cela peut être étrangement lié :D )

Je tiens toute suite à éviter toute polémique sur l’image illustrant l’article, c’est juste que cela m’a fait bien rire d’imaginer Ivan Drago en Nginx russe prêt a affronter les scripts kiddies capitalistes :) (mais cela ne fait rire que moi, je sais :p)

Mais revenons au sujet de ce billet.

Si vous êtes un peu proche de la sécurité des « serveurs web », vous avez vite compris que le simple firewalling tel qu’on le connaît devient de moins en moins adapté aux formes d’attaques présentes sur le Nain Ternet.

Au bout d’un moment, il va falloir ajouter quelques filtrages de niveau 7 pour regarder et analyser ce qu’il se trame (humour), dans nos requêtes http.

Pour les sites « web », il s’agit principalement d’insérer un firewall applicatif dédié au requêtes http, on appelle cela un WAF.

Si votre serveur http est Apache, vous utilisez sûrement le module mod_security (un must have sur tout serveur de ce nom), ou encore Ironbee (je vous en reparlerais peut être un autre jour, étant grand fan d’ Ivan Ristic, l’auteur justement de modsecurity).

Vous utilisez IIS ? Je ne comprends même pas ce que vous faites sur ce blog… :(

Donc, avec Apache, je jouais avec mod_security ou Ironbee mais j’utilise aussi Nginx depuis des années, le serveur http venu du froid qui pourrait bien vous faire revoir votre vision des serveurs http.

Bref, ce n’est pas un débat Apache VS Nginx (chacun a ses avantages/inconvénients et cela dépend vraiment de la façon dont vous utilisez votre serveur http (même si Nginx ça roxx sa maman en slip).

Donc, même si Nginx supporte plutôt très bien certains types d’attaque (qui a dit Slowloris ? :p), votre site web, lui, a peut être quelques failles de type injection SQL, Cross-Site scripting ou Cross-Site Request Forgery.

Et ModSecurity ne fonctionne pas sous Nginx.

Heureusement, il existe un WAF dédié pour Nginx, et pas des moindres.

Ce WAF s’apple NAXSI, et il est issu d’une société qui n’est pas dans le genre « plaisantin » quand il s’agit de sécurité informatique : NBS-SYSTEM

Pour preuve, vous trouverez chez eux des gens plutôt velus qui entre autres fondent des groupuscules intégristes que l’on vénère ou l’on détéste :)

(même GuiguiAbloc en parle, c’est pour dire :p)

Vous me direz, « mouais, c’est sympa ton truc, mais dans la vrai vie, ça a fait ses preuves ? »

Et bien, disons qu’il y en a qui ont plutôt bien apprécié son efficacité...

Tout de suite, on se dit, « ok, ca a quand même subit un bon test IRS (In Real Situation) »

Si je vous parle avec autant de passion de Naxsi, c’est que ce WAF a une approche plutôt originale du firewall.

Alors que ses confrères se basent surtout sur des signatures (comme un antivirus), Naxsi, lui, fonctionne comme un filtre bayésien (et oui, comme les anti-spams).

Il détecte les chaînes de caractères suspectes et donne un « score » qui, quand il devient trop élevé, renvoi le « visiteur » vers une page de votre choix (403, ou pire, vers votre NIDS pour analyse ultérieure ;) )

Je vous invite bien entendu à vous goinfrer du Wiki du projet.

Suffit la causette, comment on met cela en place ?

Je suppose que vous avez télécharger les sources de Nginx ainsi que la dernière version stable de Naxsi (0.43-1 a ce jour).

On détargézède tout cela et on compile Nginx avec Naxsi en tant que module.

Attention : Spécifier bien le add-module Nasxi en premier ! Nginx est sensible à l’ordre de chargement de ses modules.

Exemple :

./configure --prefix=/opt/nginx -add-module=../naxsi-0.43-1/naxsi_src/ --with-http_ssl_module --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --without-http_uwsgi_module --without-http_scgi_module

.Bien sûr je vous laisse adapter à votre configuration :)

Copier le fichier naxsi-0.43-1/naxsi_config/naxsi_core.rules dans votre répertoire conf de Nginx (par exemple), et on prépare la configuration de Nginx.

...
 
http {
include        /opt/nginx/conf/naxsi_core.rules;
 
...
 
server {
proxy_set_header Proxy-Connection "";
listen       *:80;
access_log  /opt/nginx/logs/nginx_access.log;
error_log  /opt/nginx/logs/nginx_error.log debug;
 
location /RequestDenied {
proxy_pass http://127.0.0.1:4242;
}
 
location / {
include    /opt/nginx/conf/monsite.rules;
...

Petite explication dans le texte.

Au niveau du block http de Nginx on charge les filtres de Naxsi (/opt/nginx/conf/naxsi_core.rules)

Puis au niveau du virtualhost, on définie une destination « RequestDenied » où seront envoyées toutes les requètes interceptées par Naxsi.

On se fait un petit fichier incluant les règles nouvellement apprises :

include    /opt/nginx/conf/monsite.rules

Fichier qui contient :

LearningMode;
SecRulesEnabled;
DeniedUrl "/RequestDenied";
 
include "/tmp/naxsi_rules.tmp";
 
## check rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;

La ligne « proxy_pass http://127.0.0.1:4242″ est un petit plus de Naxsi : l’apprentissage.

Et oui, comme tout filtre bayésien, Naxsi est capable d’apprendre des requètesiqui sont légitimes pour votre site web, ce la s’appelle une liste blanche (white list).

Pour cet apprentissage (learning mode), il vous faut un petit serveur http local qui écoutera sur le port 4242 et alimentera la base de Naxsi (dans mon exemple, le fichier /tmp/naxsi_rules.tmp  qui deviendra ensuite le /opt/nginx/conf/monsite.rules.

Vous pouvez donc télécharger le script http_config.py ici :

http://code.google.com/p/naxsi/source/browse/trunk/contrib/rules_generator/http_config.py

C’est fait ?

Lancons le http_config :

/opt/nginx/sbin# python http_config.py --rules /opt/nginx/conf/naxsi_core.rules
Starting server, use <Ctrl-C> to stop

Puis Nginx.

Maintenant vous pouvez surfer sur votre site, afin d’alimenter la liste blanche qui se créera en fonction des spécificités de votre site web.

Une petite visite sur http://localhost:4242 vous indiquera les règles apprises et en attente de validation :

You currently have 4 rules generated by naxsi
You have a total of 1584 exceptions hit.You should reload nginx's
config.Write rules and reload for ALL sites. [write&reload eos|0
pending rules|
filename:/tmp/naxsi_rules.tmp.21db4a5fea0f4dedb0aa90007de5c3c3]
[write&reload wafing.me|4 pending rules|

Il vous suffit alors de valider le « Write&reload » pour enregistrer les règles dans votre fichier.

Tout cela bien sûr est clairement expliqué ici :

http://code.google.com/p/naxsi/wiki/Howto#Installing_nginx_+_naxsi

Une fois votre fichier bien rempli, vous pouvez modifier votre VirtualHost pour renvoyer les visiteurs indélicats sur un 403 :

location /RequestDenied {
#proxy_pass http://127.0.0.1:4242;
return 403;
}

Et de commenter le « learning mode » dans votre fichier de règles.

Si bien sur, vous voulez continuez à alimenter votre filtre avec une restriction d’accès, un excellent exemple est disponible ici :

http://blog.memze.ro/?p=81

Une fois en place, vous pouvez tester a loisir la puissance de votre Naxsi :

GuiguiAbloc:~# wget "http://wafing.me?a=<>"
--2012-04-17 22:40:55--  http://wafing.me/?a=%3C%3E
Résolution de wafing.me... 8.20.110.175
Connexion vers wafing.me|8.20.110.175|:80...connecté.
requête HTTP transmise, en attente de la réponse...403 Forbidden
2012-04-17 22:40:55 ERREUR 403: Forbidden.

Je ne peux que vous inviter chaudement (tss tss), à lire la documenation de Naxsi et surtout remonter les éventuels problèmes à l’équipe pour ce projet jeune mais terriblement efficace et innovant dans le monde merveilleux des WAF.

Amusez-vous bien :D

Ce billet a été posté dans linux, sécurité et taggé , , . Bookmark ce permalink.

8 commentaires sur “Naxsi, du WAF pour votre Nginx

  1. Salut,

    Je sors la 0.45 ce soir, je t’incite donc à utiliser le *nouveau* démon d’apprentissage, nx_intercept/nx_extract, l’ancien est tout cassé ;)

  2. Merci Thibault pour l’info :)
    J’avais hésiter a partir directement de la version dev pour le billet, cela sera l’occasion d’écrire un autre billet sur le nouveau démon d’apprentissage :D

  3. Cool ! La 0.45 est sortie, et la prochaine version (d’ici une semaine) va intégrer des kikoo graphiques pour la partie reporting :)

  4. A les fameuses publications de notre guigui national!!!!
    Ca faisait un long moment que je n’avais pas lu un de tes posts.
    Je vois que t’es toujours à la recherche des dernières nouveautés du nain ternet?!!!

    ElPelicano

  5. Plutôt que d’alourdir Nginx, il reste aussi la solution de coder des sites qui ne sont pas bourrés de failles.