Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[Bug?] Netfilter, routage avancé et fragmentation

2 réponses
Avatar
Pascal
Salut tous,

Dans le but de mieux comprendre le fonctionnement de Netfilter avec un
noyau 2.4 (principalement le dernier, 2.4.29), je réalise diverses
expériences concernant principalement le suivi de connexion, le NAT, le
marquage et les interactions avec le routage. Si ça intéresse quelqu'un,
j'ai jeté mes premières observations en vrac là :
http://www.plouf.fr.eu.org/bazar/netfilter/. Attention, c'est du brut.
J'ai aussi fait un schéma résumant ce que je crois avoir compris du
cheminement d'un paquet IP à travers Netfilter et le routage, plus
complet que ceux que j'ai pu trouver jusqu'ici sur le web. Commentaires
et corrections bienvenus.

J'ai aussi fait de curieuses observations concernant la fragmentation,
c'est ce qui m'amène ici.

Pour commencer, j'ai observé la fragmentation à grands coups de LOG avec
et sans suivi de connexion. J'en parle dans le brouillon mentionné plus
haut. Bien que le suivi de connexion réassemble les paquets fragmentés
entrant dans Netfilter, il s'avère qu'un paquet forwardé qui doit être
fragmenté est vu fragmenté dans mangle POSTROUTING mais non fragmenté
partout ailleurs (sauf en sortie avec tcpdump). Par contre un paquet
émis localement devant être fragmenté n'est vu fragmenté dans aucune des
chaînes traversées.

Ensuite j'ai voulu voir ce qui se passait si je changeais l'interface de
sortie d'un paquet émis localement avec MARK+ip rule et si la MTU de la
nouvelle interface était inférieure à la taille du paquet, avec le flag
DF=0 (fragmentation possible) puis DF=1 (ne pas fragmenter). Comment ça,
vicelard ?

Mise en oeuvre :
ifconfig eth0 172.16.0.1 mtu 1300
ifconfig eth1 192.168.0.236 mtu 1500

# reroutage en sortie d'un paquet de ~1400 octets envoyé initialement
# sur eth1 (mtu 1500, pas besoin de fragmenter) vers eth0 (mtu 1300)
# pour provoquer la fragmentation apres reroutage
# note : module conntrack déchargé

# reroute tout paquet émis vers 192.168.0.7 vers eth0 au lieu de eth1
ip route add default dev eth0 table 250
ip rule add fwmark 0x7 lookup 250
iptables -t mangle -A OUTPUT -d 192.168.0.7 -j MARK --set-mark 0x7
ip route flush cache

# test
ping -M dont -c 1 -s 1400 192.168.0.7 # fragmentation possible
ping -M do -c 1 -s 1400 192.168.0.7 # ne pas fragmenter

Résultat :

clementine:~# tcpdump -vi eth0
192.168.0.236 > 192.168.0.7: icmp: echo request (ttl 64, id 0, len 1428)
172.16.0.1 > 192.168.0.7: icmp: echo request (DF) (ttl 64, id 0, len 1428)

Le paquet de 1428 octets n'est pas fragmenté et envoyé tel quel sur eth0
malgré sa MTU=1300.
J'ai voulu aller plus loin. Que se passe-t-il si on envoie un paquet
plus gros que 1500 octets ? Pour ça, je commence par envoyer le paquet
vers l'interface de loopback dont la MTU vaut 16436 :

clementine:~# route add 192.168.0.7 dev lo

# envoi d'un paquet non fragmentable de ~2000 octets > 1500 d'ethernet
clementine:~# ping -M dont -c 1 -s 2000 192.168.0.7

clementine:~# tcpdump -vi eth0
172.16.0.1 > 192.168.0.7: icmp: echo request (ttl 64, id 5727, len 2028)

En fait je ne sais pas si le paquet est vraiment sorti de la carte
ethernet, je n'ai pas le moyen de vérifier. Mais pas un message
d'erreur, rien !

Apparemment, en cas de reroutage en sortie il n'y a ni comparaison de la
taille du paquet avec la MTU de l'interface ni fragmentation si
nécessaire. Serait-ce un BUG ? Merci de vos avis.

--
Pascal
Vous pouvez me tutoyer.
Piège à spam : boite-a-spam@plouf.fr.eu.org

2 réponses

Avatar
TiChou
Dans le message <news:d0o7pt$2hcr$,
** tapota sur f.c.o.l.configuration :

Salut tous,


Salut,

[...]

En fait je ne sais pas si le paquet est vraiment sorti de la carte
ethernet, je n'ai pas le moyen de vérifier.


Pourquoi tu n'as pas moyen de le vérifier ? Tu ne peux pas sniffer le trafic
sur la machine de destination ?

--
TiChou

Avatar
Pascal
Dans le message <news:d0o7pt$2hcr$,
** tapota sur f.c.o.l.configuration :

En fait je ne sais pas si le paquet est vraiment sorti de la carte
ethernet, je n'ai pas le moyen de vérifier.


Pourquoi tu n'as pas moyen de le vérifier ? Tu ne peux pas sniffer le
trafic sur la machine de destination ?


Et bien, parce qu'au moment où j'ai fait cette expérience je n'imaginais
pas que j'en aurais besoin, et donc cette carte ethernet n'était
branchée à rien. Pour ne pas ramasser de host unreachable à cause de
l'échec de la résolution ARP, j'avais créé une entrée statique dans la
table ARP avec une adresse MAC bidon. Cette fois-ci j'ai recommencé
après avoir branchée le port de la carte directement à la carte ethernet
d'un autre PC sur lequel j'ai lancé tcpdump.

Résultats :

- Quelle que soit la valeur du flag DF et la taille du paquet IP (j'ai
essayé jusqu'à 16000), le paquet a l'air d'être émis. Du moins les leds
d'activité des deux cartes clignotent.
- Par contre, tcpdump sur la machine réceptrice ne le voit que si la
taille ne dépasse pas 1504 octets (je suppose que le rab est prévu pour
le tagging VLAN 802.1q).
- Entre 1505 et 2029 octets IP (2047 octets ethernet en comptant les 18
octets de la couche ethernet), le log kernel de la machine réceptrice
reçoit un message "bogus packet size".
- A partir de 2030 octets IP (2048 ethernet), plus rien dans le log.

Note : les deux cartes sont à base de RTL8029.

PS : mon schéma te semble bon ?

--
Pascal
Vous pouvez me tutoyer.
Piège à spam :