Lorsque vous désirez partager une connexion Internet à travers tout un réseau local, la solution courante qui s'offre à vous est le NAT. Le NAT ou Network Adress Translation permet de modifier "au vol" les paquets qui passent par la machine, faisant la liaison entre votre réseau et Internet.
De manière plus claire, la machine faisant du NAT reçoit les paquets et les modifie pour offrir un accès au Net. Ainsi, les machines de l'ensemble du réseau local peuvent partager une seule et même connexion. Il existe grossièrement deux sortes de NAT. Le Destination NAT permet de modifier l'adresse de destination des paquets réseaux. Ce type de NAT, appelé également DNAT, est la technologie mise en oeuvre pour certains types de proxies et le port forwarding. Ce type de NAT se fait avant le routage; nous verrons plus loin dans l'article que ceci est très important.
Le NAT qui nous intéresse ici est le SNAT (Source NAT). Dans ce cas précis, c'est l'adresse source des paquets réseau qui est modifiée. Ainsi, toutes les connexions qui sont faites depuis l'intérieur du réseau local semblent provenir de la même machine : la machine faisant le NAT. Le SNAT se fait après le routage. Il est courant d'entendre des erreurs dans la terminologie de ce genre de procédé. Un proxy transparent est une sorte de NAT mais le masquerading est également une sorte de NAT.
Le support SNAT n'est pas une apparition récente sous Linux. En effet, les kernels 2.0 étaient déjà capables de réaliser ce genre de chose (ipfwadm). Ce support a été optimisé avec la série 2.2 (ipchains) et, à présent que le kernel 2.4 a vu le jour, les capacités NAT du kernel sont devenues vraiment étonnantes. A l'instar du passage 2.0 à 2.2, de grands changements dans la configuration sur NAT ont fait leur apparition dans le kernel 2.4. Précisons que nous considérons dans cet article que vous avez déjà eu affaire à ipchains, ne serait-ce qu'en partie.
Netfilter, iptables et le masquerading.
Avec la série 2.2, c'est l'utilitaire ipchains qui permettait de configurer et d'administrer le masquerading. Ainsi, ajouter une règle dans la chaîne forward se faisait ainsi :
# ipchains -A forward -s 192.168.1.0/24 -d 0.0.0.0/0.0.0.0 -j MASQ
Ici, nous permettons à l'ensemble des machines du réseau 192.168.1.0 d'accéder aux serveurs situés sur Internet. Bien sûr, il ne faut pas oublier d'activer IP forwarding :
# echo 1 > /proc/sys/net/ipv4/ip_forward
C'est d'ailleurs la seule chose qui reste d'usage avec iptables. Bien sûr, il est possible de garder une compatibilité avec ipchains mais autant utiliser les nouvelles fonctionnalités en se débarrassant une fois pour toutes des vieilles habitudes. Avec iptables, les choses sont bien différentes et les possibilités sont bien supérieures à ce que faisait ipchains. Pour bien comprendre le fonctionnement d'iptables, vous devez tout simplement oublier tout ce que vous saviez d'ipchains. Vous ne devez plus considérer le NAT sous Linux comme autre chose que de l'altération de paquets réseaux. Vous comprendrez ainsi plus facilement les différentes options.
Les tables
Avec le nouveau kernel, il n'existe plus une seule table mais trois :
# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
On retrouve ici des termes déjà présents dans ipchains, mais ne vous y trompez pas, cela n'a pas grand chose à voir. Cette table contient trois chaînes. INPUT pour les paquets entrant sur la machine, FORWARD pour les paquets routés par la machine et enfin, OUTPUT pour les paquets générés par la machine.
# iptables -t nat -L Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
Ici, les chaînes sont différentes. PREROUTING concerne la modification des paquets dès qu'ils arrivent sur la machine, POSTROUTING, la modification des paquets qui sont sur le point de quitter la machine et finalement, OUTPUT, la modification des paquets générés localement et ce, avant le routage.
# iptables -t mangle -L Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
La chaîne PREROUTING permet de stocker les règles concernant les paquets avant le routage et OUTPUT les paquets générés localement et ce, avant routage.
Les cibles
Les cibles ou targets du vieux ipchains étaient bien peu nombreuses (ACCEPT, DENY, REJECT, MASQ, REDIRECT et RETURN). Avec iptables, tout ceci a été grandement étendu et réorganisé. Les cibles sont maintenant dépendantes des chaînes et des tables. Il est donc très important de connaître correctement leur signification et ce à quoi elles servent. Cible est peut-être un terme mal choisi puisqu'il est plus facile de les voir comme comportement à adopter vis-à-vis des paquets :
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 213.11.37.214
Cette ligne est équivalente à celle donnée en début d'article et utilisant ipchains. Tous les paquets en provenance du réseau local 192.168.1.0 verront leur adresse source modifiée en 213.11.37.214 avant de passer par l'interface eth1. Il est indéniable que cette ligne est beaucoup plus explicite que celle utilisant ipchains.
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 213.11.37.214:8080
Cette ligne permet de définir une règle de la chaîne PREROUTING pour la table nat ayant pour effet de changer l'adresse de destination des paquets arrivant via eth0 (port 80) en 213.11.37.214 (port 8080). Notez que cette modification étant faite AVANT le routage, l'ensemble du système verra uniquement un paquet à destination de 127.0.0.1 et rien d'autre.
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
Critères de sélection
Avant de choisir une cible ou, autrement dit, une modification à apporter aux paquets, il faut les sélectionner. Là encore, de nombreux nouveaux critères de sélection des paquets ont fait leur apparition. Ceux-ci sont présents sous la forme de modules. Il est possible de les spécifier explicitement avec l'option -m, mais la plupart sont chargés implicitement en fonction des choix de l'utilisateur. Les modules des critères de sélection (match, en anglais) sont les suivants :
# iptables -m limit -t nat -A POSTROUTING -s 192.168.12.1 -o eth0 --limit 200/sec -j SNAT --to 192.168.0.10 # iptables -t nat -L -n Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination SNAT all -- 192.168.12.1 0.0.0.0/0 limit: avg 200/sec burst 5 to:192.168.0.10 Chain OUTPUT (policy ACCEPT) target prot opt source destination
Nous ajoutons ici une règle dans la chaîne POSTROUTING de la table nat. Celle-ci définit que les paquets en provenance de l'interface ayant pour adresse 192.168.12.1 seront "SNATés" en 192.168.0.10. Cette modification sera faite tant que le critère de 43 paquets par seconde ne sera pas dépassé. Il est donc possible de contrôler le taux de connexion de chaque utilisateur du réseau local. Notez que nous avons été obligés de spécifier l'utilisation du module avec l'option -m limit.
--uid-owner permettant de spécifier l'UID de l'utilisateur qui a créé le paquet.
--gid-owner idem pour le GID.
--pid-owner permettant de spécifier l'ID du processus qui a créé le paquet.
--sid-owner permettant de spécifier l'ID de session du processus qui a créé le paquet.
INVALID pour un paquet n'appartenant à aucune connexion.
ESTABLISHED pour un paquet appartenant à une connexion pour laquelle des paquets ont déjà été envoyés dans les deux directions (E/S).
NEW pour un paquet qui débute une nouvelle connexion.
RELATED pour un paquet qui débute lui aussi une nouvelle connexion mais cette dernière est en relation avec une connexion existante.
16 Minimize-Delay
8 Maximize-Throughput
4 Maximize-Reliability
2 Minimize-Cost
0 Normal-Service
Il est possible d'obtenir une aide concernant ces modules avec la commande iptables -m module -h où module est le nom d'un module valide. Sachez également qu'un certain nombre de critères acceptent un caractère préfixe ! signifiant la négation. Nous avons remarqué que bien qu'étant documentée, cette négation n'est pas valide pour le module limit (iptables v1.2)
Il existe également un certain nombre de modules supplémentaires ne faisant pas encore partie de la distribution officielle d'iptables. Nous ne les documenterons donc pas ici. Reportez-vous directement à la page de manuel d'iptables pour plus d'information.
Le kernel
Comme avec ipchains, il est indispensable d'activer les fonctionnalités de filtrage de paquets réseau ("Network packet filtering (replace ipchains)". Nous vous conseillons de compiler tout cela sous la forme de modules plutôt que de manière statique. Un kernel modulaire au possible est toujours un excellent choix :
<M> Connection tracking (required for masq/NAT) <M> FTP protocol support <> Userspace queueing via NETLINK (EXPERIMENTAL) <M> IP tables support (required for filtering/masq/NAT) <M> limit match support <M> MAC address match support <M> netfilter MARK match support <M> Multiple port match support <M> TOS match support <M> Connection state match support <M> Unclean match support (EXPERIMENTAL) <M> Owner match support (EXPERIMENTAL) <M> Packet filtering <M> REJECT target support <> MIRROR target support (EXPERIMENTAL) <M> Full NAT <M> MASQUERADE target support <M> REDIRECT target support <M> Packet mangling <M> TOS target support <M> MARK target support <M> LOG target support <> ipchains (2.2-style) support <> ipfwadm (2.0-style) support
Vous obtiendrez alors des modules classés dans /lib/modules/2.4.0/kernel/net/ipv4/netfilter par un make modules_install :
ip_conntrack.o ip_conntrack_ftp.o ip_nat_ftp.o ip_tables.o ipt_LOG.o ipt_MARK.o ipt_MASQUERADE.o ipt_REDIRECT.o ipt_REJECT.o ipt_TOS.o ipt_limit.o ipt_mac.o ipt_mark.o ipt_multiport.o ipt_owner.o ipt_state.o ipt_tos.o ipt_unclean.o iptable_filter.o iptable_mangle.o iptable_nat.o
Un simple modprobe ip_tables devrait ensuite vous permettre d'accéder à l'ensemble des fonctionnalités disponibles. Les modules nécessaires seront automatiquement chargés en fonction de l'usage que vous en ferez de la commande iptables.
Notez qu'une compatibilité avec ipchains OU ipfwadm est proposée comme fonctionnalité dans le kernel. Je vous invite plutôt à prendre quelques heures en pleine nuit (comme moi) pour bien comprendre iptables. Ceci vous sera davantage profitable. Nous avons grandement documenté ces nouvelles fonctionnalités, mais il est indéniable que seuls des essais et une bonne dose de pratique vous rendront à l'aise dans ce domaine. N'hésitez donc pas à faire des essais entre deux machines ou à travers une connexion PPP/null-modem.
Les fonctionnalités présentes dans le kernel 2.4 en terme de filtrage et de NAT ont de quoi tansformer un simple 486DX en un matériel spécialisé haut de gamme. Il est très courant de surestimer le coût CPU de telles fonctionnalités. Chapeau bas messieurs Marc Boucher, James Morris, Harald Welte et Rusty Russell. Voilà un travail d'orfèvre qu'il convient de saluer à sa juste valeur... Merci.
Liens
* Tout sur le NAT et iptables en plusieurs langues
* Archive iptables
* FAQ netfilter / iptables