Comment installer et configurer Naxsi sur Ubuntu 14.04

De Get Docs
Aller à :navigation, rechercher

Introduction

Naxsi est un module Nginx tiers qui fournit des fonctionnalités de pare-feu d'application Web. Il apporte une sécurité supplémentaire à votre serveur Web et vous protège des diverses attaques Web telles que les injections XSS et SQL.

Naxsi est flexible et puissant. Vous pouvez utiliser des règles facilement disponibles pour les applications Web populaires telles que WordPress. En même temps, vous pouvez également créer vos propres règles et les affiner en utilisant le mode d'apprentissage de Naxsi.

Naxsi est similaire à ModSecurity for Apache. Ainsi, si vous connaissez déjà ModSecurity et/ou recherchez des fonctionnalités similaires pour Nginx, Naxsi vous intéressera certainement. Cependant, vous ne trouverez peut-être pas toutes les fonctionnalités de ModSecurity dans Naxsi.

Ce didacticiel vous montre comment installer Naxsi, comprendre les règles, créer une liste blanche et où trouver les règles déjà écrites pour les applications Web couramment utilisées.

Conditions préalables

Avant de suivre ce didacticiel, assurez-vous de remplir les prérequis suivants :

Sauf indication contraire, toutes les commandes nécessitant des privilèges root dans ce didacticiel doivent être exécutées en tant qu'utilisateur non root avec des privilèges sudo.

Étape 1 - Installation de Naxsi

Pour installer Naxsi, vous devrez installer un serveur Nginx compilé avec. Pour cela, vous aurez besoin du package nginx-naxsi. Vous pouvez l'installer de la manière habituelle d'Ubuntu avec la commande apt-get :

sudo apt-get update
sudo apt-get install nginx-naxsi

Cela installera Naxsi avec Nginx et toutes ses dépendances. Il s'assurera également que le service démarre et s'arrête automatiquement sur le Droplet.

Remarque : Si vous avez déjà installé Nginx sans Naxsi, vous devrez remplacer le package nginx-core, ou une autre variante de Nginx que vous pourriez avoir, par le package nginx-naxsi. Les autres packages Nginx ne prennent pas en charge les modules chargeables et vous ne pouvez pas simplement charger Naxsi dans un serveur Nginx existant.

Dans la plupart des cas, le remplacement de nginx-core par nginx-naxsi ne pose aucun problème et vous pouvez continuer à utiliser votre configuration précédente. Néanmoins, c'est toujours une bonne idée avec une telle mise à niveau de créer d'abord une sauvegarde de votre répertoire /etc/nginx/ existant. Après cela, suivez les instructions pour une nouvelle installation et confirmez simplement que vous acceptez de supprimer le package Nginx existant sur votre système.


L'installation par défaut de Nginx fournit un environnement Nginx de base fonctionnel, suffisant pour se familiariser avec Naxsi. Nous ne passerons pas de temps à personnaliser Nginx, mais nous passerons directement à la configuration de Naxsi. Cependant, si vous n'avez aucune expérience avec Nginx, c'est une bonne idée de vérifier Comment installer Nginx sur Ubuntu 14.04 LTS et ses articles connexes, en particulier Comment configurer les blocs de serveur Nginx (hôtes virtuels) sur Ubuntu 14.04 LTS.

Étape 2 - Activation de Naxsi

Tout d'abord, pour activer Naxsi, nous devons charger ses règles de base trouvées dans le fichier /etc/nginx/naxsi_core.rules. Ce fichier contient des signatures génériques pour détecter les attaques malveillantes. Nous discuterons de ces règles plus en détail plus tard. Pour l'instant, nous allons simplement inclure les règles dans le fichier de configuration principal de Nginx /etc/nginx/nginx.conf dans la partie écouteur HTTP. Alors, ouvrez ce dernier fichier pour le modifier avec nano :

sudo nano /etc/nginx/nginx.conf

Recherchez ensuite la section http et décommentez la partie d'inclusion pour les règles de Naxsi en supprimant le caractère # au début de la ligne. Il devrait maintenant ressembler à ceci :

/etc/nginx/nginx.conf

