Gérer les connexions HTTPS avec Squid sous CentOS

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

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.

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 la configuration du pare-feu.

# Commandes
IPT=/usr/sbin/iptables
...
# Réseau local
IFACE_LAN=enp3s1
...
# Serveur
SERVER_IP=192.168.3.1
...
# Squid 
$IPT -A INPUT -p tcp -i $IFACE_LAN --dport 3128 -j ACCEPT
$IPT -A INPUT -p udp -i $IFACE_LAN --dport 3128 -j ACCEPT
$IPT -A PREROUTING -t nat -i $IFACE_LAN -p tcp ! -d $SERVER_IP \
 --dport 80 -j REDIRECT --to-port 3128
$IPT -A INPUT -p tcp -i $IFACE_LAN --dport 3129 -j ACCEPT
$IPT -A INPUT -p udp -i $IFACE_LAN --dport 3129 -j ACCEPT
$IPT -A PREROUTING -t nat -i $IFACE_LAN -p tcp ! -d $SERVER_IP \
 --dport 443 -j REDIRECT --to-port 3129
$IPT -A INPUT -p tcp -i $IFACE_LAN --dport 3130 -j ACCEPT
$IPT -A INPUT -p udp -i $IFACE_LAN --dport 3130 -j ACCEPT

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
# mkdir ssl_cert
# 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.

# openssl req -new -newkey rsa:2048 -sha256 -days 3650 -nodes \
  -x509 -extensions v3_ca -keyout $(hostname --fqdn).pem \
  -out $(hostname --fqdn).pem
