Squid et les exceptions pour les sites problématiques

AvertissementIl y a quelques jours, j’ai mis en place un serveur proxy cache transparent dans mon entreprise. Dans la configuration actuelle, Squid gère les connexions HTTP aussi bien que les connexions HTTPS. Le but de l’opération, c’est de tester la journalisation et l’analyse du trafic web d’un réseau local avant d’installer ça chez les clients, selon la célèbre devise “eat your own dog food“.

Au bout de quelques jours, j’ai pas mal peaufiné la configuration, et je dois dire que la combinaison Squid + SquidAnalyzer est rudement efficace pour savoir en quelques clics qui fait quoi sur le web, quels sont les sites les plus populaires, qui télécharge le plus, etc.

Les sites qui posent problème

Dans l’ensemble, ça fonctionne plutôt bien pour l’écrasante majorité des sites visités. L’article du jour traite donc de la poignée de sites restants qui peuvent poser problème. Ce ne sont pas forcément des sites web d’ailleurs, mais tout ce qui nécessite une connexion sur le port 443. Comme la synchronisation d’un dépôt Github, par exemple.

# git pull
fatal: unable to access 'https://github.com/kikinovak/depot/': 
Peer's certificate issuer has been marked as 
not trusted by the user.

De manière similaire, Thunderbird proteste au démarrage lorsqu’il essaie de synchroniser le carnet d’adresses avec OwnCloud.

Squid HTTPS

L’approche pragmatique

Évidemment, on pourrait très bien ajouter notre certificat fait maison dans git et dans Thunderbird, mais ne perdons pas de vue le fait que nous cherchons uniquement à mettre en place une solution de journalisation du trafic web, et que cette façon de procéder nous ferait sauter à travers des cerceaux en feu pour pas grand-chose. La solution pragmatique consiste ici à créer des exceptions pour tous ces domaines qui posent problème, de manière à ce qu’ils contournent le serveur proxy.

J’ai essayé dans un premier temps de le faire au niveau de la configuration du proxy, mais je me suis rendu compte au bout d’une matinée ensoleillée de tentatives et d’échecs qu’une fois que le trafic arrivait au niveau de Squid il devait nécessairement être traité. Le problème se situait donc en amont.

Note 12 mars 2018 :  contrairement à ce que je viens de dire, le problème peut très bien être résolu au niveau de la configuration de Squid, comme c’est décrit un peu plus loin.

Définir les exceptions au niveau du pare-feu

Pour contourner le proxy il faut tout simplement éviter de lui faire passer les paquets TCP en premier lieu. Et pour ce faire, il faut attaquer le problème au niveau du pare-feu. Dans la configuration par défaut – c’est-à-dire où tout le trafic web est redirigé vers Squid, sans exceptions – il ressemble à ceci.

# 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

On pourrait être tenté d’ajouter une exception dans la ligne qui gère la redirection des paquets à destination du port 443, comme ceci. Notez au passage qu’on a simplement remplacé ! -d $SERVER_IP par ! -d microlinux.fr, vous verrez pourquoi.

$IPT -A PREROUTING -t nat -i $IFACE_LAN -p tcp ! -d microlinux.fr \
 --dport 443 -j REDIRECT --to-port 3129

Le problème se pose dès que l’on utilise un domaine qui pointe vers plusieurs adresses IP, comme github.com, par exemple.

$IPT -A PREROUTING -t nat -i $IFACE_LAN -p tcp ! -d github.com \
 --dport 443 -j REDIRECT --to-port 3129

Dans ce cas, on se retrouve confronté à l’erreur suivante.

iptables v1.4.21: ! not allowed with multiple source or 
destination IP addresses

La solution consiste ici d’accepter le domaine en amont de la règle de redirection.

# Exception
$IPT -A PREROUTING -t nat -i $IFACE_LAN -d github.com -j ACCEPT

# 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

Et pour finir, on va écrire une boucle qui lit les domaines – ou les adresses IP – dans un fichier no-proxy.txt. Cette boucle devra donc être insérée dans le script de pare-feu avant les redirections vers le proxy.

