• 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 23/06/2022

Sécurisez votre serveur web

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 :

Capture d'écran d'un navigateur montrant une fenêtre d'authentification pour se connecter aux fichiers du répertoire
Vous devez vous authentifier pour accéder aux fichiers du répertoire "top_secret"

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 :

L'URI LDAP est recopiée ici avec ses différentes parties dans des couleurs différentes et des explications pour chaque partie.
Détail de l'URI à utiliser pour s'authentifier grâce à votre annuaire LDAP

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 client  letsencrypt  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.

Exemple de certificat de réussite
Exemple de certificat de réussite