Iptables physdev

Bonjour à tous,

J’ai juste une petite question par rapport à iptables et physdev.

Je m’y intéresse car je me suis retrouvé coincé au moment où j’ai eu besoin de “forwarder” les packets de plusieurs interfaces.
Voici la règle que j’utilisais avant, qui fonctionne très bien pour une seule interface :

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 21 -j DNAT --to-destination 10.0.0.1

Dès que je rajoute une règle du même genre pour une autre interface, seule la première est reconnue :

iptables -t nat -A PREROUTING -i eth2 -p tcp --dport 21 -j DNAT --to-destination 10.0.0.2

C’est un peu comme si il ne prenait pas en compte le paramètre -i.

En ayant parcouru le net, j’ai vu qu’il ne fallait plus utiliser le paramètre -i pour spécifier une interface depuis le kernel 2.6 mais plutôt le module physdev.

J’ai donc transformé cette règle en :

iptables -t nat -A PREROUTING --dport 21 -m physdev --physdev-in eth2 -j DNAT --to-destination 10.0.0.2

Mais rien n’y fait… ça ne passe pas !

Quelqu’un aurait une idée ?

D’avance merci.

Tu as mal compris, ou c’était mal expliqué. physdev ne sert que lorsque iptables traite les paquets pontés, pour spécifier l’interface “physique” (port), -i ou -o servant à spécifier l’interface pont (br0). Dans le cas d’un système fonctionnant en routeur classique sans pontage, il n’y a pas lieu d’utiliser physdev.

Mais encore ? La règle avec “-i eth0” s’applique aux paquets arrivant sur une autre interface ? Impossible. Comments testes-tu ?

En cherchant un peu et en lisant le MAN j’ai fini par trouver une solution.
Pour faire du forwarding sur plusieurs interfaces il ne faut pas utiliser le paramètre -i mais -s et -d comme dans cet exemple :

iptables -t nat -A PREROUTING -p tcp -s 0/0 -d {local_ip} --dport {local_port} -j DNAT --to {destination_ip}:{destination_port}

En espérant que ça aide quelqu’un.

[quote=“PascalHambourg”]
Mais encore ? La règle avec “-i eth0” s’applique aux paquets arrivant sur une autre interface ? Impossible. Comments testes-tu ?[/quote]

En me connectant en FTP sur le port 21 je constate que j’arrive sur un serveur qui n’est pas le bon et qui correspond à une autre règle (eth0 au lieu de eth2).

Et tu as vérifié que les paquets arrivent par la bonne interface ?

Les packets transitent via un Firewall Watchguard.

La règle sur le Watchguard indique que les données transmises sur ces ports doivent arriver sur une interface d’un “routeur” en local (eth2).

Ensuite la règle iptable doit renvoyer la requête dans un des sous-réseaux sur un serveur FTP.

En essayant l’ip publique n°1 = eth0 en local, la connexion se fait bien sur le bon serveur en local (serveur 1).
En essayant l’ip publique n°2 = eth2 en local, la connexion se fait toujours sur le serveur 1 et Filezilla indique du coup une erreur d’identification.

Je suis sûr de ce que j’avance car les logs de connexion Filezilla affichent l’ip du serveur 1 quand je me connecte sur l’ip publique n°2.

Je pense que le routage et les routes statiques “déroutent” le transit…

C’est tout simplement faux. Avec -d tu fais de la discrimination sur l’adresse destination, pas sur l’interface d’entrée. Les deux n’ont rien à voir. Pour rappel, sur un système Linux, on peut utiliser n’importe quelle adresse locale sur n’importe quelle interface (à l’exception du loopback).

Comment le watchguard et le routeur sont-il interconnectés ? Si les deux interfaces eth0 et eth2 du routeur sont connectées au même réseau (ce qui ne sert à rien), alors ce comportement est (im)prévisible et aurait aussi bien pu se produire dans l’autre sens.

Le watchguard forwarde les requêtes d’une ip publique vers une ip locale et autorise par la même occasion l’ouverture de certains ports.
Comment le routeur pourrait-il alors dissocier les requêtes des 2 ips publiques si il ne possède pas 2 interfaces dans le même réseau local ?

Sachant qu’elles arrivent toutes sur le même port (21) et proviennent d’une seule et même ip locale (car le Watchguard est aussi une passerelle.) ?

Si t’as une solution je suis preneur !

Quand deux interfaces sont connectées au même réseau, par défaut (c’est modifiable via /proc/sys/net/ipv4/conf/) elles répondent toutes les deux aux requêtes ARP pour n’importe laquelle des deux adresses. La machine qui a émis la requête ARP reçoit les deux réponses et en utilise une pour envoyer les paquets IP à l’interface sélectionnée. Le résultat est imprévisible.

Une interface réseau peut parfaitement avoir plusieurs adresses IP. La seconde interface ne sert à rien.
On peut ajouter une adresse à une interface soit en créant un “alias” avec ifconfig (ancienne méthode obsolète)

ou bien avec ip (plus moderne, mais pas affiché par ifconfig si on ne définit pas un label, ce qui revient à créer un alias)

Dans ce cas les règles iptables doivent prendre en compte l’interface d’entrée (-i) et l’adresse destination (-d).

Et pour la 2ème méthode, on ne travaille plus avec le nom de l’interface mais directement avec l’ip ?

Avec les deux, comme d’habitude. Mais je ne suis pas sûr de comprendre la question. Qu’entends-tu exactement par “travailler” ?