TP4 - Tips and tricks pour sécuriser Apache - cours-info
←
→
Transcription du contenu de la page
Si votre navigateur ne rend pas la page correctement, lisez s'il vous plaît le contenu de la page ci-dessous
Département d’Informatique Licence Mobilité numérique Sécurité TP4 - Tips and tricks pour sécuriser Apache L’objectif de ce TP est de voir comment améliorer certains aspects au niveau sécurité d’un serveur Apache. Par exemple, comment faire pour que l’accès à un site se fasse via le protocole HTTPS. Seules les grandes lignes des commandes seront décrites, pour avoir la syntaxe complète d’une commande on vous invite à utiliser le manuel : man [commande] ([ ] indique que c’est optionnel), exemple : man ls. IMPORTANT : changer le mot de passe de root ! ! 1 Contenu d’un répertoire et liens symboliques Les manipulations à effectuer sont : 1. changer le nom du fichier index.php dans le site www.site1.fr en old.index.php ; 2. recharger le site www.site1.fr dans le navigateur et constater le problème ; 3. pour empêcher cela, modifier les Options dans le fichier de configuration du site comme suit Options -Indexes -FollowSymLinks +MultiViews 4. quel est le rôle de l’option MultiViews et à quel module est-elle liée ? 5. remettre le nom du fichier comme au départ (index.php) et vérifier que le message Welcome on site 1 s’affiche à nouveau. 2 Désactiver les modules qui sont inutiles Les manipulations à effectuer sont : 1. une alternative pour empêcher l’affichage du contenu des répertoires est de désactiver le module autoindex. La liste des modules actifs est visible de deux manières : — en consultant le contenu du répertoire /etc/apache2/mods-enabled ; — via la commande apachectl -M. 2. vérifier que autoindex est bien actif ; 3. le désactiver a2dismod autoindex systemctl restart apache2 3 Prévention des attaques de type Clickjacking, XSS, etc. Les navigateurs implémentent de nombreux mécanismes de défense contre des attaques qui sont rarement mis en œuvre. Nous allons donc voir comment les configurer via les en-têtes HTTP renvoyés par le serveur en réponse à des requêtes. 1
Voici une liste (incomplète) de HTTP Security Headers qui sont disponibles, avec pour certains leur utilité : • X-Frame-Options → bloque l’incrustation (iframe) d’un site dans un site tiers ; • X-XSS-Protection → activation de la détection d’attaques de type XSS ; • Content-Security-Policy ; • Referrer-Policy ; • HTTP Strict Transport Security (HSTS) ; • HTTP Public Key Pinning (HPKP) → codage en dur de l’empreinte de la clé publique du certificat TLS ; • X-Content-Type-Options → désactive l’interpréteur d’en-têtes de fichiers multimédia ; • Set-Cookie ; • etc. ATTENTION : comme on le verra plus loin, les navigateurs ne supportent pas nécessai- rement tous les en-têtes, ou de la même manière... Deux liens utiles : • https://blog.appcanary.com/2017/http-security-headers.html → plein d’infor- mations sur les en-têtes, leur intérêt, etc. • https://securityheaders.io/ donne une note à un site web en analysant les en-têtes de sécurité. 3.1 X-Frame-Options Cet HTTP response header permet de spécifier si oui ou non un navigateur dispose des autorisations pour charger une page dans un , ou . Il permet d’évi- ter les attaques de type clickjacking, en s’assurant que leur contenu n’est pas intégré au sein d’autres sites. Cette sécurité n’est disponible que dans le cas ou le navigateur supporte l’en-tête X-Frame-Options. Trois valeurs sont possibles pour cet en-tête : X-Frame-Options: deny X-Frame-Options: sameorigin X-Frame-Options: allow-from ttps://example.com/ — deny → la page ne peut pas être affiché dans une frame, peu importe le site qui essaie de la charger ; — sameorigin → la page ne peut être affiché que par un site de même origine ; — allow-from → la page ne peut s’afficher dans une frame qu’à partir de l’origine spécifié. Les manipulations à effectuer sont : 1. éditer le fichier /etc/apache2/conf-enabled/security.conf ; 2. faire en sorte que la directive suivante soit présente, ou non commentée Header set X-Frame-Options: "sameorigin" 3. quel module doit être activé ? 4. vérifier qu’il l’est, sinon l’activer (voire l’installer si nécessaire) ; 5. nous allons maintenant vérifier les en-têtes de réponse HTTP du serveur web. Pour cela, nous allons utiliser la Web Developer extension dans Firefox ; 6. puis au niveau de l’extension choisir Network en sélectionnant bien sûr la réponse du serveur web à une requête sur l’un des deux sites. Vous devriez voir au niveau de Headers, plus précisément de Response headers, X-Frame-Options suivi de sameorigin. 2
3.2 X-XSS-Protection Les manipulations à effectuer sont : 1. quelle attaque prévient cet en-tête ? 2. éditer le fichier /etc/apache2/conf-enabled/security.conf ; 3. ajouter la directive suivante : Header set X-XSS-Protection: "1; mode=block" 4. vérifier, comme précédemment, les en-têtes de réponse HTTP du serveur web ; 5. désactiver la protection, saisir sur la machine hôte le script PHP xss.php suivant : xss puis l’uploader dans le site 1 et lancer son exécution via http://www.site1.fr/xss.php?name=alert("XSS") 6. modifier le script pour réactiver la protection, puis l’exécuter à nouveau. Que constatez-vous ? 7. aller sur le site https://developer.mozilla.org et faire une recherche avec le mot clé X-XSS-Protection. Que trouvez-vous comme indication au niveau de la compatibilité des navigateurs avec cet en-tête, en particulier pour Firefox ? 8. installer sur la machine hôte le navigateur Chrome depuis le site de Google, puis refaire le test précédent afin de vérifier si lui prend correctement en compte la directive / l’en-tête. Une attaque de type Cross-Site Scripting (XSS) consiste à injecter du code qui sera exécuté par le navigateur. L’utilisateur peut voir, ou non, quelque chose se produire lors de l’injection. Il s’agit d’une attaque sur un site web tiers (le site de la victime) via un autre site web (celui du pirate), qui peut avoir deux objectifs suivant la façon dont le site pirate est utilisé : 1. soit il sert de relais pour faire transiter des données volées ; 2. soit il contient les ressources qui seront injectées dans la page attaquée. Dans tous les cas le but de l’attaque est de réaliser des actions au niveau du navigateur de la victime. Le script PHP ci-dessus est un exemple très basique d’injection Javascript. Il existe principalement deux types d’attaques XSS : 1. non persistante (XSS réfléchi / Reflected XSS) C’est la plus commune. Dans ce cas les données envoyées par un client sont utilisées telles quelles par les scripts du serveur pour produire une page de résultat et si des données non vérifiées sont incluses dans la page résultat sans encodage des entités HTML, elles pourront être utilisées pour injecter du code dans la page dynamique reçue par le navigateur. Le script PHP ci-dessus correspond à une attaque non persistante. 3
2. persistante (XSS stocké / Stored XSS) Dans ce cas les données fournies par un client sont stockées sur un serveur (BDD ou fichier en général) et sont ensuite ré-affichées sans que les caractères spéciaux HTML aient été encodés. Un exemple classique est un forum où des utilisateurs peuvent poster des textes formatés avec des balises HTML. Il suffit alors que l’attaquant poste un message injectant un script et tous les visiteurs qui chargeront la page infectée seront touchés. L’en-tête X-XSS-Protection est remplacé dans certains navigateurs par un en-tête plus général, appelé Content-Security-Policy, qui définit une politique de sécurité du contenu. Pour cela on écrit : Content-Security-Policy: politique où politique est une chaîne de caractères contenant la liste des règles qui constituent la politique CSP. Vous trouverez sur le site https://developer.mozilla.org des exemples et un descriptif de directives CSP. ATTENTION : il est conseillé de combiner les deux en-têtes. Les manipulations à effectuer sont : 1. éditer le fichier /etc/apache2/conf-enabled/security.conf ; 2. ajouter la directive suivante : Header set Content-Security-Policy: "reflected-xss" 3. vérifier, comme précédemment, les en-têtes de réponse HTTP du serveur web. Cela fonctionne-t-il ? Pourquoi ? 4. aller sur le site https://portswigger.net, puis cliquer sur WebSecurity Academy et dans Learning materials and labs consulter Cross-site scripting (XSS). 3.3 Cookie et autres en-têtes — Question 1 : comment protéger les cookies ? — Question 2 : quels mécanismes de sécurité sont associés aux en-têtes Referrer-Policy, HTTP Strict Transport Security et X-Content-Type-Options ? — Question 3 : que faudrait-il faire pour que la ligne Server: "Apache" n’apparaisse plus dans les en-têtes de la réponse du serveur ? Une requête dans votre moteur de recherche préféré avec les bons termes / mots clés vous donnera à chaque fois la réponse, voire le premier lien donné précédemment. Les manipulations à effectuer sont : 1. ajouter les directives permettant de protéger les cookies et de faire en sorte que le serveur utilise les en-têtes indiquées à la Question 2 ; 2. vérifier, comme précédemment, les en-têtes de réponse HTTP du serveur web. 4 Activation de TLS Ici il s’agit de protéger les communications via l’utilisation d’un chiffrement fort en créant un certificat auto-signé pour chacun des sites. Naturellement, on redirigera les connexions qui arriveront sur le port 80, non sécurisé, vers les port 443 qui le sera. 4
Les manipulations à effectuer sont : 1. activation du module ssl (a) a2enmod ssl (b) on redémarre Apache systemctl restart apache2 2. génération d’un certificat auto-signé pour chacun des sites (a) on crée un répertoire pour y mettre les clés et le certificat mkdir /etc/apache2/ssl mkdir /etc/apache2/ssl/www-site1 cd /etc/apache2/ssl/www-site1 (b) on génère la paire de clés et une requête de certificat pour le site www.site1.fr openssl genrsa -out site1.key 2048 openssl req -nodes -new -key site1.key -out site1.csr ATTENTION : il faut mettre au niveau de Common Name le nom du domaine (ou sous-domaine), soit dans notre cas site1.fr ; (c) finalement on génère un certificat auto-signé valide pour une année openssl x509 -req -days 365 -in site1.csr -signkey site1.key -out site1.crt (d) refaire les étapes précédentes pour le second site ; 3. on modifie le configuration des deux sites. Pour chacun on va ajouter une redirec- tion de http vers https, soit du port 80 vers le port 443. Seules les indications pour www.site1.fr sont données, pour le second site il faut s’en inspirer. On rappelle que le fichier de configuration contenant le virtualHost de www.site1.fr est le fichier site1.conf dans /etc/apache2/sites-available. ServerAdmin webmaster@localhost ServerName www.site1.fr Redirect permanent / https://www.site1.fr/ ServerAdmin webmaster@localhost ServerName www.site1.fr DocumentRoot /storage/web/www-site1 Alias /database "/usr/share/phpmyadmin" ErrorLog "/storage/logs/www-site1/site1-error.log" CustomLog "/storage/logs/www-site1/site1-access.log" common AssignUserId user-site1 user-site1 SSLEngine on SSLCertificateFile /etc/apache2/ssl/www-site1/site1.crt SSLCertificateKeyFile /etc/apache2/ssl/www-site1/site1.key Options -Indexes Options FollowSymLinks MultiViews AllowOverride none 5
Require all granted 4. on affine la configuration du chiffrement en ajoutant des directives. Ces directives seront placées après SSLEngine on. (a) Activation de tous les protocoles (différentes versions) sécurisés TLS et on désactive les SSL SSLProtocol All -SSLv2 -SSLv3 (b) sélection des méthodes de chiffrement SSLCipherSuite HIGH:!aNULL:!MD5:!ADH:!RC4:!DH (c) on force le navigateur à respecter l’ordre que l’on a précisé précédemment SSLHonorCipherOrder on (d) directives à utiliser en cas de certificat lié à une autorité de certification. Comme on en a pas, ne pas les mettre dans les fichiers de configuration. C’est uniquement un exemple. # Certificat racine si besoin SSLCACertificateFILE /etc/apache2/ssl/www-site1/certif-racine.crt # Certificat intermediaire SSLCACertificateFILE /etc/apache2/ssl/www-site1/certif-interm.crt 5 Web Application Firewall Pour finir on va installer ModSecurity, un module open source qui permet d’accroître forte- ment la sécurité d’un serveur web Apache. Il permet d’assurer un certain niveau de protection contre de nombreuses attaques exploitant des failles web : XSS, injection SQL, vol de ses- sion, etc. (consulter le site web http://www.modsecurity.org). Après son installation, on fera quelques tests pour vérifier son bon fonctionnement. 5.1 Installation Les manipulations à effectuer sont : 1. on installe le module apt-get install libapache2-mod-security2 2. on vérifie que le module est bien installé et activé apachectl -M | grep security2 3. par défaut le module ne fonctionne pas. Il faut d’abord le configurer mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf puis on édite le fichier .conf et on met SecRuleEngine on, avant de redémarrer Apache avec systemctl restart apache2 ; 4. le module a besoin de règles pour fonctionner. Des règles par défaut ont été mises en place, mais on va récupérer celles qui sont accessibles via GitHub (a) on supprime les règles qui ont été installées 6
rm -rf /usr/share/modsecurity-crs (b) on download les dernières règles apt-get install git git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/share/modsecurity-crs (c) on renomme le fichier cd /usr/share/modsecurity-crs mv crs-setup.conf.example crs-setup.conf (d) on met à jour la configuration du module dans Apache en modifiant le fichier /etc/apache2/mods-enabled/security2.conf comme suit IncludeOptional /etc/modsecurity/*.conf IncludeOptional /usr/share/modsecurity-crs/*.conf IncludeOptional /usr/share/modsecurity-crs/rules/*.conf et on met en commentaire la ligne IncludeOptional concernant OWASP ; (e) on redémarre une dernière fois Apache. 5.2 Tests Pour illustrer le bon fonctionnement du module et son intérêt, nous allons envoyer des requêtes représentatives de deux types d’attaques, à savoir l’injection d’un script (attaque de type XSS) et une injection SQL. Les manipulations à effectuer sont : 1. saisir au niveau du navigateur https://www.site1.fr/?q=">alert(1) 2. quel est le message affiché ? 3. faire la même manipulation avec https://www.site1.fr/?q=1’ OR 1=1 4. désactiver le module avec a2dismod security2, redémarrer Apache, puis refaire les manipulations précédentes et constater la différence. 6 Suivi des performances du serveur Pour avoir une idée des performances d’Apache par rapport à son activité liée à un site web, il faut utiliser le module mod_status qui permet d’afficher une page donnant des informations statistiques. Ce module est normalement déjà installé et activé, mais pour qu’il fonctionne il faut compléter la configuration du site web pour lequel on veut obtenir les informations. Les manipulations à effectuer sont : 1. utiliser la commande apachectl -M pour vérifier que le module est bien activé ; 2. ajouter les lignes qui suivent à la fin du du fichier site1.conf (faire de même pour le second site) SetHandler server-status Require local Require ip 192.168.56.1 7
3. redémarrer le service http service apache2 restart 4. consulter les informations concernant ce module sur la documentation en ligne d’Apache via le lien suivant http://httpd.apache.org/docs/2.4/ 5. pour chacun des deux sites aller sur la page web donnant les informations statistiques relatives à son activité. 7 Réécrire les URLs à la volée pour imposer l’HTTP 1.1 Le module mod_rewrite permet de réécrire les URLs, l’idée étant dans notre cas de faire en sorte que les éventuelles requêtes en HTTP 1.0 soient réécrites. Pour cela, il faut activer le module et ajouter des règles de réécriture dans chacun des virtualHost pour lequel on veut que la réécriture soit active. Les manipulations à effectuer sont : 1. activer le module, puis vérifier qu’il est bien actif ; 2. ajouter les lignes ci-dessous dans la partie ... du fichier configurant le site web www.site1.fr RewriteEngine On RewriteCond %{THE_REQUEST} !HTTP/1\.1$ RewriteRule .* - [F] 3. consulter les informations sur le module dans la documentation en ligne d’Apache, dis- ponible via le lien ci-après http://httpd.apache.org/docs/2.4/, afin de comprendre ce que fait chacune des trois lignes. 8 IP-based virtual hosting Les deux sites www.site1.fr et www.site2.fr sont définis au niveau d’Apache via des hôtes virtuels (Virtual Hosts) basés sur le nom de domaine (Name-based virtual hosting). Nous allons maintenant voir comment définir un site web via un serveur virtuel basé sur une adresse IP et un numéro de port. Ce site sera défini pour pointer sur /storage/web/www-site1 et reprendra donc une bonne partie de la configuration du site1. Cela nécessitera d’attribuer une autre adresse IP à la machine virtuelle dans le réseau 192.168.56.0. Les manipulations à effectuer sont : 1. ajouter les lignes suivantes à la fin du fichier /etc/network/interfaces iface enp0s8:1 inet static address 192.168.56.202 netmask 255.255.255.0 2. activation de cette nouvelle interface définit via IP aliasing ifup enp0s8:1 Une alternative à la méthode de configuration précédente, “obsolète”, est : ip addr add 192.168.56.202/24 dev enp0s8 label enp0s8:1 8
ATTENTION : cette seconde interface n’est pas configurée automatiquement si d’aven- ture on redémarrait la machine. 3. on modifie le fichier ports.conf dans /etc/apache2 afin qu’Apache écoute également le port 8080 sur l’adresse IP 192.168.56.202. Pour cela on ajoute après Listen 80 la directive suivante : Listen 192.168.56.202:8080 4. on crée un fichier de configuration site3.conf dans /etc/apache2/sites-available avec le contenu ci-dessous ServerName www.site1.fr DocumentRoot /storage/web/www-site1 ErrorLog "/storage/logs/www-site1/ip-error.log" CustomLog "/storage/logs/www-site1/ip-access.log" combined AssignUserId user-site1 user-site1 Options Indexes FollowSymLinks MultiViews AllowOverride none Require all granted 5. activer le nouveau site ; 6. redémarrer le service http et vérifier que vous pouvez bien vous connecter via l’adresse IP en précisant le bon numéro de port. 9 Utilisation de fail2ban Cet outil permet de protéger un serveur Apache d’un certain nombre de requêtes mal- veillantes. En particulier les tentatives d’attaques de type Brute force lorsqu’on a un accès par authentification. Les manipulations à effectuer sont : 1. installer le paquet adéquat via apt-get install fail2ban 2. comme indiqué au début du fichier jail.conf, suivant le niveau de personnalisation que l’on veut apporter à fail2ban, il est préférable de passer par un fichier annexe jail.local ou des fichiers .conf placés dans le répertoire jail.d (à l’image du fichier custom.conf vu lors d’un TP précédent). Dans notre cas, l’objectif est que les deux fichiers error.log et access.log des deux sites soient analysés. Il s’agira naturellement de faire en sorte que les fichiers de log des deux sites soient analysés en plus de ceux associés au site par défaut et qui sont dans le répertoire /var/log/apache2. Pour cela, il faudra apporter des modifications au niveau des sections dont le nom commence par apache. Par exemple au niveau de la section [apache-auth] on complétera la directive logpath comme suit : logpath = %(apache_error_log)s %(site1_error_log)s %(site2_error_log)s 9
en ayant pris soin de définir site1_error_log (idem pour le second site) dans le fichier paths-debian.conf (ou paths-common.conf) qui sera inclu dans le fichier jail.conf via la directive [INCLUDES] qui se trouve au début de celui-ci ; 3. consulter dans le répertoire filter.d de fail2ban les commentaires se trouvant dans les différents fichiers de filtrage relatifs à Apache afin d’identifier le rôle de chacun ; 4. une fois la configuration faite, il faut redémarrer le service fail2ban service fail2ban restart 5. les règles de filtrage associées à Apache sont-elles activées ? Regarder ce qu’affiche la commande iptables -L ; 6. pour corriger cela, apporter les modifications adéquates dans le fichier de configuration se trouvant dans le répertoire /etc/fail2ban/jail.d. Après avoir redémarrer fail2ban vérifier que les règles pour Apache sont maintenant bien présentes ; 7. une alternative permettant de voir la Jail list active est fail2ban-client status 8. pour plus d’information sur une Jail particulière comme apache-auth fail2ban-client status apache-auth 9. quelle option ajouter à un filtrage pour que celui-ci ignore une adresse IP donnée (par exemple 192.168.56.1 ? 10. fail2ban-client permet également de bannir / bloquer ou débloquer une adresse IP. Par exemple dans le cas de l’adresse IP 192.168.56.1 on aurait : fail2ban-client set apache-auth banip 192.168.56.1 fail2ban-client set apache-auth unbanip 192.168.56.1 10 Autres modules “utiles” 10.1 mod_allowmethods Ce module permet de restreindre aisément les méthodes HTTP pouvant être utilisées sur le serveur. Le protocole HTTP 1.1 supporte de nombreuses méthodes telles que OPTIONS, HEAD, etc. Aussi, il est peut être pertinent de ne laisser active que certaines d’entre elles telles que HEAD, POST, GET. Les manipulations à effectuer sont : 1. consulter les informations sur le module dans la documentation en ligne d’Apache ac- cessible via le lien ci-après http://httpd.apache.org/docs/2.4/ ; 2. l’activer et faire les manipulations nécessaires en terme de configuration au niveau des différents virtualHost. 10.2 mod_proxy Le module mod_proxy permet d’utiliser Apache pour mettre en place un proxy inverse (reverse proxy). On rappelle qu’à ce moment là un client web passera nécessairement par lui pour accéder aux serveurs internes, puisque le proxy sera placé en frontal des serveurs web. Un intérêt en plus de la sécurité et de pouvoir faire de la répartition de charge. Dans ce contexte, 10
le Web Application Firewall serait naturellement installé sur la machine qui fait office de proxy (le frontend ) et non sur les serveurs qui hébergent effectivement les sites (les backend ). Les manipulations à effectuer sont : 1. lancer dans Google une recherche sur How To Use Apache as a Reverse Proxy with mod_proxy (choisir le lien digitalocean) ; 2. en trouvant un site adéquat décrivant le processus de configuration, réfléchir à la façon dont cela pourrait être mis en place pour l’accès au site www.site1.fr ; 3. installer Apache sur la machine hôte et créer un fichier de configuration site4.conf qui fasse que le nom de domaine www.site4.fr corresponde à un reverse proxy qui masque le site 3 dont l’adresse est http://192.168.56.202:8080. ATTENTION : ne pas oublier de définir la correspondance entre le nom de do- maine www.site4.fr et l’adresse IP de la machine hôte 192.168.56.1 dans le fichier /etc/hosts de cette dernière. 10.3 mod_http2 Le module mod_http2 a pour objet l’activation du support du protocole HTTP/2 qui succède au protocole HTTP 1.1. Il est issu du protocole SPDY développé par Google et sa spécification a été publié en mai 2015 via la RFC 7540. En dehors de l’activation du support au niveau du service http, les applications existantes n’ont pas besoin d’être modifiées, sauf à vouloir bénéficier des apports du nouveau protocole. La majorité de la syntaxe HTTP 1.1 (méthodes, codes, etc.) est conservée dans HTTP/2. L’apport porte notamment sur la segmentation et le transport des données entre client et serveur, avec à la clé des transmissions plus rapides. Les manipulations à effectuer sont : 1. essayer d’activer ce module et de le mettre en place au niveau de la configuration du site www.site2.fr en consultant la page accessible via https://http2.pro/doc/Apache ; ATTENTION : comme indiqué dans la section Apache 2.4.27, HTTP/2 not supported in prefork, le mpm_prefork_module n’est pas compatible avec ce module. Il vous fau- dra donc procéder aux manipulations indiquées dans la section pour activer un autre Multi-Processing Module. 2. sur la machine hôte, après avoir éventuellement installer curl, lancer successivement les commandes suivantes et regarder les affichages produits curl -k -v --http1.1 https://www.site2.fr curl -k -v --http2 https://www.site2.fr 3. se connecter avec le navigateur sur http://www.site2.fr et analyser les en-têtes du serveur avec Web Developer. 11
Vous pouvez aussi lire