Sécuriser un serveur web Apache© avec mod_security

Gazette Linux n°143 — October 2007

René Pfeiffer

Adaptation française : Deny

Relecture de la version française : Joëlle Cornavin

Article paru dans le n°143 de la Gazette Linux d'octobre 2007.

Article publié sous Open Publication License. La Linux Gazette n'est ni produite, ni sponsorisée, ni avalisée par notre hébergeur principal, SSC, Inc.


Table des matières

Introduction
Examen de la couche application
Installation
Configuration
Options générales
Journalisation
Les règles
Les opérateurs
Les actions
Gestion des règles
Performance et déploiement
Ressources utiles

Introduction

Internet a son lot de filtres de paquet et de serveurs mandataires visant à augmenter la sécurité des clients comme des serveurs. Le filtrage du trafic réseau n'est jamais une mauvaise idée puisqu'il fournit un niveau de protection de base. Quand il lui échoit de protéger des serveurs web, votre filtre de paquet autorisera plus probablement le trafic HTTP (HyperText Transfer Protocol, Protocole de transfert de pages Web) et HTTPS (HyperText Transfer Protocol Secured, Protocole sécurisé de transmission de pages Web) pour les applications de votre serveur. À moins que vous déployiez une application mandataire qui examine HTTP, vous ne pouvez faire plus. Mais vous pouvez équiper votre serveur web Apache© de mod_security, qui à tour de rôle vous aide à analyser n'importe quelle requête lui étant soumis.

Examen de la couche application

Quand vous faites n'importe quel filtrage ou examen du trafic réseau, vous devez garder à l'esprit qu'habituellement personne ne comprend mieux les choses qui doivent être examinées que l'application en question. C'est l'une des raisons pour lesquels des filtres mandataires sont « mieux » adaptés à ce travail. Ils connaissent le protocole et ils peuvent normaliser des requêtes faussement encodées. Mod_security occupe une position très semblable. Il repose bien à l'intérieur du processus httpd d'Apache© et il examine les requêtes HTTP. C'est un avantage important par rapport aux serveurs mandataires puisqu'il peut également voir du contenu compressé où même crypté sans aucun problème.

Ainsi, qu'est-ce qui doit être examiné ? Le démon httpd d'Apache© examine sûrement des requêtes HTTP. Que me faut-il de plus ? Eh bien, il y a des choses que mod_security peut faire pour vous.

  • Une meilleure journalisation

    Le module peut journaliser le contenu des requêtes POST HTTP. Habituellement, Apache© ne fait pas cela. En outre, vous pouvez journaliser des transactions HTTP complètes. Ceci rend le travail d'un attaquant potentiel plus difficile. En plus de cela, vous disposez d'un contrôle très fin sur ce qu'on doit journaliser et à quel moment.

  • Opération en temps réel

    mod_security voit directement les requêtes et peut agir tout de suite.

  • Anomalies

    Le module de sécurité peut agir lors d'opération anormales sur le serveur web en examinant les taux de requêtes, les adresses IP, les sessions HTTP et les comptes utilisateurs.

  • Liste noire et blanche

    Vous pouvez user d'une approche basée sur une signature et définir ce que vous voulez autoriser et ce que vous voulez bloquer.

  • Protéger d'autres serveurs web

    Vous pouvez même protéger une autre application du serveur web en la combinant avec mod_proxy. Le serveur Apache© peut agir comme serveur mandataire inverse, voyant de ce fait toutes les requêtes HTTP et appliquant des groupes de règles.

Cela semble très impressionnant si vous désirez mon avis. À présent, nous devons seulement savoir comment l'ajouter à un déploiement d'Apache© existant.

Installation

