Łączenie dwóch interfejsów kranowych

0

Jestem totalnym noobem, to mój pierwszy eksperyment z siecią jądra. Próbuję utworzyć pomost między dwoma tapinterfejsami i staram się przesyłać ruch. To bardziej eksperyment niż jakikolwiek konkretny cel.

$ 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          

Mam br0utworzony most , z jednym tap1i tap2drugim. Mam program wstrzykujący pakiety ARP do tap1używania libpcap. Wireshark poprawnie pokazuje wchodzące pakiety tap1. Jednak żaden pakiet nie pojawia się w tap2. Próbowałem dodać regułę śledzenia w ebtables:

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

W dziennikach nie pojawiają się żadne pakiety. Będę wdzięczny za wszelkie dane wejściowe.

EDYCJA: Dodawanie dodatkowych informacji. Aplikowanie fałszywych pakietów jest rzeczywiście aplikacją. Moim zamiarem jest symulacja, w pełni programowo i bez maszyn wirtualnych, w jaki sposób pakiety są przekazywane przez stos jądra Linuksa. Nie tworzę żadnych nowych sieciowych nazw. Być może to jest problem?

Mam tylko dwa procesy. Proces „odczytu” ma otwarty deskryptor pliku tap2i stale próbuje z niego czytać. Proces zapisu ma otwarty deskryptor pliku tap1i czeka na monit użytkownika o wysłanie zapytania ARP. Zapytanie ARP ma losowy źródłowy adres IP. Źródłowy adres MAC jest ustawiony jako adres MAC tap1. Oto wynik działania 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

Skonfigurowałem tap1i tap2nie mam adresów IP. Czy to może być problem?

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

Na podstawie odpowiedzi sprawdziłem dołączanie różnych aplikacji do tap2. Zauważam to: gdy żadna aplikacja nie używa tap1lub tap2, oba interfejsy nie mają ustawionej flagi LOWER_UP.

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

Kiedy uruchamiam aplikacje, flaga LOWER_UP zostaje ustawiona:

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

Przykro mi, że okazuje się to zbyt długie, mam tylko nadzieję, że jest wystarczająco dużo informacji, aby zrozumieć problem.

SPMP
źródło

Odpowiedzi:

1

Na wszelki wypadek, ponieważ powiedziałeś, że jesteś całkowitym noob: Interfejs tun (warstwa 3) lub dotknij (warstwa 2) jest punktem końcowym interfejsu sieciowego aplikacji, a aplikacja może odczytywać i zapisywać pakiety z tego interfejsu sieciowego. To, co utworzysz ip tuntap add ...lub za pomocą przestarzałych, tunctlto trwałe nazwy takich punktów końcowych, a normalnie nadal będziesz uruchamiać aplikację i nie zrobi nic, dopóki nie uruchomisz aplikacji.

Ponieważ aplikacja od samego początku wchodzi w interakcję z interfejsem sieciowym, nie ma potrzeby „wstrzykiwania” pakietów za pomocą aplikacji innej firmy, chyba że masz na myśli „wstrzykiwanie” tej normalnej interakcji, którą opisałem.

Ponadto, jeśli chcesz się bawić w sieci, mogę polecić korzystanie z sieciowych nazw i par veth . Zasadniczo możesz skonfigurować wiele komputerów wirtualnych na swoim komputerze, które mogą naśladować komunikację między prawdziwymi komputerami w sieci.

Więc jeśli chcesz to zrobić i nie chcesz grać z własną aplikacją tworzącą i odbierającą pakiety, nie potrzebujesz interfejsu tun / tap.

Powiedział, że właśnie testowane konfiguracji, z niewielką zmianę, ponieważ nie powiedzieć to, czego używasz do „wstrzyknąć” pakiety: Użyłem dwóch socats stworzyć wykorzystać końcowego tap0ai tap1a, potem mostkiem je i stosować dwa kolejne socatsw dwie różne przestrzenie nazw, aby stworzyć dla mnie odpowiednie pakiety. Muszą znajdować się w innej przestrzeni nazw, ponieważ lokalne pakiety zawsze będą dostarczane przez sprzężenie zwrotne lo.

I zgodnie z oczekiwaniami mostkowanie urządzeń z kranem działa dobrze.

