6. Mandataire transparent pour une machine distante

Maintenant, une question se pose naturellement, si l'on peut réaliser toutes ces astucieuses manœuvres pour rediriger les connexions HTTP vers des ports locaux, ne pourrait-on pas faire la même chose mais vers une machine distante (par exemple, dans le cas où la machine qui exécute Squid n'est pas la même que celle qui fait tourner iptables). La réponse est oui, mais cela demandes des mots magiques un peu différents. Si vous souhaitez uniquement une redirection vers la machine locale, ce qui est la cas habituel, vous pouvez ignorer ce chapitre.

Pour les besoins de l'exemple, supposons que nous ayons deux machines nommées machine-squid et machine-iptables, et qu'elles soient sur le réseau réseau-local. Dans les commandes ci-dessous, remplacez ces chaînes par les adresses ou les noms réels de vos réseau et machines.

Je présenterai ici deux approches différentes.

  • Sur laquelle tournera Squid, machine-squid, vous n'avez ni besoin d'iptables, ni d'indiquer au noyau une option spécifique. La seule chose nécessaire est Squid. Vous aurez en revanche besoin[1] d'indiquer à Squid l'option http_accel telle qu'elle est décrite ci-dessus.

  • Sur la machine sur laquelle tournera iptables, machine-iptables, vous devrez configurer le noyau comme décrit dans Section 3 ci-dessus, à une exception près : vous n'avez pas besoin de l'option « REDIRECT target support ». Pour ce qui est des commandes iptables, vous aurez besoin de trois d'entre elles :

    iptables -t nat -A PREROUTING -i eth0 -s !machine-squid \
             -p tcp --dport 80 -j DNAT --to machine-squid:3128
    
    iptables -t nat -A POSTROUTING -o eth0 -s réseau-local \
             -d machine-squid -j SNAT --to machine-iptables
    
    iptables -A FORWARD -i eth0 -o eth0 -s réseau-local \
             -d machine-squid -p tcp --dport 3128 -j ACCEPT
    

    La première envoie les paquets de machine-iptables vers machine-squid. La seconde s'assure que la réponse soit renvoyée via machine-iptables, plutôt que directement au client (c'est très important !). La dernière s'assure que machine-iptables redirigera les paquets appropriés vers machine-squid. Il est possible qu'elle ne soit pas nécessaire. À vous de voir. Remarquez que nous avons spécifié -i eth0 puis -o eth0, ce qui veut dire que nous utilisons eth0 comme interface d'entrée (-i) et de sortie (-o). Si vos paquets entrent et sortent par des interfaces différentes, vous devrez ajuster ces commandes en conséquence.

Ajoutez ces commandes aux scripts de démarrage appropriés sous /etc/rc.d/

(Merci à Giles Coochey d'avoir aidé à l'écriture de cette section).

Notre première tentative marche bien, mais a un petit inconvénient : elle ne permet pas de gérer correctement les connexions HTTP/1.0 sans en-tête Host. Les connexions partiellement ou complètement compatibles HTTP/1.1, elles, marchent bien. En général, cela ne pose pas de problème, car la majorité des navigateurs modernes envoient l'en-tête Host. Cela pose problème dans le cas de certains petits programmes ou appareils embarqués, car ceux-ci n'émettent que des requêtes HTTP/1.0 très simples. Pour être capable de gérer correctement ce cas de figure, il faut en faire un peu plus.

Comme précédemment, ajoutez toutes ces commandes aux scripts de démarrage appropriés.

Voici une explication succincte de la façon dont cette seconde méthode fonctionne : dans la première méthode, nous avons utilisé la traduction d'adresse pour diriger les paquets vers l'autre machine. Ce qui implique une modification des paquets. Cette altération est la cause des défaillances mentionnés plus haut pour certains types de clients. Dans la méthode deux, nous utilisons un truc magique appelé routage dirigé (policy routing). Il faut tout d'abord sélectionner les paquets que l'on veut. Pour ce faire, nous marquons (via la cible MARK) tous les paquets destinés au port 80, excepté ceux provenant de machine-squid elle-même. Habituellement, lorsque le noyau doit décider du routage des paquets, il utilise la table de routage consultable via la commande route. Pour le routage des paquets marqués, il utilisera une table spéciale ne comportant qu'une seule entrée, une passerelle par défaut pointant vers machine-squid. Les paquets visés seront donc joyeusement envoyés vers leur destin, sans subir aucune modification. Ce qui permettra de gérer correctement toutes les connexions, y compris les connexions HTTP/1.0. (Merci à Michal Svoboda d'avoir suggéré cette section et aidé à sa rédaction).