# Exceptions
EXCEPTIONS=$(egrep -v '(^\#)|(^\s+$)' /usr/local/sbin/no-proxy.txt)
for EXCEPTION in $EXCEPTIONS; do
  $IPT -A PREROUTING -t nat -i $IFACE_LAN -d $EXCEPTION -j ACCEPT
done

Et voici à quoi ressemble mon fichier no-proxy.txt pour l’instant.

# Ne pas utiliser le proxy pour les domaines suivants
#
# Crédit Coopératif
www.credit-cooperatif.coop
# Github
github.com
# Microlinux
cloud.microlinux.fr
cloud.microlinux.eu
# Squid
squid-cache.org
# Thunderbird
start.thunderbird.net

À partir de là, il suffit d’ajouter les domaines – ou les adresses IP – problématiques au fichier no-proxy.txt et de relancer le script de pare-feu, et le tour est joué.

Définir les exceptions au niveau de Squid

Le lendemain de la publication des lignes ci-dessus, j’ai reçu un mail de Yuri Voinov, qui est inscrit comme moi à la mailing list de Squid, et qui m’a fourni une solution simple, élégante et fonctionnelle pour définir des exceptions au niveau de la configuration de Squid. Je tiens à le remercier ici.

Dans le fichier /etc/squid/squid.conf, éditer les règles SSL comme ceci.

# Règles SSL
acl DiscoverSNIHost at_step SslBump1
acl NoSSLIntercept ssl::server_name_regex "/etc/squid/no-proxy.txt"
ssl_bump peek DiscoverSNIHost
ssl_bump splice NoSSLIntercept
ssl_bump bump all

Les URLs à exclure du traitement figurent dans le fichier /etc/squid/no-proxy.txt. Pour la syntaxe, on utilisera les expressions régulières POSIX classiques.

# Teamviewer
(master|ping)[0-9][0-9]?\.teamviewer\.com
# Squid
.squid\-cache\.org
# Github
github\.com
# Microlinux
cloud\.microlinux\.eu
# Thunderbird
start\.thunderbird\.net
live\.mozillamessaging\.com

Cette solution présente une série d’avantages techniques, notamment le fait que les sites définis comme exception apparaissent quand-même dans les logs de Squid. On la préférera donc au traitement en amont dans le pare-feu.

Ce contenu a été publié dans CentOS, Documentation Microlinux, avec comme mot(s)-clé(s) , . Vous pouvez le mettre en favoris avec ce permalien.

4 réponses à Squid et les exceptions pour les sites problématiques

  1. walter dit :

    Bonjour,
    tu inspectes le trafic HTTPS, tu utilises donc une CA perso. Dans la documentation du proxy HTTPS, tu ajoutes le certificat dans le navigateur, mais pas dans git, ni dans Thunderbird. As tu essayer de le faire ? ça devrait résoudre le problème, sans contourner le proxy.

    https://stackoverflow.com/questions/9072376/configure-git-to-accept-a-particular-self-signed-server-certificate-for-a-partic

    • kikinovak dit :

      Je sais bien (mais merci de me le rappeler quand-même). Vu qu’on me demande juste de faire un monitoring du trafic web, c’est plus simple de contourner le proxy pour ces quelques domaines problématiques plutôt que de sauter à travers des cerceaux en feu et obliger tout le monde dans le réseau local à importer un certificat fait maison.

      Ceci étant dit, je viens d’avoir un tuyau d’enfer sur la mailing list de Squid, qui risque fort de 1. me simplifier grandement la vie et 2. rendre cet article obsolète.

      Un gentil bonjour de la garrigue gardoise.

  2. 9acca9 dit :

    Hi.
    This config for what version of squid it is??
    # Règles SSL
    acl DiscoverSNIHost at_step SslBump1
    acl NoSSLIntercept ssl::server_name_regex “/etc/squid/no-proxy.txt”
    ssl_bump peek DiscoverSNIHost
    ssl_bump splice NoSSLIntercept
    ssl_bump bump all

    (i dont speak english).

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.