Proxy transparent : SSL Bump, ICAP et antivirus ClamAV

Cet article documente l architecture du service proxy transparent du homelab : le routage PBR, l interception HTTPS via SSL Bump, et la chaine d inspection antivirus ICAP.

Architecture du flux

flowchart LR
    subgraph iot["VLAN IoT"]
        device["Appareil IoT"]
    end
    subgraph vyos["VyOS"]
        pbr["PBR table 100"]
        nft["nft REDIRECT<br/>dans netns Squid"]
    end
    subgraph proxy["Container Squid"]
        squid["Squid<br/>peek+splice"]
    end
    subgraph icap["Container c-icap"]
        cicap["c-icap<br/>REQMOD"]
    end
    subgraph av["Container ClamAV"]
        clam["clamd<br/>scan"]
    end
    device --> pbr
    pbr --> nft
    nft -->|"80 vers 3129<br/>443 vers 3131"| squid
    squid -->|"ICAP"| cicap
    cicap -->|"clamd protocol"| clam
    clam -->|"clean"| cicap
    cicap -->|"OK"| squid
    squid --> dest["Destination"]

Policy-Based Routing (PBR)

Le VLAN IoT utilise le PBR avec la table de routage 100 pour rediriger le trafic HTTP/HTTPS vers le container Squid. Les paquets sont marques par des regles nftables et routes vers le bridge reseau du container.

Injection nft REDIRECT

Un service systemd squid-redirect.service (BindsTo le container Squid) injecte des regles nft REDIRECT dans le namespace reseau du container :

  • Port 80 redirige vers 3129 (HTTP intercept)
  • Port 443 redirige vers 3131 (HTTPS intercept, peek+splice)

Squid utilise SO_ORIGINAL_DST pour retrouver la destination d origine.

SSL Bump : peek+splice

Sur le port 3131, Squid fait du peek+splice sur les connexions HTTPS :

  • peek : lit le SNI (Server Name Indication) du ClientHello TLS sans dechiffrer
  • splice : passe le trafic en tunnel TLS sans inspection du contenu

Cette approche permet de logger les domaines HTTPS visites sans casser le chiffrement TLS. Le scan antivirus ICAP s applique uniquement sur les requetes HTTP claires.

Chaine ICAP : c-icap et ClamAV

c-icap sert de pont entre Squid et ClamAV :

  • Squid envoie les requetes HTTP en REQMOD via le protocole ICAP
  • c-icap extrait le corps de la requete et le soumet a clamd
  • ClamAV scanne le contenu en temps reel
  • Si le contenu est clean, c-icap retourne 200 OK a Squid
  • Si le contenu est infecte, c-icap retourne une page de blocage

Demarrage coordonne

c-icap attend que clamd soit accessible (TCP connect, 120 tentatives x 1 seconde) avant de demarrer. Sans cette attente, les requetes ICAP echoueraient.

Coherence DNS

Squid et les clients DOIVENT resoudre via le meme cache DNS (BIND9). Deux caches differents donnent des IPs CDN differentes, ce qui cause des echecs de host_verify_strict dans Squid.

C est pourquoi la regle DNAT 534 intercepte aussi le DNS du container Squid et le redirige vers BIND9.

Deux modes de proxy

Mode Port Clients Methode
Explicit 3128 LXC, KVM, serveurs Variable d env http_proxy
Transparent 3130 IoT, VLAN4 PBR + nft REDIRECT

Configuration 4 ports

Squid ecoute sur 4 ports distincts avec des roles differents :

Port Mode Trafic
3128 Explicit HTTP proxy classique (LXC, KVM, serveurs)
3129 Intercept HTTP Trafic IoT redirige (nft REDIRECT depuis port 80)
3130 Explicit HTTPS Proxy HTTPS pour les clients configures
3131 Intercept HTTPS Trafic IoT SSL Bump peek+splice (nft REDIRECT depuis port 443)

Le logformat inclut le port d ecoute (%>lp) pour distinguer les flux dans Graylog.

host_verify_strict et CDN

host_verify_strict est desactive (off). Sans ca, Squid bloque les requetes vers les CDN (ghcr.io, Google, Akamai) car les IPs resolues par Squid et le client different (round-robin DNS).

Symptome typique : Docker Hub pulls depuis Home Assistant echouent avec une erreur http: server gave HTTP response to HTTPS client -- Squid renvoie une page d erreur HTTP 409 (Host header forgery) sur la connexion TLS.

client_dst_passthru on est egalement requis pour utiliser l IP destination originale via SO_ORIGINAL_DST (PBR + TPROXY).

Splice rules specifiques

Certains appareils IoT necessitent un splice complet (pas de peek) :

  • Home Assistant : tout le trafic HA est splice sans inspection
  • Samsung SmartThings : idem, les appareils Samsung ne tolerent pas le peek

Service squid-redirect : le coeur du transparent proxy

Le service squid-redirect.service est le composant critique qui rend le proxy transparent possible. Sans lui, le trafic PBR arrive dans le netns du container Squid mais rien n ecoute sur les ports 80/443 -- drop silencieux.

Fonctionnement

flowchart TB
    subgraph boot["Sequence de demarrage"]
        container["vyos-container-squid.service<br/>Podman demarre le container"]
        sleep["ExecStartPre sleep 3s<br/>Attendre le netns"]
        inject["nsenter dans le netns Squid<br/>nft add rule REDIRECT"]
    end
    container --> sleep --> inject
    inject --> r80["port 80 --> 3129"]
    inject --> r443["port 443 --> 3131"]

Le service :

  • Est lie au container via BindsTo=vyos-container-squid.service
  • Attend 3 secondes que le netns soit pret
  • Utilise nsenter -t PID -n pour entrer dans le namespace reseau du container
  • Injecte une table nft nat avec 2 regles REDIRECT (80 vers 3129, 443 vers 3131)
  • Se nettoie proprement au stop (nft flush ruleset dans le netns)

Boot race condition

Probleme : les unit files custom vivent dans /config/etc/services/ et sont symlinkes vers /etc/systemd/system/. Au boot, systemd tente de les charger AVANT que /config soit monte → symlink dangling → service inactive (dead) → pas de REDIRECT → tous les IoT perdent HTTPS silencieusement.

Fix : deux mecanismes complementaires :

  • RequiresMountsFor=/config dans le unit file
  • Le vyos-postconfig-bootup.script boucle sur /config/etc/services/*.service, cree les symlinks, fait daemon-reload, et enable + start chaque service apres le boot

Monitoring avec Uptime Kuma

Un timer systemd (60s) execute un script de verification :

  • Verifie que squid-redirect.service est actif
  • Verifie que le container Squid existe (PID)
  • Verifie que les regles nft REDIRECT sont presentes dans le netns
  • Push le resultat vers Uptime Kuma via podman exec (bypass le firewall output)

Si une des verifications echoue, le monitor Kuma passe en DOWN et une alerte est envoyee. Detection de la panne en moins de 2 minutes.

Postconfig bootup

Le script vyos-postconfig-bootup.script gere aussi :

  • La route PBR `ip route add default via table 100`
  • Le bypass Netavark masquerade pour le trafic PBR (sinon le mark PBR trigger la regle HOSTPORT-MASQ)
  • La verification de presence des certificats SSL Bump et HAProxy

Monitoring

L ACL localnet de Squid inclut le reseau Uptime Kuma pour les probes HTTP. Sans ca, les probes TCP generent des erreurs transaction-end-before-headers dans les logs.


Liens

Articles connexes


Commentaires

Laisser un commentaire

Votre adresse e-mail 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 la façon dont les données de vos commentaires sont traitées.