<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>6. Mandataire transparent pour une machine distante</title> <link rel="stylesheet" href="style.css" type="text/css"> <meta name="generator" content="DocBook XSL Stylesheets V1.64.1"> <link rel="home" href="index.html" title=" Petit guide de mise en place d'un mandataire transparent avec Linux et Squid "> <link rel="up" href="index.html" title=" Petit guide de mise en place d'un mandataire transparent avec Linux et Squid "> <link rel="previous" href="ar01s05.html" title="5. Installer iptables (Netfilter)"> <link rel="next" href="ar01s07.html" title="7. Mandataire transparent configuré sur un pont réseau"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <div class="navheader"> <table width="100%" summary="Navigation header"> <tr><th colspan="3" align="center">6. Mandataire transparent pour une machine distante</th></tr> <tr> <td width="20%" align="left"> <a accesskey="p" href="ar01s05.html">Précédent</a> </td> <th width="60%" align="center"> </th> <td width="20%" align="right"> <a accesskey="n" href="ar01s07.html">Suivant</a> </td> </tr> </table> <hr> </div> <div class="sect1" lang="fr"> <div class="titlepage"> <div><div><h2 class="title" style="clear: both"> <a name="machine-distante"></a>6. Mandataire transparent pour une machine distante</h2></div></div> <div></div> </div> <p> 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 <span><b class="command">iptables</b></span>). 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. </p> <p> Pour les besoins de l'exemple, supposons que nous ayons deux machines nommées <i class="replaceable"><tt>machine-squid</tt></i> et <i class="replaceable"><tt>machine-iptables</tt></i>, et qu'elles soient sur le réseau <i class="replaceable"><tt>réseau-local</tt></i>. Dans les commandes ci-dessous, remplacez ces chaînes par les adresses ou les noms réels de vos réseau et machines. </p> <p> Je présenterai ici deux approches différentes. </p> <div class="sect2" lang="fr"> <div class="titlepage"> <div><div><h3 class="title"> <a name="methode-simple"></a>6.1. Première méthode (plus simple, mais non exhaustive) </h3></div></div> <div></div> </div> <div class="itemizedlist"><ul type="disc"> <li><p> Sur laquelle tournera Squid, <i class="replaceable"><tt>machine-squid</tt></i>, 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 <span class="emphasis"><em>besoin</em></span><sup>[<a name="id2512751" href="#ftn.id2512751">1</a>]</sup> d'indiquer à Squid l'option <tt class="literal">http_accel</tt> telle qu'elle est décrite ci-dessus. </p></li> <li> <p> Sur la machine sur laquelle tournera iptables, <i class="replaceable"><tt>machine-iptables</tt></i>, vous devrez configurer le noyau comme décrit dans <a href="ar01s03.html" title="3. Configurer le noyau">Section 3, « Configurer le noyau »</a> 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 : </p> <pre class="programlisting"> iptables -t nat -A PREROUTING -i eth0 -s !<i class="replaceable"><tt>machine-squid</tt></i> \ -p tcp --dport 80 -j DNAT --to <i class="replaceable"><tt>machine-squid</tt></i>:3128 iptables -t nat -A POSTROUTING -o eth0 -s <i class="replaceable"><tt>réseau-local</tt></i> \ -d <i class="replaceable"><tt>machine-squid</tt></i> -j SNAT --to <i class="replaceable"><tt>machine-iptables</tt></i> iptables -A FORWARD -i eth0 -o eth0 -s <i class="replaceable"><tt>réseau-local</tt></i> \ -d <i class="replaceable"><tt>machine-squid</tt></i> -p tcp --dport 3128 -j ACCEPT </pre> <p> La première envoie les paquets de <i class="replaceable"><tt>machine-iptables</tt></i> vers <i class="replaceable"><tt>machine-squid</tt></i>. La seconde s'assure que la réponse soit renvoyée via <i class="replaceable"><tt>machine-iptables</tt></i>, plutôt que directement au client (c'est très important !). La dernière s'assure que <i class="replaceable"><tt>machine-iptables</tt></i> redirigera les paquets appropriés vers <i class="replaceable"><tt>machine-squid</tt></i>. Il est possible qu'elle ne soit pas nécessaire. À vous de voir. Remarquez que nous avons spécifié <tt class="option">-i eth0</tt> puis <tt class="option">-o eth0</tt>, ce qui veut dire que nous utilisons <tt class="literal">eth0</tt> comme interface d'entrée (<tt class="option">-i</tt>) et de sortie (<tt class="option">-o</tt>). Si vos paquets entrent et sortent par des interfaces différentes, vous devrez ajuster ces commandes en conséquence. </p> </li> </ul></div> <p> Ajoutez ces commandes aux scripts de démarrage appropriés sous <tt class="filename">/etc/rc.d/</tt> </p> <p> (Merci à Giles Coochey d'avoir aidé à l'écriture de cette section). </p> </div> <div class="sect2" lang="fr"> <div class="titlepage"> <div><div><h3 class="title"> <a name="methode-compliquee"></a>6.2. Seconde méthode (plus compliquée mais plus générale) </h3></div></div> <div></div> </div> <p> 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 <tt class="literal">Host</tt>. 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 <tt class="literal">Host</tt>. 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. </p> <div class="itemizedlist"><ul type="disc"> <li> <p> Sur <i class="replaceable"><tt>machine-iptables</tt></i>, il est nécessaire d'activer les options suivantes du noyau : </p> <pre class="programlisting"> IP: advanced router IP: policy routing IP: use netfilter MARK value as routing key IP: Netfilter Configuration -> Packet mangling IP: Netfilter Configuration -> MARK target support </pre> <p> Vous aurez également besoin des utilitaires iproute2. Votre distribution les a probablement déjà installés mais, dans le cas contraire, jetez un coup d'œil à <a href="ftp://ftp.inr.ac.ru/ip-routing/" target="_top">ftp://ftp.inr.ac.ru/ip-routing/</a> </p> <p> La configuration de la machine nécessitera les commandes suivantes : </p> <pre class="programlisting"> iptables -t mangle -A PREROUTING -j ACCEPT -p tcp --dport 80 -s <i class="replaceable"><tt>machine-squid</tt></i> iptables -t mangle -A PREROUTING -j MARK --set-mark 3 -p tcp --dport 80 ip rule add fwmark 3 table 2 ip route add default via <i class="replaceable"><tt>squid-box</tt></i> dev eth1 table 2 </pre> <p> Notez que les numéros choisis pour la marque de pare-feu (<tt class="literal">3</tt>) et pour la table de routage (<tt class="literal">2</tt>) sont complètement arbitraires. Si vous utilisez déjà un routage dirigé (<span class="foreignphrase"><i class="foreignphrase">policy routing</i></span>) ou un marquage de pare-feu pour d'autres besoins, assurez-vous que vous choisissez ici des numéros non utilisés. </p> </li> <li> <p> Passons à <i class="replaceable"><tt>machine-squid</tt></i>. Utilisez la commande suivante, qui devrait vous sembler remarquablement similaire à une commande vue précédemment. </p> <pre class="programlisting"> iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128 </pre> </li> </ul></div> <p> Comme précédemment, ajoutez toutes ces commandes aux scripts de démarrage appropriés. </p> <p> 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é (<span class="foreignphrase"><i class="foreignphrase">policy routing</i></span>). Il faut tout d'abord sélectionner les paquets que l'on veut. Pour ce faire, nous marquons (via la cible <tt class="literal">MARK</tt>) tous les paquets destinés au port <tt class="literal">80</tt>, excepté ceux provenant de <i class="replaceable"><tt>machine-squid</tt></i> elle-même. Habituellement, lorsque le noyau doit décider du routage des paquets, il utilise la table de routage consultable via la commande <span><b class="command">route</b></span>. 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 <i class="replaceable"><tt>machine-squid</tt></i>. 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). </p> </div> <div class="sect2" lang="fr"> <div class="titlepage"> <div><div><h3 class="title"> <a name="ip-dynamique"></a>6.3. Première méthode… Et dans le cas où la machine iptables a une adresse IP dynamique ? </h3></div></div> <div></div> </div> <p> Si <i class="replaceable"><tt>machine-iptables</tt></i> a une adresse IP dynamique (par exemple dans le cas d'une connexion ppp téléphonique ou d'une adresse assignée par DHCP sur un modem-câble), vous devrez alors apporter une légère modification aux commandes ci-dessus. Remplacez la seconde commande par celle-ci : </p> <pre class="programlisting"> iptable -t nat -A POSTROUTING -o eth0 -s <i class="replaceable"><tt>réseau-local</tt></i> \ -d <i class="replaceable"><tt>machine-squid</tt></i> -j MASQUERADE </pre> <p> Cette modification évite d'avoir à spécifier l'adresse IP de <i class="replaceable"><tt>machine-iptables</tt></i> dans la commande. Dans la mesure où celle-ci change souvent, vous devriez modifier la commande à chaque fois. Cette modification vous épargnera donc beaucoup de travail. </p> </div> <div class="footnotes"> <br><hr width="100" align="left"> <div class="footnote"><p><sup>[<a name="ftn.id2512751" href="#id2512751">1</a>] </sup>Les versions précédentes de ce petit guide suggéraient que tel n'était pas le cas. C'était une erreur. Désolé d'avoir créé cette confusion.</p></div> </div> </div> <div class="navfooter"> <hr> <table width="100%" summary="Navigation footer"> <tr> <td width="40%" align="left"> <a accesskey="p" href="ar01s05.html">Précédent</a> </td> <td width="20%" align="center"><a accesskey="u" href="index.html">Niveau supérieur</a></td> <td width="40%" align="right"> <a accesskey="n" href="ar01s07.html">Suivant</a> </td> </tr> <tr> <td width="40%" align="left" valign="top">5. Installer iptables (Netfilter) </td> <td width="20%" align="center"><a accesskey="h" href="index.html">Sommaire</a></td> <td width="40%" align="right" valign="top"> 7. Mandataire transparent configuré sur un pont réseau</td> </tr> </table> </div> </body> </html>