La version autorisée actuelle est la 2.x. Elle fonctionne correctement avec Apache© 2.0.x et 2.2.x. Apache© 1.3.x n'est plus soutenu (vous devriez vraiment mettre à jour vos serveurs Apache©, sérieusement). mod_security a encore d'autres pré-requis.

  • Il faudra que le module mod_unique_id soit installé.

  • libxml2 et son paquetage de développement sont nécessaires puisque le module peut inspecter XML et doit l'examiner.

  • Si vous employez un serveur web Apache© de votre distribution, assurez-vous que les paquetages de développement sont aussi installés.

  • Vous aurez besoin soit de la bibliothèque PCRE (Perl Compatible Regular Expression, Expression régulière compatible avec perl) pour examiner des expressions régulières depuis votre système d'exploitation ou depuis le paquetage livré avec votre application Apache©. La documentation de mod_security comporte un message spécial au cas où la compilation se passerait mal.

mod_security n'emploie pas autoconf. Vous devez examiner son Makefile et lui indiquer où est le répertoire ServerRoot de votre installation d'Apache©. Ensuite vous pouvez essayer de saisir make et voir si tout compile. Si vous obtenez des erreurs de compilation, assurez-vous que l'environnement de votre compilateur et les paquetages de développement sont complets. Après en avoir terminé avec la commande make, arrêtez votre serveur Apache© et saisissez make install. Le Makefile copiera le module dans le répertoire des modules du serveur Apache© (habituellement /usr/local/apach2/modules/ pour un serveur web compilé, mais votre distribution peut placer les modules ailleurs). À présent, vous devez seulement activer le module en ajoutant les lignes suivantes dans votre fichier de configuration d'Apache©.

LoadFile /usr/lib/libxml2.so # optional
LoadModule security2_module modules/mod_security2.so	

Ensuite, les seules choses que nous devons configurer sont le module est le groupe des règles.

Configuration

Avertissement : Chaque mesure de sécurité doit être appliquée dans un but spécifique. Vous ne pouvez simplement ajouter des filtres sans penser aux conséquences pour les applications. Vous-même ou vos utilisateurs peuvent avoir des applications web s'exécutant, qui s'interrompt quand des mesures spéciales de sécurité sont activées. Si vous n'êtes pas certain de ne pas dérégler quelque chose, vous pouvez utiliser le groupe des règles et des actions en « audit mode ». Alors mod_security journalisera seulement sans bloquer. C'est une bonne idée de tout examiner jusqu'à ce que vous soyez certain d'opter pour le « live mode ». Elle rendra aussi vos utilisateurs heureux.

Un test très simple consiste à ajouter une règle unique en employant les deux lignes suivantes :

soyez On
SecRule REQUEST_URI attack

À présent, envoyez à votre serveur web une requête contenant le mot attack. Vous devriez obtenir un message d'erreur 403 Forbidden et la requête bloquée devrait générer une ligne dans le fichier journal des erreurs d'Apache©. Si vous définissez la première option à

SecRuleEngine DetectionOnly

Alors le module simplement détectera et ne bloquera rien. On examinera à présent les classes des différentes options disponibles. Assurez-vous d'avoir examiné la documentation de mod_security et le fichier de l'archive d'exemplaire des règles du noyau qui peut être téléchargé.

Options générales

mod_security a plusieurs groupes d'option. Voici quelques-unes des directives de configuration de base.

SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess On

La première ligne modifie la requête d'examen à on ou off. Les deux autres lignes contrôlent si les requêtes et les données du corps de la réponse seront examinées par le module. N'oubliez pas que les données doivent être bufférisées. Cela signifie que cela est requis pour l'examen des requêtes HTTP POST, mais on doit les buffériser et de ce fait cela demande de la mémoire. Vous pouvez réduire la quantité de mémoire utilisée par cette directive.

SecRequestBodyInMemoryLimit 131072

Vous pouvez également limiter la taille des données du corps de la requête HTTP. C'est très pratique pour désactiver des données importantes dans les requêtes HTTP POST.

SecRequestBodyLimit 10485760

Chaque requête supérieure à 10485760 octets verra s'afficher le message d'erreur 413 Request Entity Too Large. Le nombre par défaut est 134217728 octets (131072 KO).

Les serveurs Web incluent typiquement le type MIME (Multipurpose Internet Mail Extensions) des données qu'ils mettent dans les réponses. Vous pouvez contrôler les types que vous voulez examiner. Habituellement, vous ne voudrez pas analyser des données de type JPEG ou PDF (Portable Document Format).