http {
...
        # nginx-naxsi config
        ##
        # Uncomment it if you installed nginx-naxsi
        ##

        include /etc/nginx/naxsi_core.rules;
...

Enregistrez le fichier et quittez l'éditeur.

Deuxièmement, nous devons activer les règles précédentes et configurer certaines options de base pour Naxsi. Par défaut, la configuration de base de Naxsi se trouve dans le fichier /etc/nginx/naxsi.rules. Ouvrez ce fichier :

sudo nano /etc/nginx/naxsi.rules

Remplacez uniquement la valeur de DeniedUrl par un fichier d'erreurs qui existe déjà par défaut et laissez le reste inchangé :

/etc/nginx/naxsi.rules

# Sample rules file for default vhost.
LearningMode;
SecRulesEnabled;
#SecRulesDisabled;
DeniedUrl "/50x.html";

## check rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;

Enregistrez le fichier et quittez.

Voici les directives de configuration ci-dessus avec leur signification :

  • LearningMode - Démarrer Naxsi en mode apprentissage. Cela signifie qu'aucune demande ne sera réellement bloquée. Seules les exceptions de sécurité seront générées dans le journal des erreurs Nginx. Un tel comportement initial non bloquant est important car les règles par défaut sont plutôt agressives. Plus tard, sur la base de ces exceptions, nous créerons une liste blanche pour le trafic légitime.
  • SecRulesEnabled - Activer Naxsi pour un bloc/emplacement de serveur. De même, vous pouvez désactiver Naxsi pour un site ou une partie de site en décommentant SecRulesDisabled.
  • DeniedUrl - URL à laquelle les demandes refusées seront envoyées en interne. C'est le seul paramètre que vous devez modifier. Vous pouvez utiliser la page d'erreur 50x.html facilement disponible qui se trouve dans la racine du document par défaut (/usr/share/nginx/html/50x.html), ou vous pouvez créer votre propre page d'erreur personnalisée.
  • CheckRule - Définit le seuil des différents compteurs. Une fois ce seuil dépassé (ex. 8 points pour le compteur SQL) la requête sera bloquée. Pour rendre ces règles plus agressives, diminuez leurs valeurs et vice versa.

Le fichier naxsi.rules doit être chargé emplacement par emplacement pour un bloc serveur. Chargeons-le pour l'emplacement racine (/) du bloc de serveur par défaut. Ouvrez d'abord le fichier de configuration du bloc serveur /etc/nginx/sites-enabled/default :

sudo nano /etc/nginx/sites-enabled/default

Ensuite, trouvez l'emplacement racine / et assurez-vous qu'il ressemble à ceci :

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ =404;
            # Uncomment to enable naxsi on this location
            include /etc/nginx/naxsi.rules;
    }

Avertissement : Assurez-vous d'ajouter un point-virgule à la fin de l'instruction include pour naxsi.rules car il n'y en a pas par défaut. Ainsi, si vous décommentez uniquement l'instruction, il y aura une erreur de syntaxe dans la configuration.


Une fois que vous avez effectué les modifications ci-dessus, vous pouvez recharger Nginx pour que les modifications prennent effet :

sudo service nginx reload

L'étape suivante explique comment vérifier si les modifications ont réussi et comment lire les journaux.

Étape 3 - Vérification des journaux

Pour vous assurer que Naxsi fonctionne, même s'il est toujours en mode apprentissage, accédons à une URL qui devrait lever une exception et regardons le journal des erreurs pour l'exception.

