HTTPSDans notre précédent article sur Squid, nous avons décrit en détail la configuration d’un serveur proxy cache HTTP. Dans l’état actuel, le serveur ne gère pas du tout les connexions HTTPS. Étant donné que l’écrasante majorité des sites web populaires utilisent un protocole sécurisé, nous n’avons fait qu’une partie du travail. Cet article sera donc consacré à la gestion des requêtes HTTPS.

Introduction

Depuis la version 3.5, Squid offre une fonctionnalité qui s’appelle le SSL-Bump. Notre démarche consistera à créer un certificat racine que l’on exportera vers les navigateurs web du réseau. Lorsque ceux-ci se connecteront sur un site HTTPS, ce trafic sera dévié vers un deuxième port de Squid, et le serveur générera un certificat dynamique.

La documentation officielle est malheureusement quelque peu laconique et pas toujours très claire, mais on arrive à faire fonctionner le tout avec une bonne dose d’obstination et d’expérimentation.

Implications éthiques

Strictement parlant, l’analyse des flux HTTPS telle que nous la pratiquons ici n’est rien d’autre qu’une attaque MIDM (Man In The Middle). La documentation de Squid contient d’ailleurs la mise en garde suivante.

On the ethical side; consider some unknown other person reading all your private communications. What would you be happy with them doing? Be considerate of others.

L’Agence nationale de la sécurité des systèmes d’information offre une page d’informations sur l’analyse des flux HTTPS. La problématique à laquelle nous sommes confrontés est résumée dans le passage suivant.

L’analyse d’un contenu (web par exemple) sécurisé à l’aide de TLS, peut toutefois se justifier afin de s’assurer que les données provenant d’un réseau non maîtrisé (Internet par exemple) ne représentent pas une menace pour le système d’information interne. Les architectures visant à déchiffrer les flux TLS, pour permettre leur analyse, « tordent » donc le modèle pour lequel ce protocole est conçu.

Avant de mettre en oeuvre cette solution dans une entreprise, une école ou une médiathèque, il s’agit donc d’être conscient de ces implications et de prendre les mesures légales nécessaires sous forme d’une clause au contrat et d’une page d’accueil explicative qui détaillent ce qui se passe sous le capot.

Vérifier les options de compilation

Squid doit impérativement être compilé avec les options suivantes.

./configure \
--with-openssl \
--enable-ssl-crtd \
...

Le paquet binaire fourni par Red Hat Enterprise Linux 7 et CentOS 7 est parfaitement utilisable tel quel. La commande squid -v affiche l’ensemble des options de compilation de l’application.

$ squid -v | egrep '(--with-openssl|--enable-ssl-crtd)' > /dev/null && echo OK
OK

Configuration du pare-feu

Dans notre première configuration de Squid comme proxy cache transparent HTTP, nous avons redirigé les requêtes HTTP (port 80) vers le port 3128 de Squid. Pour utiliser le HTTPS, ce sera un peu plus compliqué.

  • Les requêtes vers le port 80 seront redirigées vers le port 3128.
  • Les requêtes vers le port 443 seront redirigées vers le port 3129.
  • Squid intercepte à son tour ces requêtes et utilise le port 3130 en interne.

Voici à quoi pourra ressembler concrètement la configuration du pare-feu.

$ sudo firewall-cmd --permanent --add-service=squid
$ sudo firewall-cmd --permanent \
  --add-forward-port=port=80:proto=tcp:toport=3128:toaddr=192.168.3.1
