Ça va pas être possible avec vos baskets

Tags: , , ,
No Comments »

Dans ma boîte, l’équipe sécurité a publié voila quelques mois de cela un module pour nginx: un firewall applicatif du nom de naxsi.

Ce module, sous licence GPLv2, je viens de le publier dans pkgsrc current sous la forme d’une option de www/nginx. Je me propose de vous montrer ici comment sécuriser simplement votre serveur web / proxy inverse nginx grâce à naxsi.

Premièrement, si comme moi (et comme il se doit) vous utilisez une branche stable de pkgsrc, mettez simplement à jour www/nginx comme ceci:

$ cd /usr/pkgsrc/www/nginx
# cvs up -rHEAD -dP

Puis spécifiez à pkgsrc que vous souhaitez activer l’option naxsi pour le paquet nginx:

$ grep nginx /etc/mk.conf
PKG_OPTIONS.nginx+=     naxsi

Ceci fait, reconstruisez le paquet comme d’habitude:

$ cd /usr/pkgsrc/www/nginx
$ sudo make update clean

Dans la configuration de nginx, incluez les règles par défaut de naxsi de cette façon:

http {
    include       /usr/pkg/etc/nginx/mime.types;
    include       /usr/pkg/etc/nginx/naxsi_core.rules; # < --- ici
    default_type  application/octet-stream;

Comme vous pourrez le constater, le fichier /usr/pkg/etc/nginx/naxsi_core.rules contient un set de règles déjà très efficaces contre bon nombre d'attaques connues.
Reste alors à activer le filtrage sur une location et choisir quels types d'attaques vous souhaitez bloquer; par exemple:

        location / {
            SecRulesEnabled;
            CheckRule "$SQL >= 8" BLOCK;
            CheckRule "$RFI >= 8" BLOCK;
            CheckRule "$TRAVERSAL >= 4" BLOCK;
            CheckRule "$EVADE >= 4" BLOCK;
            CheckRule "$XSS >= 8" BLOCK;

Un redémarrage de nginx plus loin, on essayera par exemple d’accéder à une adresse louche:

$ wget -O- http://coruscant/?../../etc/passwd
--2012-04-22 10:21:01--  http://coruscant/?../../etc/passwd
Resolving coruscant... 192.168.1.2
Connecting to coruscant|192.168.1.2|:80... connected.
HTTP request sent, awaiting response... No data received.

Et de constater dans /var/log/nginx/error.log:

2012/04/22 10:21:01 [error] 25353#0: *15 NAXSI_FMT: ip=192.168.1.1&server=192.168.1.2&uri=/&total_processed=1&total_blocked=1&zone0=ARGS&id0=1200&var_name0=, client: 192.168.1.1, server: localhost, request: "GET /?../../etc/passwd HTTP/1.0", host: "192.168.1.2"

Moi j’trouve ça assez classe tout de même.

Toutes les infos relatives à la configuration de naxsi sont disponibles sur le Wiki de ce dernier.

Is “if” really evil ?

Tags: , ,
5 Comments »

Hier, FRLinux me demande innocemment d’ajouter le module WPtouch, un chouette plugin pour WordPress, qui permet aux mobiles de visualiser le site sous forme d’application, bien plus lisible que le blog dans sa forme classique.
Ni une ni deux je m’execute… et m’aperçois que l’affichage d’iMil.net ne change pas d’un iota sur mes devices mobiles. Je me rappelle alors que le nginx placé devant l’Apache qui sert ce site cache la homepage pendant 10 minutes. Ceci explique cela.

Après quelques minutes de recherche, j’ai résolu le problème en plaçant ces quelques règles supplémentaires dans mon nginx.conf:

location / {
    set $mobile_ua '0';

    if ($http_user_agent ~* '(iPhone|iPod|mobile|Android|2.0\ MMP|240x320|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|hiptop|IEMobile)') {
        set $mobile_ua '1';
    }
    # ...directives proxypass...
    proxy_cache_key imil.net$request_uri$mobile_ua;
    # ...plein d'autres trucs...
}

Explication: on initialise une variable $mobile_ua à 0, si le User Agent match l’une des chaînes de caractères listées dans la condition if, la variable $mobile_ua est placée à 1.
La clé de cache étant maintenant composée également de cette variable, nous disposons de deux espaces de cache distincts, un pour les mobiles, l’autre pour le reste.

mmmmm nginx.

Rapid’CGI PHP, nginx et NetBSD

Tags: , , ,
3 Comments »

Il y a une foultitude de documentations sur la façon de faire tourner PHP via fastCGI sur un nginx, et à chaque fois, j’ai l’impression de lire des tambouilles copiées/collées de ci et de là. Ça cause de scripts (non portables la plupart du temps), de wrappers, et autres solutions capillotractées, et ça me plaît pas. En dépilant un peu, j’ai abouti à une solution que je trouve élégante… sous NetBSD evidemment :)

Tout d’abord, il s’agit de compiler PHP avec le support fastCGI, sans pollution avec le module CGI. Ceci est réalisé grâce au fichier /etc/mk.conf et la directive suivante:

PKG_OPTIONS.php=        -cgi fastcgi

Un make install clean plus loin, on peut s’assurer du support fastCGI d’un des binaires générés de cette façon:

$ /usr/pkg/libexec/cgi-bin/php -h|grep -i bind
  -b
|
 Bind Path for external FASTCGI Server mode

Il existe dans pkgsrc un outil spécialement dédié à gérer ce type d’implémentation, il s’agit de www/spawn-fcgi, que nous installons donc sans hésiter. spawn-fcgi a le bon goût d’être controlé par le fichier /etc/rc.conf, ainsi, après avoir copié /usr/pkg/share/examples/rc.d/spawnfcgi dans le repertoire /etc/rc.d, on configure le logiciel de cette façon:

$ grep spawn /etc/rc.conf
spawnfcgi=YES
spawnfcgi_jobs="php"
spawnfcgi_php_command="/usr/pkg/libexec/cgi-bin/php"
spawnfcgi_php_args=""
spawnfcgi_php_user="nginx"
spawnfcgi_php_address="127.0.0.1"
spawnfcgi_php_port="9000"
spawnfcgi_php_children="3"

Attention toutefois, il existe un minuscule bug dans rc.d/spawnfcgi que j’ai signalé au mainteneur, voici le patch trivial à appliquer:

--- /usr/pkg/share/examples/rc.d/spawnfcgi      2011-07-24
12:57:38.000000000 +0200
+++ /etc/rc.d/spawnfcgi 2011-07-24 17:16:49.000000000 +0200
@@ -38,6 +38,7 @@
                job_user=$(eval echo \$${name}_${job}_user)
                job_cwd=$(eval echo \$${name}_${job}_cwd)                                       job_socket=$(eval echo \$${name}_${job}_socket)
+               job_port=$(eval echo \$${name}_${job}_port)
                job_socket_mode=$(eval echo \$${name}_${job}_socket_mode)
                job_address=$(eval echo \$${name}_${job}_address)
                job_children=$(eval echo \$${name}_${job}_children)

Update bon, on est jamais mieux servi que par soi-même toussa, j’ai donc corrigé le package dans pkgsrc current. Un ptit cvs up -dP -rHEAD et tout devrait rouler.
Nous pouvons alors démarrer spawnfcgi comme n’importe quel autre service:

$ sudo /etc/rc.d/spawnfcgi start

Et de constater:

$ ps axuww|grep php
nginx     795  0.0  0.8  26412  8012 ?       Is    5:16PM  0:00.17 /usr/pkg/libexec/cgi-bin/php
nginx   18322  0.0  0.7  26412  7816 ?       Is    5:16PM  0:00.14 /usr/pkg/libexec/cgi-bin/php
nginx   22540  0.0  0.8  26412  8012 ?       Is    5:16PM  0:00.18 /usr/pkg/libexec/cgi-bin/php

Eeeeeexcellent Smithers.

Il ne reste alors plus qu’à configurer nginx pour qu’il passe à PHP en mode fastCGI les pages de script à interpréter:

        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /home/user/www$fastcgi_script_name;
            include        /usr/pkg/etc/nginx/fastcgi_params;
        }

Il faudra evidemment prendre soin de remplacer /home/user/www par le chemin de votre documentroot. Il doit d’ailleurs certainement y avoir une variable pour s’épargner cela…

On oublie pas le petit phpinfo() qui va bien:

WP Theme & Icons based on GlossyBlue by N.Design Studio
Banner from www.trynthlas.com
Entries RSS Comments RSS Log in
Performance Optimization WordPress Plugins by W3 EDGE