Überbrückung zweier Tap-Schnittstellen

Überbrückung zweier Tap-Schnittstellen

Ich bin ein absoluter Neuling, dies ist mein allererstes Experiment mit Kernel-Netzwerken. Ich versuche, eine Brücke zwischen zwei tapSchnittstellen zu erstellen und den Datenverkehr durchzuleiten. Es ist eher ein Experiment als ein bestimmter Zweck.

$ brctl showstp br0
br0
bridge id      8000.46846e0c0ff9
designated root    8000.46846e0c0ff9
root port         0            path cost          0
max age          20.00         bridge max age        20.00
hello time        2.00         bridge hello time      2.00
forward delay        15.00         bridge forward delay      15.00
ageing time         300.00
hello timer           1.98         tcn timer          0.00
topology change timer     0.00         gc timer         115.04
flags          


tap1 (1)
port id        8001            state            forwarding
designated root    8000.46846e0c0ff9   path cost        100
designated bridge  8000.46846e0c0ff9   message age timer      0.00
designated port    8001            forward delay timer   10.34
designated cost       0            hold timer         0.98
flags          

tap2 (2)
port id        8002            state            forwarding
designated root    8000.46846e0c0ff9   path cost        100
designated bridge  8000.46846e0c0ff9   message age timer      0.00
designated port    8002            forward delay timer    0.00
designated cost       0            hold timer         0.98
flags          

Ich habe die Brücke br0erstellt und sowohl tap1als auch tap2hinzugefügt. Ich habe ein Programm, das ARP-Pakete in tap1einfügt libpcap. Wireshark zeigt die eingehenden Pakete korrekt an tap1. Allerdings wird kein Paket bei angezeigt tap2. Ich habe versucht, die folgende Regel in ebtables hinzuzufügen:

sudo ebtables -I INPUT --log --log-level debug

In den Protokollen werden keine Pakete angezeigt. Ich freue mich über alle Hinweise.

EDIT: Weitere Informationen hinzufügen. Das Einfügen gefälschter Pakete ist tatsächlich die Anwendung. Meine Absicht hier ist es, vollständig in Software und ohne VMs zu simulieren, wie Pakete durch den Linux-Kernel-Stack weitergeleitet werden. Ich erstelle keine neuen Netzwerk-Namespaces. Vielleicht ist das das Problem?

