Wie erfasst man den Datenverkehr auf virtuellen Schnittstellen?

12

Ich möchte den Datenverkehr auf virtuellen Linux-Schnittstellen zu Debugging-Zwecken erfassen. Ich habe experimentiert mit veth, tunund dummyInterface - Typen; Bei allen dreien habe ich Probleme, tcpdumpetwas zu zeigen.

So richte ich die Dummy-Schnittstelle ein:

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

In einem Terminal sehen Sie es mit tcpdump:

tcpdump -i dummy10

Hören Sie gleich mit nc:

nc -l 99.99.99.1 2048

In einem dritten Schritt stellen Sie eine HTTP-Anfrage mit curl:

curl http://99.99.99.1:2048/

Obwohl wir in Terminal 2 die Daten aus der curlAnfrage sehen können, zeigt sich nichts von tcpdump.

In einem Tun / Tap-Tutorial werden einige Situationen erläutert , in denen der Kernel möglicherweise keine Pakete sendet, wenn er auf einer lokalen Schnittstelle ausgeführt wird:

Wenn wir die Ausgabe von tshark betrachten, sehen wir ... nichts. Es wird kein Datenverkehr über die Schnittstelle geleitet. Dies ist richtig: Da wir die IP-Adresse der Schnittstelle anpingen, entscheidet das Betriebssystem korrekt, dass kein Paket "auf dem Draht" gesendet werden muss, und der Kernel selbst antwortet auf diese Pings. Wenn Sie darüber nachdenken, ist es genau das, was passieren würde, wenn Sie die IP-Adresse einer anderen Schnittstelle anpingen würden (zum Beispiel eth0): Es würden keine Pakete gesendet. Dies mag offensichtlich klingen, könnte aber zunächst Verwirrung stiften (es war für mich).

Es ist jedoch schwer einzusehen, wie dies auf TCP-Datenpakete zutreffen könnte.

Vielleicht tcpdumpsollte das Interface anders angebunden sein?

SolidSnack
quelle
Ich bin nicht sicher, warum es schwierig ist, das bei TCP-Paketen zu sehen. Diese werden wie Pings im Kernel verarbeitet. Das Gleiche passiert.
Derobert
@derobert Bei Pings kann der Kernel antworten. Bei Datenpaketen stellte ich mir eher vor, dass sie die Schnittstelle "übergehen" müssten, damit die Anwendung auf sie reagieren könnte.
SolidSnack
1
Anwendungen sprechen mit dem Kernel über Lesen, Schreiben usw. Viele Netzwerk-Apps müssen nicht einmal wissen, dass Schnittstellen vorhanden sind. Damit der Datenverkehr über einen von ihnen geleitet wird, muss er vom Kernel als nicht lokal angesehen werden. Richten Sie beispielsweise einen OpenVPN-Tunnel ein, um den Datenverkehr über tun0 zu erfassen. (Natürlich ist tun0 eine spezielle Möglichkeit für Apps, mit dem Kernel zu sprechen und eine Netzwerkschnittstelle im Userland zu implementieren, wie dies OpenVPN tut.)
derobert

Antworten:

8

Der Verkehr läuft über die loSchnittstelle.

Wenn einer Box eine IP hinzugefügt wird, wird eine Route für diese Adresse zur 'lokalen' Tabelle hinzugefügt. Alle Routen in dieser Tabelle leiten den Verkehr über die Loopback-Schnittstelle weiter.

Sie können den Inhalt der 'lokalen' Tabelle folgendermaßen anzeigen:

ip route show table local

Was auf meinem System so aussieht:

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 

Also im Grunde , wenn ich keinen Verkehr senden 10.230.134.38, 127.0.0.0/8, 127.0.0.1(redundant) , 172.17.42.1oder 192.168.0.20wird der Verkehr über das Loopback - Interface geroutet, obwohl dieser IPs ist wirklich auf einer andere Schnittstelle.

Patrick
quelle
1

Sie können tcpdumpmit jeder Schnittstelle auf dem Host ( tcpdump -i any ...) verwenden

Charles Nakhel
quelle
0

Dies sollte durch Aufrufen eines zweiten Systems möglich sein (möglicherweise sogar einer VM auf diesem Host).

Sie können DNATin der OUTGOINGKette der natTabelle verwenden und die Pakete an eine Schnittstelle umleiten, die der Kernel nicht steuert. Sie müssen sie dort widerspiegeln:

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