SecResponseBodyMimeTypesClear
SecResponseBodyMimeType (null) text/plain text/html text/css text/xml

La première directive affiche la liste des types à vérifier. La seconde ligne définit les types qui nous intéressent. Le téléversement de fichiers peut être une chose que vous souhaitez contrôler. Vous pouvez transférer chaque fichier téléversé dans un répertoire distinct. En outre, vous pouvez rassembler tous les fichiers téléversés de votre serveur à condition que vous ayez de l'espace disque. Ceci peut être utile lors d'activités légales après que quelque chose se soit mal passé.

SecUploadDir /var/spool/apache/private
SecUploadKeepFiles Off

Il est de bon ton de ne pas utiliser le répertoire habituel dévolu aux fichiers temporaires pour stocker les téléversements. Créez un répertoire à cet effet et définissez les permissions adéquates. Seul Apache© doit accéder à cet emplacement.

Journalisation

Vous pouvez permettre l'audit de journalisation, qui peut vous aider fortement pendant le déboguage ou lors de pires situations. Vous avez le choix de tout journaliser ou seulement les évènements qui ont déclenché une des vérifications internes de mod_security. Ceci inclut les groupes de règles.

SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^[45]"

Nous voulons seulement noter les évènements appropriés et nous concentrer sur les réponses qui génèrent des codes de statut 4xx ou 5xx. C'est le rôle des expressions régulières. Vous pouvez tout journaliser si vous en avez besoin. La journalisation peut être notée dans un simple fichier ou dans un répertoire avec un fichier par évènement noté. Le dernier est habituellement réservé aux sites à gros volume.

SecAuditLogType Serial
SecAuditLog /var/log/www/modsec_audit.log
# SecAuditLogStorageDir /var/log/www/modsec_audit

Ainsi qu'il est noté ci-dessus, le contenu qui peut être journalisé est étendu. Vous pouvez journaliser des parties de la requête HTTP originale avec la réponse.

SecAuditLogParts "ABEIFHZ"

Cela signifie qu'on veut noter la vérification d'en-tête et de bas de page (options A et H), la requête originale (option B), la réponse intermédiaire du corps (option E), la requête modifiée du corps (option I), la réponse finale de l'en-tête (option F) et l'extrémité finale de l'évènement journalisé (option Z, qui est obligatoire). La réponse intermédiaire du corps est soit la réponse originale, soit la réponse modifiée par mod_security. La requête modifiée du corps est soit la requête originale du corps, soit une variante abrégée quand l'encodage multipart/form-data est employé. Les options par défaut sont ABIFHZ.

Les règles

Le module de sécurité emploie cinq phases distinctes pour le traitement des requêtes et des réponses depuis le serveur web.

  1. Analyse des en-têtes des requêtes

  2. Analyse du corps des requêtes

  3. Analyse des en-tête des réponses

  4. Analyse du corps de la réponse

  5. Journalisation

Il est important de penser à ceci quand vous concevez vos groupes de règles, presque comme quand vous concevez les filtres de paquets. La directive SecRule décrit une règle.

SecRule VARIABLES [OPERATOR] ACTIONS

Une fois écrit sous cette forme, mod_security

  1. modifiera les variables,

  2. appliquera l'opérateur s'il existe,

  3. se déclenchera après une correspondance pour chaque variable,

  4. et exécutera

  1.       l'action par défaut ou

  2.        les actions décrites dans la règle.

Souvenez-vous de la règle d'essai avec la chaîne « attack ». Nous avons indiqué au module d'examiner la variable REQUEST_URI de la requête HTTP et d'appliquer l'opérateur d'expression régulière visant à rechercher la chaîne désirée. Nous n'avons fait aucune action, ainsi l'action par défaut prévaut. Vous pouvez combiner des variables en employant des opérateurs logiques.

SecRule "REQUEST_URI|QUERY_STRING" attack

