{"id":1163,"date":"2012-04-17T21:57:10","date_gmt":"2012-04-17T20:57:10","guid":{"rendered":"http:\/\/blog.guiguiabloc.fr\/?p=1163"},"modified":"2012-04-18T21:16:15","modified_gmt":"2012-04-18T20:16:15","slug":"naxsi-du-waf-pour-votre-nginx","status":"publish","type":"post","link":"http:\/\/blog.guiguiabloc.fr\/index.php\/2012\/04\/17\/naxsi-du-waf-pour-votre-nginx\/","title":{"rendered":"Naxsi, du WAF pour votre Nginx"},"content":{"rendered":"<p><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2012\/04\/ivandrago.jpg\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-1164\" title=\"ivandrago\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2012\/04\/ivandrago-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" srcset=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2012\/04\/ivandrago-300x300.jpg 300w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2012\/04\/ivandrago-150x150.jpg 150w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2012\/04\/ivandrago.jpg 400w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Quand je dis WAF, je parle bien s\u00fbr de <a title=\"https:\/\/www.owasp.org\/index.php\/Web_Application_Firewall\" href=\"https:\/\/www.owasp.org\/index.php\/Web_Application_Firewall\" target=\"_blank\">Web Application Firewall<\/a> , pas de <a title=\"http:\/\/fr.wikipedia.org\/wiki\/Wife_acceptance_factor\" href=\"http:\/\/fr.wikipedia.org\/wiki\/Wife_acceptance_factor\" target=\"_blank\">Wife Acceptance Factor <\/a>, (quoi que parfois cela peut \u00eatre \u00e9trangement li\u00e9 \ud83d\ude00 )<\/p>\n<p>Je tiens toute suite \u00e0 \u00e9viter toute pol\u00e9mique sur l&rsquo;image illustrant l&rsquo;article, c&rsquo;est juste que cela m&rsquo;a fait bien rire d&rsquo;imaginer <a title=\"http:\/\/fr.wikipedia.org\/wiki\/Ivan_Drago\" href=\"http:\/\/fr.wikipedia.org\/wiki\/Ivan_Drago\" target=\"_blank\">Ivan Drago<\/a> en Nginx russe pr\u00eat a affronter les scripts kiddies capitalistes \ud83d\ude42 (mais cela ne fait rire que moi, je sais :p)<\/p>\n<p>Mais revenons au sujet de ce billet.<\/p>\n<p>Si vous \u00eates un peu proche de la s\u00e9curit\u00e9 des \u00ab\u00a0serveurs web\u00a0\u00bb, vous avez vite compris que le simple firewalling tel qu&rsquo;on le conna\u00eet devient de moins en moins adapt\u00e9 aux formes d&rsquo;attaques pr\u00e9sentes sur le Nain Ternet.<\/p>\n<p>Au bout d&rsquo;un moment, il va falloir ajouter quelques filtrages de niveau 7 pour regarder et analyser ce qu&rsquo;il se trame (humour), dans nos requ\u00eates http.<\/p>\n<p>Pour les sites \u00ab\u00a0web\u00a0\u00bb, il s&rsquo;agit principalement d&rsquo;ins\u00e9rer un firewall applicatif d\u00e9di\u00e9 au requ\u00eates http, on appelle cela un WAF.<\/p>\n<p>Si votre serveur http est<a title=\"http:\/\/www.apache.org\/\" href=\"http:\/\/www.apache.org\/\" target=\"_blank\"> Apache<\/a>, vous utilisez s\u00fbrement le module<a title=\"http:\/\/www.modsecurity.org\/\" href=\"http:\/\/www.modsecurity.org\/\" target=\"_blank\"> mod_security<\/a> (un must have sur tout serveur de ce nom), ou encore <a title=\"https:\/\/www.ironbee.com\/\" href=\"https:\/\/www.ironbee.com\/\" target=\"_blank\">Ironbee<\/a> (je vous en reparlerais peut \u00eatre un autre jour, \u00e9tant grand fan d&rsquo; Ivan Ristic, l&rsquo;auteur justement de modsecurity).<\/p>\n<p>Vous utilisez IIS ? Je ne comprends m\u00eame pas ce que vous faites sur ce blog&#8230; \ud83d\ude41<\/p>\n<p>Donc, avec Apache, je jouais avec mod_security ou Ironbee mais j&rsquo;utilise aussi <a title=\"http:\/\/wiki.nginx.org\/Main\" href=\"http:\/\/wiki.nginx.org\/Main\" target=\"_blank\">Nginx<\/a> depuis des ann\u00e9es, le serveur http venu du froid qui pourrait bien vous faire revoir votre vision des serveurs http.<\/p>\n<p>Bref, ce n&rsquo;est pas un d\u00e9bat Apache VS Nginx (chacun a ses avantages\/inconv\u00e9nients et cela d\u00e9pend vraiment de la fa\u00e7on dont vous utilisez votre serveur http (m\u00eame si Nginx \u00e7a roxx <a title=\"http:\/\/lmgtfy.com\/?q=milf+in+string\" href=\"http:\/\/lmgtfy.com\/?q=milf+in+string\" target=\"_blank\">sa maman en slip<\/a>).<\/p>\n<p>Donc, m\u00eame si Nginx supporte plut\u00f4t tr\u00e8s bien certains types d&rsquo;attaque (qui a dit <a title=\"http:\/\/ha.ckers.org\/slowloris\/\" href=\"http:\/\/ha.ckers.org\/slowloris\/\" target=\"_blank\">Slowloris<\/a> ? :p), votre site web, lui, a peut \u00eatre quelques failles de type <a title=\"http:\/\/fr.wikipedia.org\/wiki\/Injection_SQL\" href=\"http:\/\/fr.wikipedia.org\/wiki\/Injection_SQL\" target=\"_blank\">injection SQL<\/a>, <a title=\"http:\/\/fr.wikipedia.org\/wiki\/Cross-site_scripting\" href=\"http:\/\/fr.wikipedia.org\/wiki\/Cross-site_scripting\" target=\"_blank\">Cross-Site scripting<\/a> ou<a title=\"http:\/\/fr.wikipedia.org\/wiki\/Cross-site_request_forgery\" href=\"http:\/\/fr.wikipedia.org\/wiki\/Cross-site_request_forgery\" target=\"_blank\"> Cross-Site Request Forgery<\/a>.<\/p>\n<p>Et ModSecurity ne fonctionne pas sous Nginx.<\/p>\n<p>Heureusement, il existe un WAF d\u00e9di\u00e9 pour Nginx, et pas des moindres.<\/p>\n<p>Ce WAF s&rsquo;apple <a title=\"http:\/\/code.google.com\/p\/naxsi\/\" href=\"http:\/\/code.google.com\/p\/naxsi\/\" target=\"_blank\">NAXSI<\/a>, et il est issu d&rsquo;une soci\u00e9t\u00e9 qui n&rsquo;est pas dans le genre \u00ab\u00a0plaisantin\u00a0\u00bb quand il s&rsquo;agit de s\u00e9curit\u00e9 informatique : <a title=\"http:\/\/www.nbs-system.com\/\" href=\"http:\/\/www.nbs-system.com\/\" target=\"_blank\">NBS-SYSTEM<\/a><\/p>\n<p>Pour preuve, vous trouverez chez eux des <a title=\"http:\/\/imil.net\/wp\/\" href=\"http:\/\/imil.net\/wp\/\" target=\"_blank\">gens plut\u00f4t velus <\/a>qui entre autres fondent des <a title=\"http:\/\/www.gcu-squad.org\/\" href=\"http:\/\/www.gcu-squad.org\/\" target=\"_blank\">groupuscules int\u00e9gristes que l&rsquo;on v\u00e9n\u00e8re ou l&rsquo;on d\u00e9t\u00e9ste <\/a>\ud83d\ude42<\/p>\n<p>(m\u00eame <a title=\"http:\/\/blog.guiguiabloc.fr\/index.php\/2009\/02\/27\/gculicious-propulse-par-mennen-barbe-difficile\/\" href=\"http:\/\/blog.guiguiabloc.fr\/index.php\/2009\/02\/27\/gculicious-propulse-par-mennen-barbe-difficile\/\" target=\"_blank\">GuiguiAbloc en parle<\/a>, c&rsquo;est pour dire :p)<\/p>\n<p>Vous me direz, \u00ab\u00a0mouais, c&rsquo;est sympa ton truc, mais dans la vrai vie, \u00e7a a fait ses preuves ?\u00a0\u00bb<\/p>\n<p>Et bien, disons qu&rsquo;il y en a <a title=\"http:\/\/www.bluevision.be\/blog-fr\/la-securite-autour-du-site-charlie-hebdo\/\" href=\"http:\/\/www.bluevision.be\/blog-fr\/la-securite-autour-du-site-charlie-hebdo\/\" target=\"_blank\">qui ont plut\u00f4t bien appr\u00e9ci\u00e9 son efficacit\u00e9.<\/a>..<\/p>\n<p>Tout de suite, on se dit, \u00ab\u00a0ok, ca a quand m\u00eame subit un bon test IRS (In Real Situation)\u00a0\u00bb<\/p>\n<p>Si je vous parle avec autant de passion de Naxsi, c&rsquo;est que ce WAF a une approche plut\u00f4t originale du firewall.<\/p>\n<p>Alors que ses confr\u00e8res se basent surtout sur des signatures (comme un antivirus), Naxsi, lui, fonctionne comme un filtre bay\u00e9sien (et oui, comme les anti-spams).<\/p>\n<p>Il d\u00e9tecte les cha\u00eenes de caract\u00e8res suspectes et donne un \u00ab\u00a0score\u00a0\u00bb qui, quand il devient trop \u00e9lev\u00e9, renvoi le \u00ab\u00a0visiteur\u00a0\u00bb vers une page de votre choix (403, ou pire, vers votre NIDS pour analyse ult\u00e9rieure \ud83d\ude09 )<\/p>\n<p>Je vous invite bien entendu \u00e0 vous goinfrer <a title=\"http:\/\/code.google.com\/p\/naxsi\/wiki\/TableOfContents?tm=6\" href=\"http:\/\/code.google.com\/p\/naxsi\/wiki\/TableOfContents?tm=6\" target=\"_blank\">du Wiki du projet<\/a>.<\/p>\n<p><strong>Suffit la causette, comment on met cela en place ?<\/strong><\/p>\n<p>Je suppose que vous avez t\u00e9l\u00e9charger <a title=\"http:\/\/nginx.org\/en\/download.html\" href=\"http:\/\/nginx.org\/en\/download.html\" target=\"_blank\">les sources de Nginx <\/a>ainsi que la derni\u00e8re version stable de <a title=\"http:\/\/code.google.com\/p\/naxsi\/downloads\/detail?name=naxsi-0.43-1.tgz&amp;can=2&amp;q=\" href=\"http:\/\/code.google.com\/p\/naxsi\/downloads\/detail?name=naxsi-0.43-1.tgz&amp;can=2&amp;q=\" target=\"_blank\">Naxsi (0.43-1 a ce jour).<\/a><\/p>\n<p>On d\u00e9targ\u00e9z\u00e8de tout cela et on compile Nginx avec Naxsi en tant que module.<\/p>\n<p><strong>Attention<\/strong> : Sp\u00e9cifier bien le add-module Nasxi en premier ! Nginx est sensible \u00e0 l&rsquo;ordre de chargement de ses modules.<\/p>\n<p>Exemple :<\/p>\n<pre lang=\"text\">\r\n.\/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\r\n<\/pre>\n<p>.Bien s\u00fbr je vous laisse adapter \u00e0 votre configuration \ud83d\ude42<\/p>\n<p>Copier le fichier naxsi-0.43-1\/naxsi_config\/naxsi_core.rules dans votre r\u00e9pertoire conf de Nginx (par exemple), et on pr\u00e9pare la configuration de Nginx.<\/p>\n<pre lang=\"text\">\r\n...\r\n\r\nhttp {\r\ninclude\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/opt\/nginx\/conf\/naxsi_core.rules;\r\n\r\n...\r\n\r\nserver {\r\nproxy_set_header Proxy-Connection \"\";\r\nlisten\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 *:80;\r\naccess_log\u00a0 \/opt\/nginx\/logs\/nginx_access.log;\r\nerror_log\u00a0 \/opt\/nginx\/logs\/nginx_error.log debug;\r\n\r\nlocation \/RequestDenied {\r\nproxy_pass http:\/\/127.0.0.1:4242;\r\n}\r\n\r\nlocation \/ {\r\ninclude\u00a0\u00a0\u00a0 \/opt\/nginx\/conf\/monsite.rules;\r\n...\r\n<\/pre>\n<p>Petite explication dans le texte.<\/p>\n<p>Au niveau du block http de Nginx on charge les filtres de Naxsi (\/opt\/nginx\/conf\/naxsi_core.rules)<\/p>\n<p>Puis au niveau du virtualhost, on d\u00e9finie une destination \u00ab\u00a0RequestDenied\u00a0\u00bb o\u00f9 seront envoy\u00e9es toutes les requ\u00e8tes intercept\u00e9es par Naxsi.<\/p>\n<p>On se fait un petit fichier incluant les r\u00e8gles nouvellement apprises :<\/p>\n<pre lang=\"text\">\r\ninclude\u00a0\u00a0\u00a0 \/opt\/nginx\/conf\/monsite.rules\r\n<\/pre>\n<p>Fichier qui contient :<\/p>\n<pre lang=\"text\">\r\nLearningMode;\r\nSecRulesEnabled;\r\nDeniedUrl \"\/RequestDenied\";\r\n\r\ninclude \"\/tmp\/naxsi_rules.tmp\";\r\n\r\n## check rules\r\nCheckRule \"$SQL >= 8\" BLOCK;\r\nCheckRule \"$RFI >= 8\" BLOCK;\r\nCheckRule \"$TRAVERSAL >= 4\" BLOCK;\r\nCheckRule \"$EVADE >= 4\" BLOCK;\r\nCheckRule \"$XSS >= 8\" BLOCK;\r\n<\/pre>\n<p>La ligne \u00ab\u00a0proxy_pass http:\/\/127.0.0.1:4242\u00a0\u00bb est un petit plus de Naxsi : l&rsquo;apprentissage.<\/p>\n<p>Et oui, comme tout filtre bay\u00e9sien, Naxsi est capable d&rsquo;apprendre des requ\u00e8tesiqui sont l\u00e9gitimes pour votre site web, ce la s&rsquo;appelle une liste blanche (white list).<\/p>\n<p>Pour cet apprentissage (learning mode), il vous faut un petit serveur http local qui \u00e9coutera sur le port 4242 et alimentera la base de Naxsi (dans mon exemple, le fichier \/tmp\/naxsi_rules.tmp\u00a0 qui deviendra ensuite le \/opt\/nginx\/conf\/monsite.rules.<\/p>\n<p>Vous pouvez donc t\u00e9l\u00e9charger le script http_config.py ici :<\/p>\n<p><a title=\"http:\/\/code.google.com\/p\/naxsi\/source\/browse\/trunk\/contrib\/rules_generator\/http_config.py\" href=\"http:\/\/code.google.com\/p\/naxsi\/source\/browse\/trunk\/contrib\/rules_generator\/http_config.py\" target=\"_blank\">http:\/\/code.google.com\/p\/naxsi\/source\/browse\/trunk\/contrib\/rules_generator\/http_config.py<\/a><\/p>\n<p>C&rsquo;est fait ?<\/p>\n<p>Lancons le http_config :<\/p>\n<pre lang=\"text\">\r\n\/opt\/nginx\/sbin# python http_config.py --rules \/opt\/nginx\/conf\/naxsi_core.rules\r\nStarting server, use <Ctrl-C> to stop\r\n<\/pre>\n<p>Puis Nginx.<\/p>\n<p>Maintenant vous pouvez surfer sur votre site, afin d&rsquo;alimenter la liste blanche qui se cr\u00e9era en fonction des sp\u00e9cificit\u00e9s de votre site web.<\/p>\n<p>Une petite visite sur http:\/\/localhost:4242 vous indiquera les r\u00e8gles apprises et en attente de validation :<\/p>\n<pre lang=\"text\">\r\nYou currently have 4 rules generated by naxsi\r\nYou have a total of 1584 exceptions hit.You should reload nginx's\r\nconfig.Write rules and reload for ALL sites. [write&reload eos|0\r\npending rules|\r\nfilename:\/tmp\/naxsi_rules.tmp.21db4a5fea0f4dedb0aa90007de5c3c3]\r\n[write&reload wafing.me|4 pending rules|\r\n<\/pre>\n<p>Il vous suffit alors de valider le \u00ab\u00a0Write&#038;reload\u00a0\u00bb pour enregistrer les r\u00e8gles dans votre fichier.<\/p>\n<p>Tout cela bien s\u00fbr est clairement expliqu\u00e9 ici :<\/p>\n<p><a title=\"http:\/\/code.google.com\/p\/naxsi\/wiki\/Howto#Installing_nginx_+_naxsi\" href=\"http:\/\/code.google.com\/p\/naxsi\/wiki\/Howto#Installing_nginx_+_naxsi\" target=\"_blank\">http:\/\/code.google.com\/p\/naxsi\/wiki\/Howto#Installing_nginx_+_naxsi<\/a><\/p>\n<p>Une fois votre fichier bien rempli, vous pouvez modifier votre VirtualHost pour renvoyer les visiteurs ind\u00e9licats sur un 403 :<\/p>\n<pre lang=\"text\">\r\nlocation \/RequestDenied {\r\n#proxy_pass http:\/\/127.0.0.1:4242;\r\nreturn 403;\r\n}\r\n<\/pre>\n<p>Et de commenter le \u00ab\u00a0learning mode\u00a0\u00bb dans votre fichier de r\u00e8gles.<\/p>\n<p>Si bien sur, vous voulez continuez \u00e0 alimenter votre filtre avec une restriction d&rsquo;acc\u00e8s, un excellent exemple est disponible ici :<\/p>\n<p><a title=\"http:\/\/blog.memze.ro\/?p=81\" href=\"http:\/\/blog.memze.ro\/?p=81\" target=\"_blank\">http:\/\/blog.memze.ro\/?p=81<\/a><\/p>\n<p>Une fois en place, vous pouvez tester a loisir la puissance de votre Naxsi :<\/p>\n<pre lang=\"text\">\r\nGuiguiAbloc:~# wget \"http:\/\/wafing.me?a=<>\"\r\n--2012-04-17 22:40:55--\u00a0 http:\/\/wafing.me\/?a=%3C%3E\r\nR\u00e9solution de wafing.me... 8.20.110.175\r\nConnexion vers wafing.me|8.20.110.175|:80...connect\u00e9.\r\nrequ\u00eate HTTP transmise, en attente de la r\u00e9ponse...403 Forbidden\r\n2012-04-17 22:40:55 ERREUR 403: Forbidden.\r\n<\/pre>\n<p>Je ne peux que vous inviter chaudement (tss tss), \u00e0 lire la documenation de Naxsi et surtout remonter les \u00e9ventuels probl\u00e8mes \u00e0 l&rsquo;\u00e9quipe pour ce projet jeune mais terriblement efficace et innovant dans le monde merveilleux des WAF.<\/p>\n<p>Amusez-vous bien \ud83d\ude00<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quand je dis WAF, je parle bien s\u00fbr de Web Application Firewall , pas de Wife Acceptance Factor , (quoi que parfois cela peut \u00eatre \u00e9trangement li\u00e9 \ud83d\ude00 ) Je tiens toute suite \u00e0 \u00e9viter toute pol\u00e9mique sur l&rsquo;image illustrant &hellip; <a href=\"http:\/\/blog.guiguiabloc.fr\/index.php\/2012\/04\/17\/naxsi-du-waf-pour-votre-nginx\/\">Read More <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7,8],"tags":[183,181,182],"_links":{"self":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1163"}],"collection":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/comments?post=1163"}],"version-history":[{"count":11,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1163\/revisions"}],"predecessor-version":[{"id":1175,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1163\/revisions\/1175"}],"wp:attachment":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/media?parent=1163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/categories?post=1163"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/tags?post=1163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}