Ich habe nur zwei Prozesse. Der „Lese“-Prozess hat einen Dateideskriptor in geöffnet tap2und versucht ständig, daraus zu lesen. Der Schreibprozess hat einen Dateideskriptor in geöffnet tap1und wartet auf die Benutzeraufforderung, um die ARP-Abfrage zu senden. Die ARP-Abfrage hat eine zufällige Quell-IP-Adresse. Die Quell-MAC-Adresse wird als MAC-Adresse von festgelegt tap1. Hier ist die Ausgabe von tcpdump:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tap1, link-type EN10MB (Ethernet), capture size 262144 bytes
^[[A07:19:57.752990 ARP, Request who-has google-public-dns-a.google.com tell 0.0.248.17, length 28
    0x0000:  ffff ffff ffff ba9c 0589 16ad 0806 0001
    0x0010:  0800 0604 0001 ba9c 0589 16ad 0000 f811
    0x0020:  0000 0000 0000 0808 0808

Ich habe tap1und so konfiguriert tap2, dass keine IP-Adressen vorhanden sind. Könnte das das Problem sein?

brctl addbr br0
ip tuntap add name tap1 mode tap
ip tuntap add name tap2 mode tap
brctl addif br0 tap1
brctl addif br0 tap2
ifconfig tap1 0.0.0.0 up
ifconfig tap2 0.0.0.0 up
ifconfig br0 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255
ip link set br0 up
ip link set tap1 up
ip link set tap2 up

Basierend auf der Antwort habe ich das Anhängen verschiedener Anwendungen an geprüft . Dabei ist mir Folgendes aufgefallen: Wenn keine Anwendung oder tap2verwendet , ist bei beiden Schnittstellen das Flag LOWER_UP nicht gesetzt.tap1tap2

4: br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff
25: tap1: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN mode DEFAULT group default qlen 500
    link/ether ba:9c:05:89:16:ad brd ff:ff:ff:ff:ff:ff
26: tap2: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN mode DEFAULT group default qlen 500

Wenn ich die Anwendungen starte, wird das Flag LOWER_UP gesetzt:

4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff
25: tap1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP mode DEFAULT group default qlen 500
    link/ether ba:9c:05:89:16:ad brd ff:ff:ff:ff:ff:ff
26: tap2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP mode DEFAULT group default qlen 500
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff

Es tut mir leid, dass es so lang wird. Ich hoffe nur, dass es genügend Informationen gibt, um das Problem zu verstehen.

Antwort1

Nur für den Fall, weil du gesagt hast, dass du ein totaler Neuling bist: Eine Tun- (Schicht 3) oder Tap- (Schicht 2) Schnittstelle ist der Netzwerkschnittstellenendpunkt einer Anwendung, und die Anwendung kann Pakete von dieser Netzwerkschnittstelle lesen und schreiben. Was du mit ip tuntap add ...oder die veralteten erschaffst, tunctlsindpersistente Namenfür solche Endpunkte, und Sie werden normalerweise immer noch die Anwendung ausführen, und es wird nichts passieren, wenn Sie die Anwendung nicht ausführen.

Da die Anwendung konstruktionsbedingt mit der Netzwerkschnittstelle interagiert, besteht keine Notwendigkeit, Pakete mit einer Drittanbieteranwendung „einzufügen“, es sei denn, Sie meinen mit „einfügen“ diese normale Interaktion, die ich beschrieben habe.

Wenn Sie mit Netzwerken experimentieren möchten, empfehle ich Ihnen außerdemNetzwerk-NamespacesUndveth-Paare. Grundsätzlich können Sie auf Ihrem Computer viele virtuelle Computer einrichten, die die Kommunikation zwischen realen Computern in einem Netzwerk nachahmen können.

Wenn Sie dies also tun möchten und nicht mit Ihrer eigenen Anwendung herumspielen möchten, die Pakete erstellt und empfängt, benötigen Sie keine Tun/Tap-Schnittstelle.

Trotzdem habe ich gerade Ihr Setup getestet, mit einer kleinen Abweichung, weil Sie nicht gesagt haben, was Sie zum „Einschleusen“ von Paketen verwenden: Ich habe zwei socats verwendet, um zwei Tap-Endpunkte tap0aund zu erstellen tap1a, dann habe ich sie überbrückt und zwei weitere socats in zwei verschiedenen Namespaces verwendet, um die richtigen Pakete für mich zu erstellen. Sie müssen in einem anderen Namespace sein, da lokale Pakete immer über Loopback übermittelt werden lo.

Und wie erwartet funktioniert das Überbrücken von Abgriffgeräten problemlos.

Ich vermute also, dass das Problem bei dem Paket liegt, das Sie einfügen: Falsche Ethernet-Adresse oder keine Übertragung. Bitte bearbeiten Sie Ihre Frage mit der tcpdump -xx ...Ausgabe, wenn Sie das ARP-Paket einfügen.

Oder möchten Sie vielleicht stattdessen Netzwerk-Namespaces erstellen und zwei Endpunkte von zwei Veth-Paaren überbrücken? Das ist viel einfacher.

Bearbeiten

Das ARP-Paket sieht gut aus. Es scheint, als ob keine Anwendung mit verbunden ist tap2. Wenn dies der Fall ist ip link, sollten Sie kein LOWER_UPFlag für sehen tap2. Vermutung: Die Bridge erkennt, dass das Gerät nur teilweise aktiv ist, und sendet keine Pakete an diesen Port.

Versuchen Sie, es durch ein zu ersetzen, tapdashateine damit verbundene Anwendung, etwa

sudo socat TUN:10.0.2.2/24,tun-name=tapx,tun-type=tap,iff-up - | hexdump -C

(die 10.0.2.2/24Adresse tut nichts, socatfunktioniert aber nicht, wenn Sie keine Adresse angeben) und in einem anderen Terminal

sudo ip link set tapx master br0

(das ersetzt brctl addif), fügen Sie dann Ihr Paket mehrere Male ein und prüfen Sie, ob Sie im ersten Fenster einen Hexdump erhalten. Suchen Sie auch nach LOWER_UPmit ip link show dev tapx.

Übrigens sind ifconfigund brctlveraltet. Verwenden Sie stattdessen ipund .bridge

Die Nichtzuweisung von IP-Adressen an die Ports der Bridge hat keine Auswirkungen, da die Bridge-Portskeine IP-Adressen haben(wenn ihnen welche zugewiesen wurden, bevor sie durch eine Brücke versklavt wurden, werden sie ignoriert). Siehe z. B.Hier.

Antwort2

Ich habe viel damit gekämpft und glaube, ich bin zu einer Lösung gekommen. Oder zumindest zu einem besseren Verständnis dessen, was vor sich geht.

Es ist wichtig zu bedenken, dass die einzige Möglichkeit, ein Paket an eine Tap-Schnittstelle auf der Empfangsseite ("RX") zu übermitteln, darin besteht, dieses Paket in den Socket-Deskriptor zu schreibenerstellt durch den Prozess, der den Hahn öffnete(über open("/dev/net/tun",...)und ioctl). Nur ein Prozess kann diesen Dateideskriptor gleichzeitig haben. Wenn ein Tap-Gerät geöffnet ist und ein anderer Prozess versucht, ein anderes Tap-Gerät mit demselben Namen erneut zu öffnen, schlägt dieser Systemaufruf fehl.

Wenn Sie also einen anderen Prozess haben, wie z. B. Wireshark, der einen Raw-Socket öffnet und dann bindetDaszu tap0, es ist nur in der Lage, Verkehr zu schreibenausdes Systems (aus Sicht des Kernels). Das heißt, Wireshark sollte den TXZähler von erhöhen tap0und nur RXPakete werden an die überbrückte Schnittstelle weitergeleitet.

Sie können die Zähler für jedes Like überprüfen:

#!/bin/bash
for if in tap{0,1}; do
    stats=/sys/class/net/$if/statistics/
    rx=$(cat $stats/rx_packets)
    tx=$(cat $stats/tx_packets)
    echo "$if: rx=$rx, tx=$tx"
done

die Ausgabe erfolgt in etwa wie folgt:

tap0: rx=0, tx=6
tap1: rx=0, tx=5

In Ihrem speziellen Fall vermute ich, dass das Problem hier liegt:

Ich habe ein Programm, das ARPPakete mithilfe von libpcap in einfügt tap1. Wireshark zeigt die eingehenden Pakete korrekt an tap1. Bei wird jedoch kein Paket angezeigt tap2.

Wie fügen Sie ARP-Pakete in tap1 ein? Ich gehe davon aus, dass Wireshark nicht anruft fd = open("/dev/net/tun", ...)und ioctl(fd, TUNSETIFF, ...)daher die gesendeten Pakete TX sind und daher nicht überbrückt werden.

Sie benötigen das Programm, das tap0Pakete in tap0den Dateideskriptor von schreibt, damit diese Pakete weitergeleitet werden br0und angezeigt werden tap1.

verwandte Informationen