Przypuszczam, że problem tkwi w pakiecie, który wstrzykujesz: zły adres ethernetowy lub brak emisji. Edytuj swoje pytanie za pomocą tcpdump -xx ...danych wyjściowych po wstrzyknięciu pakietu ARP.

A może chcesz zamiast tego utworzyć sieciowe przestrzenie nazw i połączyć dwa punkty końcowe dwóch par veth? To o wiele prostsze.

Edytować

Pakiet ARP wygląda dobrze. Wygląda na to, że nie jest podłączona żadna aplikacja tap2. Jeśli to zrobisz ip link, nie powinieneś widzieć LOWER_UPflagi dla tap2. Zgadnij: Most wykrywa, że ​​urządzenie jest tylko częściowo podniesione i nie wysyła pakietów do tego portu.

Spróbuj zastępując ją tap, że ma aplikację podłączony do niego, coś takiego

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

( 10.0.2.2/24adres nic nie robi, ale socatnie zadziała, jeśli nie podasz adresu) i na innym terminalu

sudo ip link set tapx master br0

(który zastępuje brctl addif), a następnie wstrzyknij swój pakiet kilka razy i sprawdź, czy w pierwszym oknie pojawi się zrzut heksowy. Sprawdź również za LOWER_UPpomocą ip link show dev tapx.

BTW ifconfigi brctlsą nieaktualne. Użyj ipi bridgezamiast.

Nie przypisywanie adresów IP do portów mostu nie ma znaczenia, ponieważ porty mostu nie mają adresów IP (jeśli przydzielono im niektóre adresy, zanim zostały zniewolone przez most, są one ignorowane). Zobacz np . Tutaj .

reż
źródło
Dodałem szczegóły. Czy możesz to sprawdzić?
SPMP
Okazuje się, że jest odwrotnie. tap2korzysta z aplikacji, ale nie tap1. Za każdym razem, gdy aplikacja łączy się z interfejsem, ustawiana jest LOWER_UP. Czy to wskazuje na problem?
SPMP
Dziękujemy za dotychczasową pomoc! Nie zaznaczyłem odpowiedzi jako zaakceptowanej, na wypadek, gdyby ktoś mógł ją zrozumieć.
SPMP
0

Walczyłem z tym bardzo i myślę, że znalazłem rozwiązanie. A przynajmniej lepsze zrozumienie tego, co się dzieje.

Należy pamiętać, że jedynym sposobem dostarczenia pakietu do interfejsu zaczepów po stronie odbierającej („RX”) jest zapisanie tego pakietu w deskryptorze gniazda utworzonym przez proces, który otworzył zaczep (przez open("/dev/net/tun",...)i ioctl). Tylko jeden proces może mieć jednocześnie ten deskryptor pliku. Jeśli urządzenie z kranem jest otwarte, a inny proces próbuje ponownie otworzyć inne urządzenie z kranem o tej samej nazwie, to połączenie systemowe nie powiedzie się.

Więc kiedy masz jakikolwiek inny proces, jak Wireshark, otwierając gniazdo surowy a następnie wiązanie że do tap0, jest zdolny tylko pisać ruch z systemu (z punktu widzenia jądra). Oznacza to, że wireshark powinien obijać TXlicznik tap0i tylko RXpakiety będą przekazywane do mostkowanego interfejsu.

Możesz sprawdzić liczniki dla każdego z nich:

#!/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

który wyprowadza coś takiego:

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

Podejrzewam, że w twoim konkretnym przypadku problem jest następujący:

Mam program wstrzykujący ARPpakiety do tap1korzystania z libpcap. Wireshark poprawnie pokazuje wchodzące pakiety tap1. Jednak żaden pakiet nie pojawia się w tap2.

Jak wstrzykujesz pakiety ARP do tap1? Zakładam Wireshark nie dzwoni fd = open("/dev/net/tun", ...)i ioctl(fd, TUNSETIFF, ...)tak pakiety wysyłane będą TX, a zatem nie mostkiem.

Będziesz potrzebował programu, który otworzy się, tap0aby zapisać pakiety do tap0deskryptora pliku, aby pakiety te były przekazywane br0i wyświetlane na tap1.

Matt Rundle
źródło