Ceci fait la même chose mais avec deux variables différentes. L'action sera déclenchée si le fragment de chaîne est trouvé dans l'une ou l'autre variable. Vous pouvez employer des opérateurs bien connus à l'intérieur des règles. L'assortiment des expressions régulières se fait grâce à la bibliothèque PCRE, ainsi vous pouvez utiliser toutes les constructions que PCRE comprend (ce qui est fondamentalement tout ce que vous pouvez faire avec la concordance des modèles de Perl). Les longues lignes peuvent être séparées en utilisant \ juste comme avec des scripts shell Bash.

N'oubliez pas que la section VARIABLES contient des variables. Leur contenu varie. Si la variable est vide ou non présente, la règle ne correspond pas. Ceci est important et la vérification des paramètres le demande. Les variables peuvent être ARGS, FILES, FILES_TMPNAMES, ENV, REMOTE_PORT, QUERY_STRING, SCRIPT_BASENAME,AUTH_TYPE, REQUEST_COOKIES, SESSIONID, TIME et beaucoup d'autres. La référence comporte une liste complète.

Les opérateurs

Les règles mod_security peuvent contenir des opérateurs. Ils sont utilisés pour valider la requête ou pour chercher des anomalies particulières. Le @ indique qu'un opérateur suit.

SecRule ARGS "@validateUtf8Encoding"
SecRule ARGS "@validateByteRange" 10,13,32-126

La première règle examine la requête pour s'assurer que l'encodage UTF-8 (Unicode Transformation Format) est valide. Le second exemple examine une plage spécifique de caractères dans la requête. Si la requête contient d'autres caractères que le saut de ligne, le retour chariot ou les caractères US ASCII (American Standard Code for Information Interchange, alors l'action se déclenche. Vous pouvez également faire appel à des scripts additionnels.

SecRule FILES_TMPNAMES "@inspectFile /usr/local/bin/check_file.pl" 

Ceci redirige tous les fichiers téléversés vers le script Perl afin de procéder à d'autres contrôle. Le code de sortie du script indique à mod_security s'il doit agir ou non. Vous pouvez même utiliser des listes noires en temps réel pour vos règles.

SecRule REMOTE_ADDR "@rbl bad.guys.and.girls.example.net"

Les actions

Il y a cinq types généraux d'actions.

  1. Les actions disruptives—arrêtent les transactions courantes

    1. interdisent—arrêtent une transaction et génèrent une erreur

    2. abandonne—abandonnent une transaction sans erreur

    3. redirigent—répondent avec une redirection (telle que 301 ou 302)

    4. redirigent— réacheminent la requête vers un autre serveur

    5. marquent une pause—ralentissent l'exécution de la requête

  2. Les actions non-disruptives—modifient l'état de la transaction courante

  3. Les actions de flux—modifient le flux des règles

    • autorisent—arrêtent le traitement des règles postérieures

    • relient—combinent la règle active avec la prochaine

    • oublient—ignorent une correspondance dans la règle courante ; utile pour commenter des règles, tout en les gardant encore actives

    • ignorent—sautent la prochaine règle ou plus

  4. Les actions de méta-données—contiennent des méta-données pour les règles en tant qu'information supplémentaire ; utile en cas de journalisation

  5. Les actions de données— sont des paramètres fictifs pour d'autres actions.

L'action par défaut peut être définie avec la directive SecDefaultAction. Elle peut être modifiée chaque fois que vous en avez besoin, ainsi vous pouvez définir des blocs de règles avec différentes actions par défaut. Les actions sont très semblables à celles utilisées par le logiciel de détection et de prévention d'intrusions Snort. Elles vous procurent beaucoup de flexibilité et elles autorisent une sélection tout à fait complexe d'essais. Voici un exemple de règle du noyau qui recherchent des tentatives d'injecter un message électronique dans une requête.

SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/* "[\n\r]\s*(?:to|bcc|cc)\s*:.*?\@" \
  "t:none,t:lowercase,t:urlDecode,capture,ctl:auditLogParts=+E,log,auditlog,msg:'Email Injection Attack.
  Matched signature <%{TX.0}>',,id:'950019',severity:'2'"</%{TX.0}>

Notez que j'ai inséré un saut de ligne pour une meilleure lisibilité. Le paramètre d'action est une simple chaîne qui indique au module de consigner chaque correspondance dans le fichier courant log et dans auditlog avec un message texte Email Injection Attack accompagné de plusieurs paramètres de la requête. Les règles du noyau ont d'autres exemples pour d'autres attaques comme le cross-site scripting, les injections SQL (structured query language, Langage structuré de requête), les anomalies HTTP et similaires.

Gestion des règles

Assurez-vous que vous maintenez vos fichiers de règles en bon ordre et que vous documentez chaque modification. C'est très important. N'importe quelle sorte de filtre peut endommager la totalité de vos applications et protocoles. Par conséquent, vous devez savoir quelles modifications induisent ce qui arrive. Vous aurez aussi besoin de cette information en développant vos propres règles. Considérez que des applications web personnalisées ont besoin de règles personnalisées. Certaines attaques peuvent être identiques, mais des applications personnalisées ont des particularités qui doivent être prises en compte. Le groupe des règles du noyau est un bon endroit pour commencer. Vous pouvez désactiver des règles sans les supprimer depuis votre configuration. C'est extrêmement utile au cas vous souhaiteriez distribuer des règles à de multiples serveurs. Vous pouvez faire ceci en fractionnant votre règle dans de multiples fichiers et en implémentant une configuration maître qui active ou désactive les groupes de règles sélectionnés.

Performance et déploiement

Tout a un prix et le filtrage de requêtes HTTP ne déroge pas à la règle. Mod_security doit garder la requête dans une mémoire tampon ou doit l'enregistrer dans un fichier temporaire. Vous devez en tenir compte. L'analyse induit une légère surcharge en terme de cycles processeur ainsi que pour le serveur web. Si vous installez le module sur un serveur qui a déjà des problèmes de performance, les choses n'iront pas mieux. C'est le rôle de la méthode du serveur mandataire inverse. Des sites fréquemment visités n'iront probablement pas loin sans serveurs mandataires supplémentaires.

Vos propres applications web sont une dernière chose à prendre en compte. N'installez pas simplement les règles du noyau en acceptant tout par défaut. Examinez le groupe des règles et décidez par vous-même si vous avez besoin de toutes les règles. Des choses peuvent casser si vous n'êtes pas assez prudent. Personne ne connaît vos applications web mieux que vous. Faites bon usage de cette application.

Ressources utiles

René est né pendant l'année de la fondation d'Atari© et la sortie du jeu Pong. Depuis sa prime jeunesse, il a commencé à démonter des objets pour savoir comment ils fonctionnent. Il ne pouvait pas même passer devant des chantiers en construction sans rechercher les fils électriques qui pourraient sembler intéressants. Sa passion pour l'informatique débute quand son grand-père lui achète un 4-bit micro contrôleur avec 256 octets de mémoire vive et un système d'exploitation de 4096 octets, le poussant à apprendre l'assembleur avant tout autre langage.

Après avoir fini l'école, il est allé à l'université afin d'apprendre la physique. Il a alors collecté des expériences avec un C64©, un C128©, deux Amigas©, un Ultrix© de DEC©, un OpenVMS et finalement un GNU/Linux sur un PC en 1997. Il emploie /Linux depuis ce temps et il aime toujours démonter des choses pour les ré-assembler. Sa soif de découverte le rend proche du mouvement Free Software©, où il s'évertue à comprendre comment les choses fonctionnent. Il est aussi impliqué dans des groupes de liberté civile axés sur les droits numériques.

Depuis 1999, il propose ses compétences en tant qu'indépendant. Ses principales activités comprennent l'administration système et réseau, la programmation et des conseils. En 2001, il a commencé à donner des conférences sur la sécurité informatique à Technikum Wien. Quand il n'est pas vissé devant les écrans d'ordinateur, n'examine pas du matériel et ne disserte pas d'équipement réseau, il se passionne pour la plongée sous-marine, l'écriture ou la photographie avec sa caméra numérique. Il aimerait à nouveau s'essayer à l'écriture de roman et au jeu de rôle dès qu'il trouvera un peu plus de temps libre pour s'organiser