Generating a 2048 bit RSA private key
..............................................+++
.................................+++
writing new private key to 'amandine.sandbox.lan.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) []: [Entrée]
Common Name (eg, 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. Là aussi, on utilisera le nom d’hôte pleinement qualifié du serveur pour nommer le fichier résultant.

# openssl x509 -in $(hostname --fqdn).pem -outform DER \
  -out $(hostname --fqdn).der

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

# ls
amandine.sandbox.lan.der amandine.sandbox.lan.pem

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

Mozilla Firefox

Ouvrir Édition > Préférences > Avancé > Certificats > Afficher les certificats et cliquer sur Importer.

Certificat Mozilla Firefox

Sélectionner le fichier amandine.sandbox.lan.der et cocher l’ensemble des options proposées.

Certificat Mozilla Firefox

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

Certificat Mozilla Firefox

Konqueror

L’ajout du certificat dans Konqueror ne se fait pas directement dans la configuration du navigateur, mais dans les Préférences SSL de KDE.

Certificat Konqueror

Cliquer sur Ajouter, sélectionner le fichier amandine.sandbox.lan.der et confirmer en cliquant sur Appliquer.

Certificat Konqueror

Le certificat apparaît alors tout en bas dans la liste, dans les Certificats ajoutés par l’utilisateur.

Certificat Konqueror

Google Chrome

Ouvrir Paramètres > Paramètres avancés > Gérer les certificats > Autorités et cliquer sur Importer.

Google Chrome

Importer le fichier amandine.sandbox.lan.der en cochant tous les paramètres de confiance.

Google Chrome

Le certificat apparaît dans la liste des autorités sous le nom que l’on a choisi à la rubrique Organization Name, préfixé de org-.

Google Chrome

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 du proxy
http_port 3130
http_port 3128 intercept
https_port 3129 intercept ssl-bump \
  cert=/etc/squid/ssl_cert/amandine.sandbox.lan.pem \
  generate-host-certificates=on dynamic_cert_mem_cache_size=4MB

# Emplacement de ssl_crtd et du cache des certificats TLS
sslcrtd_program /usr/lib64/squid/ssl_crtd \
  -s /var/lib/squid/ssl_db -M 4MB
sslcrtd_children 8 startup=1 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.

# install -d -m 750 -o squid -g squid /var/lib/squid
# semanage fcontext -a -e /var/spool/squid /var/lib/squid
# runuser -u squid -- /usr/lib64/squid/ssl_crtd -c \
  -s /var/lib/squid/ssl_db
# restorecon -FRv /var/lib/squid

Attention à ne pas ajouter de barre oblique / à la fin des chemins /var/spool/squid et /var/lib/squid en argument à semanage fcontext.

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

# 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.

# 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/ - ...
Ce contenu a été publié dans CentOS, Documentation Microlinux, Non classé, avec comme mot(s)-clé(s) , . Vous pouvez le mettre en favoris avec ce permalien.

15 réponses à Gérer les connexions HTTPS avec Squid sous CentOS

  1. Yann dit :

    Bonjour,

    Une petite remarque concernant votre article : je pense qu’il serait bon d’ajouter un paragraphe discutant des implications de sécurité d’une telle approche. En effet, le serveur mandataire devient un composant ultra critique car il permet de signer des certificats pour n’importe quel site web et permet d’avoir accès en clair à toutes les communications. Voir à ce sujet le guide de l’ANSSI : https://www.ssi.gouv.fr/administration/guide/recommandations-de-securite-concernant-lanalyse-des-flux-https/.

    Il faut également bien prendre en compte les aspects juridiques de la mise en place d’une telle solution (secret des correspondances notamment).

    Cordialement

    • kikinovak dit :

      Paradoxalement, je fais ça sur la demande d’une entreprise qui me dit qu’elle doit répondre à l’obligation légale d’enregistrer l’ensemble de son trafic web à partir du moment où elle met à disposition une connexion wifi. Elle entend par là : savoir quelle adresse IP du réseau local s’est connecté à quel site quel jour et quelle heure, et garder une trace de tout cela pendant un an au moins. Et vu que ça doit être humainement lisible, j’ai opté pour la solution Squid + SquidAnalyzer (article à venir).

  2. DJR dit :

    Hello,

    Merci pour ce billet qui m’a permis de mettre cela en place très simplement ! ;-))

    Une p’tite remarque concernant les lignes iptables; tu as le moyen de factoriser tes lignes en faisant :
    $IPT -A INPUT -p tcp -i $IFACE_LAN –dport 3127:3129 -j ACCEPT
    $IPT -A INPUT -p udp -i $IFACE_LAN –dport 3127:3129 -j ACCEPT

  3. Thibaut BARTHALAY dit :

    Bonjour,

    Tout d’abord, merci pour tous ces tutos qui m’ont bien aidé jusqu’à présent.

    Je viens de suivre la procédure a la lettre.

    Alors, mon problème est le suivant :

    Je peux voir dans les log de squid les site en https que je “visite” mais le client ne peux pas réellement accès au site. Comme si Squid ne redirigeait pas le trafic vers le poste client après avoir intercepté la trame … Une idée ?

    Bonne journée,

    BARTHLAY Thibaut.

    • kikinovak dit :

      Bonjour,

      La gestion du HTTPS avec Squid est une telle usine à gaz innommable que le diagnostic à distance me paraît une chose impossible. En ce qui me concerne, je ne peux que vous conseiller de vous inscrire à la mailing list de Squid. Avant de faire fonctionner tout ça, je me suis bien renseigné là-bas, et les gars ont été une aide précieuse pour débugger.

  4. Thibaut BARTHALAY dit :

    Ok, je comprend.

    Merci en tout cas.

    Bonne journée.

  5. Thibaut BARTHALAY dit :

    Bizarement, je suis reparti d’une machine vierge en CentOS 7.0.

    J’ai suivi le tuto a la lettre, aucune erreur pendant la mise en place. Mais cela ne marche pas. Je suppose qu’il manques quelques infos dans le tuto… Bonne journée.

    Ps: dans mon message précedent, jetait parti d’une install existante, la je suis reparti de zéro.

  6. Thibaut BARTHALAY dit :

    Alala… ! Que ferai-je sans vous !!! Alors je rectifie :
    Votre tuto est génial 😉 Merci !!!

    Ce n’est pas la première fois que je m’aide de vos tuto et je suis toujours satisfais (ou je fini par l’être !).

    Maintenant reste plus qu’a trouver comment le relier a un Active Directory 🙂

    • kikinovak dit :

      Je suis content d’avoir pu vous rendre service. Remarque en passant : si mon souvenir est bon, SELinux causait des problèmes avec le démon ssl_crtd qui génère les certificats SSL à la volée. Un bug dans la politique par défaut de SELinux, et qui m’a causé des problèmes aussi. SELinux est un outil de sécurité très puissant, mais parfois on s’arrache un peu les cheveux avec. En revanche, je ne peux malheureusement pas vous aider pour l’Active Directory. La dernière fois que j’ai touché à Windows, c’était avant la sortie de Windows XP aux alentours de 2001. Nos postes de travail sont 100 % CentOS 7 aussi.

      Un gentil bonjour de la garrigue gardoise.

  7. Thibaut BARTHALAY dit :

    C’est plus clair pour moi, merci.

    Bonne continuation en tout cas !

  8. johann dit :

    bonjour et merci pour le tutoriel moi j’ai un souci j’utilise un ubuntu 14.04 lts et j veux faire du filtrage https mais je blocque au niveau de la recompilation de squid

  9. William E Brinkman dit :

    Merci pour l’excellent tutoriel. J’ai eu un problème à la fin et j’ai fourni une brève solution ci-dessous.

    (Le français n’est pas ma langue maternelle alors s’il vous plaît pardonner.)

    test squid
    # squid -k parse

    Fichiers: /var/log/cache.log et /var/log/access.log peuvent vous aider à résoudre les problèmes.

    L’essai initial s’est écrasé car il voulait une base de données de cert dans un endroit particulier.
    Créer un directorey # mkdir /var/lib/squid
    et changer de propriétaire
    # chown squid:squid /var/lib/squid

    Créez les fichiers en:
    #/usr/lib64/squid/ssl_crtd -c -s /var/lib/squid /ssl_db

    Changer la propriété des fichiers (# chown squid: squid file.names)

    # systemctl restart squid – devrait maintenant fonctionner!

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.