174 lines
6.2 KiB
Markdown
174 lines
6.2 KiB
Markdown
% Introduction au HTTPS
|
|
% Sylvain Eliade — S.C.O.P. Cadoles
|
|
% Mai 2019
|
|
|
|
## Introduction au HTTPS
|
|
|
|
* HTTP encapsulé dans une connexion chiffrée
|
|
* Historiquement avec le protocole SSL
|
|
* Aujourd'hui c'est TLS
|
|
|
|
---
|
|
|
|
## Chiffrement à clé publique et privée
|
|
|
|
* La clé publique est distribuée (non secrète) et ne sert qu'à chiffrer
|
|
* La clé privée est secrète et sert à déchiffrer
|
|
|
|
Le serveur possède une clé privée (secrète) et une clé publique (appelée certificat), signée par une *autorité*.
|
|
|
|
---
|
|
|
|
## Certificats
|
|
|
|
* Prouve l'identité du propriétaire du certificat
|
|
* Doivent être signés par une autorité reconnue (ou plusieurs)
|
|
* Peuvent être signés par soi-même (*self signed*) mais c'est relou (difficile à utiliser), et du coup ça ne prouve pas grand chose
|
|
|
|
---
|
|
|
|
## Autorités
|
|
|
|
* Système hiérarchique (une autorité peut signer des certificats d'une sous-autorité, etc.) : on parle de *chaîne* de certificats
|
|
* Combine des acteurs publics (états, ministères, etc.) et privés (entreprises)
|
|
* On doit avoir confiance envers ces autorités
|
|
* Chaque OS a un « app store » de certificats d'autorités (paquet `ca-certificates` dans Debian/Ubuntu)
|
|
* Système centralisé, moyennement sûr (nombreux cas d'autorités qui font n'importe quoi)
|
|
* Un peu mieux depuis Let's Encrypt
|
|
|
|
---
|
|
|
|
## Phase de négociation (handshake) TLS
|
|
|
|
![](./img/tls_handshake.gif)
|
|
|
|
---
|
|
|
|
En simplifié :
|
|
|
|
1. Le client se connecte au serveur, lui indique les protocoles cryptographiques qu'il supporte (cipher suite)
|
|
2. Le serveur lui répond, en indiquant le protocole choisi, ainsi que son certificat public (signé par une autorité).
|
|
3. Le client vérifie le certificat.
|
|
4. Échange de clé entre le client et le serveur. Cette clé est spécifique à cette session entre client et serveur.
|
|
|
|
Ensuite le client et le serveur communiquent en HTTP entre eux, mais tout est chiffré à l'aide des clés échangées.
|
|
|
|
---
|
|
|
|
La phase de négociation ne se reproduit pas à chaque requête HTTP : normalement la connexion TLS reste ouverte une ou deux minutes, permettant de faire passer d'autres requêtes.
|
|
|
|
De même, les étapes 1 à 3 peuvent être ignorées quand le serveur et le client se connaissent déjà et ont encore les infos de chacun en cache.
|
|
|
|
---
|
|
|
|
## Vérification OCSP
|
|
|
|
A l'étape 3, le client peut aller vérifier auprès d'un serveur OCSP (*Online Certificate Status Protocol*) que le certificat du serveur est bien valide.
|
|
|
|
De nos jours, le serveur peut s'en charger lui-même (*OCSP stapling*), il envoie une certification OCSP (avec la date) au client : évite un aller-retour du client avec le serveur OCSP.
|
|
|
|
---
|
|
|
|
## SNI (Server Name Indication)
|
|
|
|
Rappel du HTTP : le nom d'hôte demandé est transmis dans l'entête `Host` de la requête HTTP.
|
|
|
|
Donc : l'hôte demandé est dans la requête chiffrée, AVANT que le serveur web ne puisse savoir quel certificat utiliser pour le HTTPS !
|
|
|
|
Solution : le SNI !
|
|
|
|
---
|
|
|
|
* Le nom d'hôte demandé est inscrit dans la connexion TLS par le client
|
|
* Très bien supporté de nos jours (si pas supporté : utilisation du vhost par défaut)
|
|
* Inconvénient : le nom n'est pas chiffré (possibilité d'interception pour voir quel site vous visitez)
|
|
|
|
---
|
|
|
|
## Configuration Apache HTTPS
|
|
|
|
Attention : il faut créer un vhost différent, car le port est différent.
|
|
|
|
```
|
|
<VirtualHost *:443>
|
|
ServerName cesi.test
|
|
SSLEngine on
|
|
SSLCertificateFile "/var/www/certs/cesi.cert"
|
|
SSLCertificateKeyFile "/var/www/certs/cesi.private"
|
|
</VirtualHost>
|
|
```
|
|
|
|
Si on a un site en HTTPS il est recommandé que la version HTTP ne fasse que rediriger vers le site en HTTPS (plus simple niveau config serveur).
|
|
|
|
---
|
|
|
|
## Let's Encrypt
|
|
|
|
* Autorité de certification à but non lucratif qui délivre des certificats signés gratuits.
|
|
* Avant LE, il fallait payer (en général cher) pour avoir un certificat signé par une autorité !
|
|
* Inconvénient : durée du certificat limitée à 90 jours.
|
|
* Inconvénient : ne marche pas pour les domaines privés (réseau privé).
|
|
* Plusieurs manières de valider qu'on est bien propriétaire d'un domaine : HTTP ou DNS
|
|
* Plusieurs clients : certbot, dehydrated, etc.
|
|
|
|
---
|
|
|
|
## Let's Encrypt : certbot
|
|
|
|
* `# apt install certbot python-certbot-apache`
|
|
* `# certbot --apache`
|
|
|
|
C'est tout, il va poser des questions et va tout configurer à votre place… Mais des fois ça ne marche pas trop du coup quand notre configuration est un peu complexe.
|
|
|
|
---
|
|
|
|
## Let's Encrypt : [dehydrated](https://github.com/lukas2511/dehydrated)
|
|
|
|
Plus léger que certbot, un peu plus manuel.
|
|
|
|
* `# apt install dehydrated dehydrated-apache2`
|
|
* Ajouter les noms de domaine dans le fichier `/etc/dehydrated/domains.txt` (un par ligne)
|
|
* Lancer `dehydrated -c`
|
|
* Configurer son vhost :
|
|
|
|
```
|
|
SSLCertificateFile /var/lib/dehydrated/certs/example.org/fullchain.pem
|
|
SSLCertificateKeyFile /var/lib/dehydrated/certs/example.org/privkey.pem
|
|
```
|
|
|
|
Tester la config et recharger Apache.
|
|
|
|
---
|
|
|
|
## Attention !
|
|
|
|
Dans certains cas, `apache2ctl configtest` ne renvoie pas d'erreur s'il y a un problème au niveau des certificats, mais ensuite le `reload` (ou `graceful`) plantera !
|
|
|
|
Exemple : si on utilise `chain.pem` de Let's encrypt (qui ne contient que la chaîne de certification, et pas le certificat lui-même) à la place de `fullchain.pem`.
|
|
|
|
Solution : vérifier `/var/log/apache2/error.log` après un reload si on a modifié des trucs dans la config SSL !
|
|
|
|
---
|
|
|
|
## Exercice 1
|
|
|
|
Installer `dehydrated` et le configurer pour le domaine `cesi.sylvain.eliade.net`. Lancer dehydrated.
|
|
|
|
Il va tenter de vérifier l'appartenance du domaine et échouer (logique). A la place, prendre les fichiers `.pem` fournis et les recopier dans le bon répertoire.
|
|
|
|
Configurer un vhost Apache pour ce domaine, utilisant les certificats fournis. Ne pas oublier d'activer `mod_ssl` : `a2enmod ssl` et redémarrer Apache.
|
|
|
|
Dans `/etc/hosts` inscrire une ligne avec `127.0.0.1 cesi.sylvain.eliade.net`.
|
|
|
|
Tester la config avec curl, et si possible le navigateur de la machine hôte.
|
|
|
|
## Exercice 2 (facultatif)
|
|
|
|
Générer un certificat auto-signé :
|
|
|
|
```
|
|
# mkdir /etc/ssl/localcerts/
|
|
# openssl req -new -x509 -days 365 -nodes -out /etc/ssl/localcerts/apache.pem -keyout /etc/ssl/localcerts/apache.key
|
|
```
|
|
|
|
Le mettre en place dans Apache, et vérifier que ça fonctionne avec un navigateur (qui affichera un message d'avertissement). |