Comment capturer du trafic sur des interfaces virtuelles?

12

Je voudrais capturer du trafic sur des interfaces virtuelles Linux, à des fins de débogage. J'ai expérimenté avec veth, tunet les dummytypes d' interface; sur les trois, j'ai du mal tcpdumpà montrer quoi que ce soit.

Voici comment j'ai configuré l'interface factice:

ip link add dummy10 type dummy
ip addr add 99.99.99.1 dev dummy10
ip link set dummy10 up

Dans un terminal, regardez-le avec tcpdump:

tcpdump -i dummy10

Dans une seconde, écoutez-le avec nc:

nc -l 99.99.99.1 2048

Dans un troisième, faites une requête HTTP avec curl:

curl http://99.99.99.1:2048/

Bien que dans le terminal 2, nous puissions voir les données de la curldemande, rien ne s'affiche tcpdump.

Un didacticiel Tun / Tap clarifie certaines situations dans lesquelles le noyau peut n'envoyer aucun paquet lorsque l'on opère sur une interface locale:

En regardant la sortie de tshark, on voit ... rien. Aucun trafic ne passe par l'interface. C'est exact: puisque nous envoyons une requête ping à l'adresse IP de l'interface, le système d'exploitation décide correctement qu'aucun paquet ne doit être envoyé "sur le fil", et le noyau lui-même répond à ces pings. Si vous y réfléchissez, c'est exactement ce qui se passerait si vous cingliez l'adresse IP d'une autre interface (par exemple eth0): aucun paquet ne serait envoyé. Cela peut sembler évident, mais pourrait être une source de confusion au début (c'était pour moi).

Cependant, il est difficile de voir comment cela pourrait s'appliquer aux paquets de données TCP.

Peut tcpdump-être devrait être lié à l'interface d'une manière différente?

solidsnack
la source
Je ne sais pas pourquoi il est difficile de voir cela arriver aux paquets TCP. Comme les pings, ceux-ci sont traités dans le noyau. La même chose se produit.
derobert
@derobert Dans le cas des pings, le noyau peut répondre. Dans le cas des paquets de données, j'imaginais plutôt qu'ils auraient à "passer" l'interface pour que l'application puisse y répondre.
solidsnack
1
Les applications parlent au noyau en utilisant la lecture, l'écriture, etc. De nombreuses applications réseau n'ont même pas besoin de savoir que des interfaces existent. Pour que le trafic passe sur l'un d'eux, le noyau doit le voir comme non local. Par exemple, configurez un tunnel OpenVPN, puis vous pouvez capturer le trafic passant par tun0. (Bien sûr, tun0 est un moyen spécial pour les applications de parler au noyau, d'implémenter une interface réseau dans l'espace utilisateur, ce que fait OpenVPN.)
derobert

Réponses:

8

Le trafic passe par l' lointerface.

Lorsqu'une IP est ajoutée à une boîte, une route pour cette adresse est ajoutée à la table «locale». Tous les itinéraires de ce tableau acheminent le trafic via l'interface de bouclage.

Vous pouvez afficher le contenu de la table «locale» avec les éléments suivants:

ip route show table local

Ce qui sur mon système ressemble à ceci:

local 10.230.134.38 dev tun0  proto kernel  scope host  src 10.230.134.38 
broadcast 10.230.134.38 dev tun0  proto kernel  scope link  src 10.230.134.38 
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1 
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1 
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1 
broadcast 172.17.0.0 dev docker0  proto kernel  scope link  src 172.17.42.1 
local 172.17.42.1 dev docker0  proto kernel  scope host  src 172.17.42.1 
broadcast 172.17.255.255 dev docker0  proto kernel  scope link  src 172.17.42.1 
broadcast 192.168.0.0 dev enp6s0  proto kernel  scope link  src 192.168.0.20 
local 192.168.0.20 dev enp6s0  proto kernel  scope host  src 192.168.0.20 
broadcast 192.168.0.255 dev enp6s0  proto kernel  scope link  src 192.168.0.20 

Donc , fondamentalement , si j'envoie tout le trafic vers 10.230.134.38, 127.0.0.0/8, 127.0.0.1(redondant) , 172.17.42.1ou 192.168.0.20, le trafic sera routés sur l'interface de réalimentation, même si les adresses IP sont vraiment sur une autre interface.

Patrick
la source
1

Vous pouvez utiliser tcpdumpavec n'importe quelle interface sur l'hôte ( tcpdump -i any ...)

Charles nakhel
la source
0

Cela devrait être possible en invoquant un deuxième système (peut même être une machine virtuelle sur cet hôte).

Vous pouvez utiliser DNATdans la OUTGOINGchaîne de la nattable et rediriger les paquets vers une interface que le noyau ne contrôle pas. Vous devez y réfléchir:

iptables -t nat -A OUTPUT -p tcp -d 99.99.99.1 --dport 2048 \
  -j DNAT --to-destination 1.2.3.4
Hauke ​​Laging
la source