Nous verrons plus tard comment cette règle fonctionne exactement. Pour l'instant, suivez le journal des erreurs de Nginx pour trouver l'exception (l'option -f garde la sortie ouverte et y ajoute un nouveau contenu :

sudo tail -f /var/log/nginx/error.log

Essayez d'accéder à votre Droplet à l'URL http://Your_Droplet_IP/index.html?asd=----. Cela devrait déclencher une exception de sécurité Naxsi en raison des tirets, qui sont utilisés pour les commentaires dans SQL, et sont donc considérés comme faisant partie des injections SQL.

Dans la sortie de sudo tail -f /var/log/nginx/error.log, vous devriez maintenant voir le nouveau contenu suivant :

Output of nginx's error log2015/11/14 03:58:35 [error] 4088#0: *1 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/index.html&learning=1&total_processed=24&total_blocked=1&zone0=ARGS&id0=1007&var_name0=asd, client: X.X.X.X, server: localhost, request: "GET /index.html?asd=---- HTTP/1.1", host: "Y.Y.Y.Y"

La partie la plus importante de la ligne ci-dessus est mise en surbrillance : zone0=ARGS&id0=1007&var_name0=asd. Il vous donne la zone (la partie de la requête), l'identifiant de la règle déclenchée et le nom de la variable de la requête suspecte.

De plus, X.X.X.X est l'adresse IP de votre ordinateur local et Y.Y.Y.Y est l'adresse IP de votre Droplet. L'URI contient également le nom de fichier de la requête (index.htm), le fait que Naxsi fonctionne toujours en mode apprentissage (learning=1), et le nombre total de toutes les requêtes traitées ([ X182X]).

De plus, juste après la ligne ci-dessus, un message concernant la redirection vers le DeniedUrl devrait suivre :

Output of nginx's error log2015/11/14 03:58:35 [error] 4088#0: *1 rewrite or internal redirection cycle while internally redirecting to "/50x.html" while sending response to client, client: X.X.X.X, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "Y.Y.Y.Y", referrer: "http://Y.Y.Y.Y/index.html?asd=----"

Lorsque Naxsi est en mode apprentissage, cette redirection ne s'affichera que dans les journaux mais ne se produira pas réellement.

Appuyez sur CTRL-C pour quitter tail et arrêter la sortie du fichier journal des erreurs.

Plus tard, nous en apprendrons davantage sur les règles de Naxsi, puis il sera important d'avoir cette compréhension de base des journaux.

Étape 4 - Configuration des règles Naxsi

La partie la plus importante de la configuration de Naxsi est ses règles. Il existe deux types de règles : les règles principales et les règles de base. Les règles principales (identifiées par MainRule) sont appliquées globalement pour le serveur, et font donc partie du bloc http de la configuration principale de Nginx. Ils contiennent des signatures génériques pour détecter les activités malveillantes.

Les règles de base (identifiées par BasicRule) sont principalement utilisées pour la liste blanche des signatures et des règles de faux positifs. Ils sont appliqués par emplacement et doivent donc faire partie de la configuration du bloc de serveur (vhost).

Commençons par les règles principales, et regardons celles par défaut fournies par le package nginx-naxsi dans le fichier /etc/nginx/naxsi_core.rules. Voici un exemple de ligne :

/etc/nginx/naxsi_core.rules

...
MainRule "str:--" "msg:mysql comment (--)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1007;
...

À partir de la règle ci-dessus, nous pouvons décrire les parties suivantes, qui sont universelles et présentes dans chaque règle :

  • MainRule est la directive par laquelle commencer chaque règle. De même, chaque règle se termine par le numéro d'identification de la règle.
  • str: se trouve dans la deuxième partie de la règle. S'il s'agit de str:, cela signifie que la signature sera une chaîne simple, comme dans l'exemple ci-dessus. Les expressions régulières peuvent également être associées à la directive rx:.
  • msg: donne quelques éclaircissements sur la règle.
  • mz: signifie zone de correspondance, ou quelle partie de la demande sera inspectée. Cela peut être le corps, l'URL, les arguments, etc.
  • s: détermine le score qui sera attribué lorsque la signature sera trouvée. Des scores sont ajoutés à différents compteurs tels que SQL (attaques SQL), RFI (attaques par inclusion de fichiers à distance), etc.

Essentiellement, la règle ci-dessus (id 1007) avec le commentaire mysql comments signifie que si la chaîne -- se trouve dans n'importe quelle partie d'une requête (corps, arguments, etc.), 4 des points seront ajoutés au compteur SQL.

Si nous revenons à l'exemple d'URI (http://Your_Droplet_IP/index.html?asd=----) qui a déclenché l'exception SQL dans le journal, vous remarquerez que pour déclencher la règle 1007, nous avions besoin de 2 paires de tirets (--). En effet, pour chaque paire, nous obtenons 4 points et la chaîne SQL a besoin de 8 points pour bloquer une requête. Ainsi, une seule paire de tirets ne poserait pas de problème et, dans la plupart des cas, le trafic légitime n'en souffrirait pas.

Une directive de règle spéciale est negative. Il applique des scores si la signature ne correspond pas, c'est-à-dire vous soupçonnez une activité malveillante lorsqu'il manque quelque chose dans la demande.

Par exemple, regardons la règle avec id 1402 du même fichier /etc/nginx/naxsi_core.rules :

/etc/nginx/naxsi_core.rules

...
MainRule negative "rx:multipart/form-data|application/x-www-form-urlencoded" "msg:Content is neither mulipart/x-www-form.." "mz:$HEADERS_VAR:Content-type" "s:$EVADE:4" id:1402;
...

La règle ci-dessus signifie que 4 points seront ajoutés au compteur EVADE si l'en-tête de requête Content-type ne contient ni multipart/form-data, ni application/x-www-form-urlencoded. Cette règle est également un exemple de la manière dont les expressions régulières (rx:) peuvent être utilisées pour la description de la signature.

Étape 5 - Règles de liste blanche

Les règles Naxsi par défaut bloqueront presque certainement une partie du trafic légitime sur votre site, en particulier si vous avez une application Web complexe prenant en charge une grande variété d'interactions utilisateur. C'est pourquoi il existe des listes blanches pour résoudre ces problèmes.

Les listes blanches sont créées avec le deuxième type de règles, les règles de base de Naxsi. Avec une règle de base, vous pouvez mettre en liste blanche une règle entière ou des parties de celle-ci.

Pour illustrer le fonctionnement des règles de base, revenons à la règle de commentaire SQL (id 1007). Imaginez que vous avez un fichier avec deux tirets dans le nom de fichier, par exemple some--file.html sur votre site. Avec la règle 1007 en place, ce fichier augmentera le compteur SQL de 4 points. Ce nom de fichier seul et le score qui en résulte ne suffisent pas à bloquer une requête, mais il s'agit tout de même d'un faux positif qui peut poser problème. Par exemple, si nous avons également un argument avec deux tirets, la requête déclenchera la règle 1007.

Pour le tester, suivez le journal des erreurs comme avant :

sudo tail -f /var/log/nginx/error.log

Essayez d'accéder à http://Your_Droplet_IP/some--file.html?asd=--. Vous n'avez pas besoin d'avoir ce fichier sur votre site Web pour le test.

Vous devriez voir une exception familière similaire à celle-ci dans la sortie du journal des erreurs :

Output of nginx's error log2015/11/14 14:43:36 [error] 5182#0: *10 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/some--file.html&learning=1&total_processed=10&total_blocked=6&zone0=URL&id0=1007&var_name0=&zone1=ARGS&id1=1007&var_name1=asd, client: X.X.X.X, server: localhost, request: "GET /some--file.html?asd=-- HTTP/1.1", host: "Y.Y.Y.Y"

Appuyez sur CTRL-C pour arrêter d'afficher la sortie du journal des erreurs.

Pour résoudre ce déclencheur de faux positifs, nous aurons besoin d'une liste blanche qui ressemble à celle-ci :

BasicRule wl:1007 "mz:URL";

Le mot-clé important est wl pour la liste blanche, suivi de l'ID de la règle. Pour être plus précis sur ce que nous mettons en liste blanche, nous avons également spécifié la zone de correspondance - l'URL.

Pour appliquer cette liste blanche, créez d'abord un nouveau fichier pour les listes blanches :

sudo nano /etc/nginx/naxsi_whitelist.rules

Ensuite, collez la règle dans le fichier :

/etc/nginx/naxsi_whitelist.rules

BasicRule wl:1007 "mz:URL";

Si vous avez d'autres listes blanches, elles peuvent également figurer dans ce fichier, chacune sur une nouvelle ligne.

Le fichier avec les listes blanches doit être inclus dans votre bloc serveur. Pour l'inclure dans le bloc de serveur par défaut, utilisez à nouveau nano :

sudo nano /etc/nginx/sites-enabled/default

Ajoutez ensuite le nouvel include juste après le précédent pour Naxsi comme ceci :

/etc/nginx/sites-enabled/default

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
                # Uncomment to enable naxsi on this location
                include /etc/nginx/naxsi.rules;
                include /etc/nginx/naxsi_whitelist.rules;
        }

Pour que cette modification prenne effet, rechargez Nginx :

sudo service nginx reload

Maintenant, si vous essayez à nouveau la même requête dans votre navigateur pour Your_Droplet_IP/some--file.html?asd=--, seul le paramètre asd égalant deux tirets déclenchera 4 points pour le compteur SQL, mais pas le nom de fichier inhabituel. Ainsi, vous ne verrez pas cette demande dans le journal des erreurs comme une exception.

Écrire toutes les listes blanches nécessaires peut être une tâche fastidieuse et une science en soi. C'est pourquoi, au début, vous pouvez utiliser les listes blanches Naxsi facilement disponibles. Il en existe pour les applications Web les plus populaires. Il vous suffit de les télécharger et de les inclure dans le bloc serveur comme nous venons de le faire.

Une fois que vous vous êtes assuré de ne voir aucune exception pour les requêtes légitimes dans le journal des erreurs, vous pouvez désactiver le mode d'apprentissage de Naxsi. Pour cela ouvrez le fichier /etc/nginx/naxsi.rules avec nano :

sudo nano /etc/nginx/naxsi.rules

Commentez la directive LearningMode en ajoutant le caractère # devant comme ceci :

/etc/nginx/naxsi.rules

...
#LearningMode;
SecRulesEnabled;
#SecRulesDisabled;
...

Enfin, rechargez Nginx pour que le changement prenne effet :

sudo service nginx reload

Désormais, Naxsi bloquera toutes les requêtes suspectes et votre site sera plus sécurisé.

Conclusion

C'est aussi simple que cela d'avoir un pare-feu d'application Web avec Nginx et Naxsi. C'est suffisant pour commencer et j'espère que vous serez intéressé à en savoir plus sur ce que le puissant module Naxsi a à offrir. Vous pouvez désormais rendre votre serveur Nginx non seulement rapide, mais également sécurisé.