Vous venez de mettre en ligne un site web qui vous permettra de partager des informations avec le monde entier. Malheureusement, le monde n’est pas constitué que de personnes bien intentionnées. Dans ce chapitre, je vais vous montrer trois façons de renforcer la sécurité d’un site web :
en évitant de donner des informations sur votre architecture ;
en restreignant l’accès à certaines ressources ;
en utilisant le protocole HTTPS.
Sécurisez la configuration de votre serveur web
En matière de sécurité, il est toujours préférable de donner le moins d’informations possibles sur son système à de potentiels attaquants. Or, par défaut, Apache renvoie des en-têtes HTTP contenant le nom et la version du serveur web, ainsi que le nom du système d’exploitation : autant d’informations qui peuvent intéresser une personne mal intentionnée.
Pour éviter ça, Ubuntu vous facilite la vie en regroupant les directives sensibles en termes de sécurité dans le fichier /etc/apache2/conf-available/security.conf
. Dans ce fichier, configurez les directives comme ceci, c’est la configuration qui donne le moins d’informations :
ServerTokens Prod ServerSignature Off
Rechargez ensuite la configuration d’Apache :
$ sudo systemctl reload apache2
Idéalement, il faudrait également “réduire la surface d’attaque” de votre serveur en désactivant tous les modules que vous n’utilisez pas. C’est parfois compliqué de savoir quel module on utilise vraiment, mais c’est très instructif d’aller chercher dans la documentation à quoi sert chaque module activé sur votre système.
Au-delà des questions générales de sécurité de votre serveur, vous serez peut-être amené à stocker des fichiers sensibles dont vous souhaitez restreindre l’accès. Je vais vous montrer comment faire.
Restreignez l’accès aux ressources sensibles
Apache permet de restreindre l’accès à des ressources en fonction d’un grand nombre de critères. Les modes d’authentification les plus courants sont certainement par IP et par login/mot de passe.
Commencez par créer les données à protéger :
$ sudo mkdir /var/www/html/www.example.com/top_secret $ echo “voici mon secret” > /var/www/html/www.example.com/top_secret/index.html
Pour protéger votre répertoire top_secret
, ajoutez la section suivante à la configuration de votre <VirtualHost /> dans /etc/apache2/sites-available/www.example.com.conf
et rechargez la configuration Apache :
<Directory /var/www/html/www.example.com/top_secret> AuthType Basic AuthName “Accès restreint aux utilisateurs authentifiés” AuthBasicProvider file AuthUserFile “/etc/apache2/passwords” Require ip 192.168.29.3 Require valid-user </Directory>
La directive qui permet de restreindre l’accès à une ressource est Require
.
Ici, toutes les requêtes venant de l’IP 192.168.29.3 sont automatiquement acceptées. Une fenêtre d’authentification est proposée aux requêtes venant d’autres IP. Un couple login/mot de passe valide doit être entré pour que l’accès soit autorisé.
Les directives Auth*
précisent le fonctionnement de cette autorisation par mot de passe :
AuthType Basic
: indique une authentification par login/mot de passe simple.AuthName
: permet de définir le titre de la fenêtre d’authentification qui sera affichée aux clients.AuthBasicProvider file
: indique que les comptes utilisateurs sont définis dans un fichier.AuthUserFile
: précise le fichier où sont enregistrés les comptes utilisateurs.
Il vous faut donc maintenant créer ce fameux fichier de mots de passe grâce à la commande htpasswd
:
$ sudo htpasswd -c /etc/apache2/passwords marie
On vous demande de définir un mot de passe et voilà, vous venez de créer l’utilisateur “marie”. L’option -c
n’est à utiliser que pour le premier utilisateur, car elle crée le fichier s’il n’existe pas.
Vous pouvez tester en vous connectant à http://www.example.com/top_secret/
depuis votre machine cliente :
Vous pouvez aussi envisager d’utiliser votre annuaire LDAP comme base d’utilisateurs plutôt qu’un simple fichier. Pour cela, activez le module authnz_ldap :
$ sudo a2enmod authnz_ldap $ sudo systemctl reload apache2
Modifiez ensuite votre VirtualHost comme ceci :
<Directory /var/www/html/www.example.com/top_secret> AuthType Basic AuthName “Accès restreint aux utilisateurs authentifiés” AuthBasicProvider ldap AuthLDAPURL ldap://localhost/ou=Personnes,dc=mon-entreprise,cd=com?uid?sub Require ip 192.168.29.3 Require valid-user </Directory>
Vous voyez que la directive AuthBasicProvider
est passée de file
à ldap
. Vous avez donc logiquement remplacé la directive AuthUserFile
par la directive AuthLDAPURL
qui indique la recherche à effectuer dans l’annuaire sous la forme d’une URI. Voici ensuite le détail de l’URI utilisée :
Dans ce cas, souvenez-vous, l’utilisateur “Marie Dupond” que vous aviez créé avait pour login et mot de passe “mdupond”.
Les possibilités de contrôle d’accès et d’authentification que permet Apache sont nombreuses et dépassent le cadre de ce cours.
Vous pouvez remarquer que les authentifications par mot de passe que vous avez mises en place transmettent le mot de passe en clair. Ce n’est pas une bonne pratique de sécurité, car toute personne ayant accès au réseau pourrait lire ces mots de passe. Je vais donc maintenant vous apprendre à chiffrer votre connexion par le protocole HTTPS.
Sécurisez vos connexions grâce à HTTPS
Il y a plusieurs intérêts à configurer votre site en HTTPS :
vos connexions sont chiffrées, ce qui empêche de pouvoir intercepter vos mots de passe mais aussi vos informations de session, vos cookies, etc. ;
le serveur est identifié par un certificat, ce qui permet au client de pouvoir s’assurer que le serveur auquel il se connecte est bien celui qu’il prétend être ;
HTTPS est maintenant la norme, et les moteurs de recherche, Google en tête, référencent mieux les sites HTTPS que les sites HTTP ;
les navigateurs web commencent à bloquer les sites Internet qui ne sont pas en HTTPS.
Pour pouvoir configurer votre site en HTTPS, vous devrez générer un certificat pour votre serveur. Tout le monde peut générer un certificat auto-signé avec avec les binaires d’OpenSSL, mais pour que les clients soient sûrs que le certificat présenté à la connexion corresponde au serveur qu’ils veulent joindre, ils font confiance à une autorité de certification, comme IdenTrust ou Let's Encrypt, pour valider le certificat du serveur.
Pour pouvoir générer un certificat signé par Let’s Encrypt, vous devez installer le paquet letsencrypt
:
$ sudo apt-get install letsencrypt
Vous n’avez ensuite qu’une simple commande à exécuter pour générer votre certificat mais… pour vérifier que vous êtes bien propriétaire du domaine DNS que vous voulez chiffrer, Let’s Encrypt va tenter une connexion sur le port 443 de votre machine en utilisant votre domaine DNS. En conséquence :
vous devez avoir un domaine DNS valide qui pointe sur votre serveur ;
vous devez générer votre certificat depuis la machine sur laquelle pointe votre domaine DNS ;
en mode
standalone
comme je vais vous montrer, votre serveur web ne doit pas écouter le port 443 quand vous lancez la commande, car c’est le logiciel Let's Encrypt lui-même qui va utiliser ce port le temps de faire la vérification.
Si vous n’avez pas de nom de domaine DNS valide, vous ne pourrez pas reproduire la commande suivante, mais au moins vous saurez comment faire le jour où vous en aurez besoin :
$ letsencrypt certonly --standalone --agree-tos --email mon_email@example.com -d example.com -d www.example.com --standalone-supported-challenges http-01
La commande à utiliser s’appelle tout simplement letsencrypt
:
la sous-commande
certonly
demande de générer un certificat mais sans l’installer dans votre serveur web ;l’option
--standalone
indique que c’est le clientletsencrypt
lui-même qui va faire la vérification sur le port 443 ;--agree-tos
valide les conditions d’utilisation du service ;--email
indique un e-mail de contact ;-d
indique le domaine à inclure dans le certificat. Vous pouvez avoir plusieurs options-d
pour chacun des sous-domaines que vous voulez inclure dans le certificat ;--standalone-supported_challenges http-01
définit la méthode de validation de la connexion à votre serveur.
Vous trouverez les clés générées dans /etc/letsencrypt/live/example.com/
. Elles sont valables 3 mois, et vous pourrez les renouveler avant leur date d’expiration par la commande :
$ letsencrypt certonly --standalone --agree-tos --email mon_email@example.com -d example.com -d www.example.com --standalone-supported-challenges http-01 --renew-by-default
C’est la même commande que précédemment, à laquelle vous rajoutez juste l’option --renew-by-default
.
Pour pouvoir utiliser ces certificats dans Apache, modifiez votre VirtualHost comme ceci :
<IfModule mod_ssl.c> <VirtualHost *:443> ... # On active le chiffrement (HTTPS) SSLEngine On SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem ... </VirtualHost> </IfModule>
Les balises <IfModule />
qui entourent votre VirtualHost indiquent que cette configuration ne sera prise en compte que si le module mod_ssl
est chargé. Pensez donc à le charger par la commande :
$ sudo a2enmod ssl
Les directives suivantes ajoutées par exemple après la définition de votre DocumentRoot
activent le SSL, et précisent le chemin de vos fichiers de certificat.
Enfin, vous voyez que votre VirtualHost n’est plus actif que sur le port 443. Certains clients auront certainement oublié d’utiliser la connexion HTTPS, et vous allez les rediriger vers la connexion chiffrée en rajoutant les lignes suivantes au début de votre fichier, avant vos balises <VirtualHost *:443 />
existantes :
<VirtualHost *:80> ServerName www.example.com ServerAlias example.com ServerAdmin webmaster@example.com <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent] </IfModule> </Virtualhost>
Je ne vais pas rentrer dans le détail des règles de réécriture gérées par le module mod_rewrite
(activé par défaut), mais ici toutes les requêtes HTTP vers les domaines example.com ou www.example.com seront réécrites à l’identique et de manière transparente en HTTPS. C’est exactement ce qui se passe si vous tapez l’adresse suivante dans la barre d’adresse de votre navigateur :
http://www.google.fr/search?q=openclassrooms
Google vous redirige automatiquement vers la même adresse en https://.
En résumé
Pour renforcer la sécurité sur un serveur de production, vous pouvez configurer Apache pour ne plus transmettre d’informations système dans les headers.
Il est possible de restreindre l’accès d’un répertoire à certaines IP ou à certains utilisateurs grâce à la directive
Require
.La liste des utilisateurs autorisés à accéder à une partie restreinte de votre site peut être gérée à travers un fichier texte ou à travers un annuaire LDAP.
Let’s Encrypt est une solution gratuite et pratique pour signer des certificats et configurer un site en HTTPS
Dans le chapitre suivant, vous rendrez votre site web plus dynamique grâce au langage PHP.