rp_filter et maux de tête
Je viens de passer un certain temps à régler un problème avec une machine fraîchement migrée de CENTOS 5.7 à CENTOS 6.2
J’ai une machine dans un réseau A qui tente de contacter mon serveur qui dispose d’une interface (1) dans le réseau A et une interface (2) dans le réseau B.
Plusieurs cas de figure:
- La machine ping l’adresse de l’interface (1) du serveur. C’est sur le même réseau, tout va bien.
- La machine ping l’adresse de l’interface (2) du serveur. Ce n’est pas le même réseau, le routeur joue son rôle, le paquet ICMP arrive bien sur l’interface (2) comme l’atteste tcmdump, mais il n’y a jamais de ECHO REPLY… WTF ?!?
Ce cas de figure marchait parfaitement avec CENTOS 5.x. C’était sans compter l’arrivée du noyau 2.6.31 qui a modifié le fonctionnement du « Reverse path filtering »
Extrait Release notes Redhat 6x:
A change in the 2.6.31 Linux kernel made thenet.ipv4.conf.default.rp_filter = 1
more strict in the I/O that is accepted. Consequently, in Red Hat Enterprise Linux 6, if there are multiple interfaces on the same subnet and I/O is sent to the one that is not the default route, the I/O will be dropped. Note that this applies to iSCSI iface binding when multiple interfaces are on the same subnet. To work around this, set the net.ipv4.conf.default.rp_filter
parameter in /etc/sysctl.conf
to 0 or 2, and reboot the machine.
Quand la machine contacte le serveur sur l’interface (2), le serveur voit un paquet provenant du réseau A, il ne va pas comme avec CENTOS 5 (en vert) répondre par la même interface en routant le paquet mais va tenter de répondre avec l’interface (1) (en rouge sur le schéma) qui est sur le réseau A. Or, c’est la qu’intervient le rp_filter qui va détruire la paquet !
Pour se sortir de cette situation il suffit d’éditer /etc/sysctl.conf et de changer net.ipv4.conf.default.rp_filter = 1 pour net.ipv4.conf.default.rp_filter = 2 ou éventuellement net.ipv4.conf.default.rp_filter = 0