Partager une connexion avec iptables et route

Présentation de ce cours
Rubrique : Administration de GNU/Linux
Niveau : ***
Audience : Utilisateur moyen de GNU/Linux avec un noyau 2.4 ou supérieur.
Lectures préalables :
But : Expliquer comment mettre en place le partage d'une connexion Internet pour plusieurs machines GNU/Linux.

Généralités | (Haut de page) |

Partager une connexion permet de relier plusieurs machines à Internet (ou d'une manière plus générale à un autre réseau) au travers d'une seule machine (la passerelle). Toutes seront comme si elles avaient l'adresse IP de celle physiquement connectée à Internet. Ceci est un cas particulier de NAT, ou translation d'adresses, appelé dans Linux le Masquerading.

En quelques mots, lorsqu'une machine désirant envoyer un paquet sur Internet le transmettra à la passerelle, cette dernière remplacera l'adresse de l'émetteur réel par la sienne. Ensuite, elle envoie le paquet au destinataire en utilisant un port de son choix. Lorsque ce destinataire (un serveur web par exemple) renverra une réponse sur le port choisi, la passerelle saura à qui la transmettre sur le réseau interne. Elle fera donc alors une modification de l'adresse de destination. Ce mécanisme est invisible pour l'initiateur interne, du moment que l'on a spécifié la passerelle à utiliser.

Configurer la passerelle | (Haut de page) |

Il faut tout d'abord configurer la passerelle. Il s'agit donc de la machine qui est connectée à Internet et à travers laquelle les autres passent. Cela suppose que le réseau interne est déjà configuré. L'interface reliée à l'extérieur doit être identifiée. Dans le cas d'une connexion par modem, ce sera généralement ppp0. La commande suivante permet de la connaître :

> netstat -rn | grep UG | gawk '{print $8}'

Elle affichera le nom de l'interface. Le programme netstat permet de connaître diverses informations réseau (comme les connexions actives). Avec l'option -r, ce sont les tables de routage qui sont affichées. L'option -n permet d'éviter la résolution de noms et donc d'obtenir plus rapidement les informations. On recherche dans ce résultat l'indicateur U indiquant que la route est active, et le G qui désigne une passerelle. S'il y en a plusieurs, à vous de déterminer celle à utiliser.

Si votre adresse IP peut potentiellement changer à chaque connexion, comme par exemple lorsque l'on se connecte avec un modem par l'intermédiaire d'un fournisseur d'accès, la première commande à taper est la suivante :

> iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

Si votre adresse IP est statique, il vaut mieux utiliser celle-là :

> iptables -t nat -A POSTROUTING -o ppp0 -j SNAT --to-source xxx.xxx.xxx.xxx

En remplaçant xxx.xxx.xxx.xxx par l'adresse statique. Avant de voir les différences, décrivons ce qui est commun dans les deux cas.

On utilise tout d'abord la table nat de Netfilter qui est utilisée pour les translations d'adresses. On y récupère les paquets destinés à sortir (chaîne POSTROUTING) en passant par l'interface de notre choix (ici ppp0). Ensuite ce qui change est la cible vers laquelle envoyer les paquets pour traitement.

Dans le premier cas, il s'agit de MASQUERADE qui va réaliser le remplacement de l'adresse source comme expliqué précédemment. Pour le deuxième, c'est la même chose, si ce n'est que l'on spécifie cette adresse avec l'option --to-source. La cible SNAT signifie Source NAT ce qui correspond bien à un changement de l'adresse source.

La différence est dans le cas où la connexion vers l'extérieur serait interrompue. La cible MASQUERADE ne permettra pas de récupérer les communications qui étaient en cours. En revanche, avec SNAT, on saura que l'adresse d'origine n'a pas changée. Le noyau tentera alors de rétablir les connexions qui existaient auparavant.

Après qu'une de ces deux commandes ait été utilisée, il faut activer la redirection. Cela se fait à l'aide d'un élément spécial du pseudo-sytème de fichiers /proc :

> echo 1 > /proc/sys/net/ipv4/ip_forward

La suite de ces deux commandes peut être ajoutée dans un des fichiers lancés au démarrage car cela sera perdu après un arrêt de la machine. Certaines distributions utilisent par exemple /etc/rc.d/boot.local pour cela.

Configurer les machines internes | (Haut de page) |

Une fois cela réalisé, il faut configurer les machines sur le réseau interne pour leur dire d'utiliser la passerelle préalablement configurée. On utilise l'outil route qui permet de définir les tables de routages. La commande est la suivante :

> route add default gw 192.168.1.1

192.168.1.1 est un exemple pris au hasard (dans les classes d'adresses utilisées sur les réseaux internes) Cette valeur doit être remplacée par l'adresse IP par laquelle les ordinateurs voient la passerelle depuis le réseau interne. Là encore cette commande doit être exécutée à chaque démarrage.

Cela suppose que le réseau interne est bien configuré. Il faut que la passerelle soit accessible depuis ces machines.

Pour vérifier la table de routage, il suffit de lancer le programme route sans aucun paramètre. L'affichage devrait ressembler à ceci (seules les colonnes utiles sont indiquées ici) :

> route
Destination Passerelle  Genmask         Indic Iface
193.168.0.2 *           255.255.255.255 UH    eth0
192.168.0.0 *           255.255.255.0   U     eth0
default     192.168.0.1 0.0.0.0         UG    eth0

On suppose ici que l'adresse de la machine sur le réseau interne est 192.168.0.2 et possède une seule carte réseau Ethernet (eth0). La première ligne indique cela. L'indicateur H de la quatrième colonne permet de savoir qu'il s'agit d'une machine unique.

La ligne suivante est la route permettant d'atteindre la passerelle. Sur le réseau interne, l'accès se fait directement (pas de passerelle) par l'interface eth0.

Enfin la dernière ligne est la plus intéressante dans ce cas. Elle indique que pour toutes les autres adresses de destination, la route par défaut passe par la passerelle 192.168.0.1.

Permettre un serveur interne | (Haut de page) |

Tout cela permet d'initier des connexions uniquement depuis le réseau interne vers l'extérieur. Or, il se peut que l'on souhaite avoir un service proposé par une machine à l'intérieur. Par exemple admettons que la machine d'adresse 192.168.1.3 héberge un site web (port 80 par défaut) qui doivent être accessible. Toutes les demandes d'accès à ce site se feront sur la passerelle. C'est à elle ensuite de les transférer sur le serveur interne concerné. On utilise alors une translation d'adresse de destination, qui est l'opposé de ce qui a été exposé ci-dessus.

Voici dans ce cas-là la commande iptables à utiliser :

> iptables -t nat -p tcp -A PREROUTING -j DNAT --destination-port 80 --to-destination 192.168.1.3:80

On utilise à nouveau la table nat car il s'agit toujours d'une translation d'adresse. Mais cette translation est ici faite dès que le paquet pénètre la couche réseau (PREROUTING). Cela bien évidemment pour mettre la bonne adresse destination dès que possible afin que le routage s'effectue correctement.

La cible est DNAT (Destination NAT) qui est le pendant du SNAT. C'est elle qui permet de modifier l'adresse de destination des informations.

On trouve enfin les options nécessaires qui devront bien sûr être adaptées selon les besoins. Tout d'abord --destination-port qui est le port de connexion depuis l'extérieur. Il peut être totalement différent de celui sur la machine faisant office de serveur sur le réseau interne. L'adresse de ce serveur est indiquée avec l'option --to-destination prenant en paramètre l'adresse et éventuellement un numéro de port (après les : ). Si le port n'est pas précisé, c'est le même que celui indiqué par --destination-port qui sera utilisé. En fait, c'est tout simplement qu'il n'y aura pas de modification de cette valeur.

Il s'agit ici aussi d'un traitement invisible en dehors de la passerelle. Pour la personne qui demandera une page web, tout se passera comme si elle était fournie par la passerelle. A noter également que ce port ne doit bien évidemment pas être bloqué par des règles de pare-feu.