$ sudo firewall-cmd --permanent --add-port=3129/tcp
$ sudo firewall-cmd --permanent \
  --add-forward-port=port=443:proto=tcp:toport=3129:toaddr=192.168.3.1
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all
internal (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp3s1
  sources:
  services: dhcp dns squid ssh
  ports: 3129/tcp
  protocols:
  masquerade: no
  forward-ports: port=80:proto=tcp:toport=3128:toaddr=192.168.3.1
        port=443:proto=tcp:toport=3129:toaddr=192.168.3.1
  source-ports:
  icmp-blocks:
  rich rules:

InfoLes deux premières règles concernant l’ouverture du port 3128 pour Squid et la redirection des requêtes HTTP vers ce port sont peut-être déjà en vigueur. Quant à l’adresse IP 192.168.3.1, c’est celle de l’interface réseau côté LAN du proxy.

Créer un certificat racine auto-signé

Le certificat racine sera utilisé par Squid pour générer à la volée les certificats dynamiques pour les sites qui passent par le proxy. Notez que par là, nous devenons une autorité de certification pour le réseau local.

Dans un premier temps, on va trouver un endroit approprié pour stocker le certificat. Les permissions seront définies en fonction de l’utilisateur système squid et du groupe système squid correspondant.

$ cd /etc/squid
$ sudo mkdir ssl_cert
$ sudo chown squid:squid ssl_cert
$ cd ssl_cert

Ensuite, on va créer le certificat en fournissant les informations nécessaires. Notre certificat sera valable pour dix ans (-days 3650), et le fichier résultant sera nommé en fonction du nom d’hôte pleinement qualifié de la machine (hostname --fqdn), en l’occurrence amandine.sandbox.lan.pem. Voici à quoi cela peut ressembler.

$ sudo openssl req -new -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -x509 -extensions v3_ca -keyout certificat.pem -out certificat.pem
Generating a 4096 bit RSA private key
..................................................................
..................................................................
................................................................++
writing new private key to 'certificat.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:FR
State or Province Name (full name) []:Gard
Locality Name (eg, city) [Default City]:Montpezat
Organization Name (eg, company) [Default Company Ltd]:Microlinux
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:amandine.sandbox.lan
Email Address []:info@microlinux.fr

Enfin, créer un certificat encodé en DER (Distinguished Encoding Rules) que l’on pourra importer dans les navigateurs web des postes clients.

$ sudo openssl x509 -in certificat.pem -outform DER -out certificat.der

Au final, on obtient deux fichiers qui ressemblent à ceci.

$ ls
certificat.der certificat.pem

Le fichier certificat.der devra être distribué aux postes clients, et le certificat devra être installé manuellement dans les navigateurs web.

Pour Mozilla Firefox, ouvrir Préférences > Vie privée et sécurité > Certificats > Afficher les certificats et cliquer sur Importer.

Squid Firefox

Sélectionner le fichier certificat.der et cocher les options proposées.

Squid Firefox

Le certificat apparaît désormais dans la liste des Autorités, sous le nom que l’on a choisi à la rubrique Organization Name.

Squid Firefox

InfoCertains navigateurs web comme Edge sous Microsoft Windows ou Safari sous macOS vous font sauter à travers des cerceaux en feu pour importer manuellement un certificat local.

Adapter la configuration de Squid

Pour la configuration de Squid, je me suis basé sur l’exemple fourni dans la documentation, en l’adaptant à mes besoins.

# Ports
http_port 3130
http_port 3128 intercept
https_port 3129 intercept ssl-bump \
  cert=/etc/squid/ssl_cert/certificat.pem \
  generate-host-certificates=on \
  dynamic_cert_mem_cache_size=64MB

# SSL certificate generation
sslcrtd_program /usr/lib64/squid/ssl_crtd -s /var/lib/squid/ssl_db -M 64MB
sslcrtd_children 32 startup=5 idle=1

# SSL-Bump
acl step1 at_step SslBump1
ssl_bump peek step1
ssl_bump bump all

J’initialise le cache qui contiendra les certificats TLS créés à la volée. Je dois définir le contexte SELinux manuellement, en le calquant sur celui du répertoire /var/spool/squid. Pour plus de détails, voir ce rapport de bug.

$ sudo install -d -m 750 -o squid -g squid /var/lib/squid
$ sudo semanage fcontext -a -e /var/spool/squid /var/lib/squid
$ sudo runuser -u squid -- /usr/lib64/squid/ssl_crtd -c \
  -s /var/lib/squid/ssl_db
Initialization SSL db...
Done
$ sudo restorecon -FRv /var/lib/squid

ImportantAttention : Si vous utilisez la complétion automatique, veillez à ne pas ajouter de barre oblique / à la fin des chemins /var/spool/squid et /var/lib/squid en argument à semanage fcontext.

Il ne reste plus qu’à redémarrer Squid.

$ sudo systemctl restart squid

Vérifier le fonctionnement

Pour vérifier le fonctionnement du proxy pour les protocoles HTTP et HTTPS, il suffit de naviguer au hasard sur des sites sécurisés et non sécurisés, en gardant un oeil sur le contenu du journal /var/log/squid/access.log.

$ sudo tail -f /var/log/squid/access.log
1520243219.271 39 192.168.3.2 TCP_MISS_ABORTED/000 0 
POST https://www.youtube.com/youtubei/v1/log_event? - ...
1520243220.667 154 192.168.3.2 TCP_MISS/200 1989 
GET http://www.slackware.com/getslack/ - ...

Désactiver le proxy en cas de blocage

Une fois que le proxy est mis en place pour les protocoles HTTP et HTTPS, il est impossible de le contourner. En cas de problème, c’est bien de savoir comment désactiver le proxy – du moins temporairement – pour ne pas rester bloqué.

Concrètement, il suffit de supprimer la redirection des ports dans le pare-feu.

$ sudo firewall-cmd --permanent \
  --remove-forward-port=port=80:proto=tcp:toport=3128:toaddr=192.168.3.1
$ sudo firewall-cmd --permanent \
  --remove-forward-port=port=443:proto=tcp:toport=3129:toaddr=192.168.3.1
$ sudo firewall-cmd --reload

Notre prochain article sera consacré à la gestion des sites qui peuvent poser problème.


La rédaction de cette documentation demande du temps et des quantités significatives de café espresso. Vous appréciez ce blog ? Offrez un café au rédacteur en cliquant sur la tasse.