Wymuś lokalny ruch IP na zewnętrzny interfejs

30

Mam maszynę z kilkoma interfejsami, które mogę skonfigurować tak, jak chcę, na przykład:

  • eth1: 192.168.1.1
  • eth2: 192.168.2.2

Chciałbym przekazać cały ruch wysłany na jeden z tych lokalnych adresów przez drugi interfejs. Na przykład wszystkie żądania do serwera iperf, ftp, http o numerze 192.168.1.1 powinny być nie tylko kierowane wewnętrznie, ale przekazywane dalej przez eth2 (a sieć zewnętrzna zajmie się przekierowaniem pakietu do eth1).

Próbowałem i spojrzałem na kilka poleceń, takich jak iptables, ip route itp. ... ale nic nie działało.

Najbliższe zachowanie, jakie mogłem osiągnąć, to:

ip route change to 192.168.1.1/24 dev eth2

które wysyłają wszystkie 192.168.1.x na eth2, z wyjątkiem 192.168.1.1, które nadal są wewnętrznie trasowane. Czy mógłbym wtedy przesyłać NAT całego ruchu skierowanego do fałszywego 192.168.1.2 na eth1, przekierowanego wewnętrznie na 192.168.1.1? Właściwie walczę z iptables, ale jest to dla mnie zbyt trudne.

Celem tej konfiguracji jest przeprowadzenie testów sterowników interfejsu bez użycia dwóch komputerów.

Używam Linuksa, ale jeśli wiesz, jak to zrobić w systemie Windows, kupię to!

Edytować:

Sieć zewnętrzna to tylko kabel krosowy między eth1 i eth2. Powiedzmy, że mam serwer http na moim komputerze. Teraz chcę uzyskać dostęp do tego serwera z tego samego komputera, ale chcę zmusić ruch TCP / IP do przechodzenia przez ten kabel eth1 / eth2. Jak mam w tym celu skonfigurować moje interfejsy?

calandoa
źródło
Czy mówisz, że chcesz, aby cały ruch był dublowany przez interfejs 1 i 2, ale by powrócił tylko do interfejsu 2 z innego routera? Czy to nie może zrobić trochę dziwnych rzeczy w sieci? Czy lepiej byłoby skierować ruch lustrzany z interfejsu 2 do innego systemu, który właśnie spadł, a następnie można go monitorować lub użyć oprogramowania do wirtualizacji do przechwytywania ruchu? Może brakuje mi czegoś w opisie.
Bart Silverstrim
Wygląda na to, że chce wygenerować pakiet, powiedzmy 192.168.1.1, który jest adresem IP eth1. Ale zamiast stosu Linuksa odbierającego ten pakiet całkowicie wewnętrznie, chce, aby pakiet został wypchnięty z eth2 (który zostanie dostarczony zewnętrznie z powrotem do eth1, a następnie stosu Linux). Nie jestem pewien, czy jest to możliwe; gdy warstwa sieci wykryje, że adres jest interfejsem wewnętrznym, nie będzie miał powodu, aby patrzeć na tabele routingu. Ktoś inny może wiedzieć lepiej.
PP.

Odpowiedzi:

14

Rozszerzyłem odpowiedź Caladony, ponieważ nie widziałem pakietów odpowiedzi. W tym przykładzie:

  1. Na moim lokalnym komputerze mam karty sieciowe w różnych podsieciach, 192.168.1 / 24 , 192.168.2 / 24
  2. Istnieje zewnętrzny router / komputer, który ma dostęp do obu podsieci.
  3. Chcę wysyłać ruch dwukierunkowy przez karty sieciowe na lokalnym komputerze.
  4. Konfiguracja wymaga dwóch nieużywanych adresów IP dla każdej podsieci.

Lokalne trasy iptable komputera są ustawione na ruch wychodzący SNAT i DNAT do „fałszywego” adresu IP.

iptables -t nat -A POSTROUTING -d 192.168.1.100 -s 192.168.2.0/24 -j SNAT --to-source      192.168.2.100
iptables -t nat -A PREROUTING  -d 192.168.1.100 -i eth0           -j DNAT --to-destination 192.168.1.1
iptables -t nat -A POSTROUTING -d 192.168.2.100 -s 192.168.1.0/24 -j SNAT --to-source      192.168.1.100
iptables -t nat -A PREROUTING  -d 192.168.2.100 -i eth1           -j DNAT --to-destination 192.168.2.1

Reguły wykonują następujące czynności:

  1. Przepisz źródło 192.168.2.1 do 192.168.2.100 na pakietach wychodzących
  2. Przepisz adres 192.168.1.100 do 192.168.1.1 na przychodzących pakietach
  3. Przepisz źródło 192.168.1.1 do 192.168.1.100 na pakietach wychodzących
  4. Przepisz adres 192.168.2.100 do 192.168.2.1 na przychodzących pakietach

Podsumowując, system lokalny może teraz komunikować się z „wirtualną” maszyną o adresach 192.168.1.100 i 192.168.2.100.

Następnie musisz zmusić lokalny komputer do korzystania z zewnętrznego routera w celu uzyskania fałszywego adresu IP. Robisz to, tworząc bezpośrednią trasę do adresów IP poprzez router. Chcesz się upewnić, że pakiety są wymuszane na przeciwną do podsieci docelowej.

ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP 
ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP

Wreszcie, aby wszystko działało, zewnętrzny router musi wiedzieć, jak dotrzeć do fałszywych adresów IP na lokalnym komputerze. Możesz zrobić cienkie, włączając ARP proxy dla twojego systemu.

echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/proxy_arp
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Dzięki tej konfiguracji możesz teraz traktować fałszywe adresy IP jako prawdziwy system na komputerze lokalnym. Wysyłanie danych do podsieci .1 wymusi pakiety z interfejsu .2. Wysyłanie danych do podsieci .2 wymusi pakiety z interfejsu .1.

ping 192.168.1.100
ping 192.168.2.100
cmcginty
źródło
O wiele lepiej na twój sposób! Zauważ, że potrzebuję również ip_forward, aby działało ARP: echo 1> / proc / sys / net / ipv4 / ip_forward
calandoa
28

Z powodzeniem wykorzystałem następujące informacje w systemie Linux do przetestowania przepustowości na nowej podwójnej karcie 10 Gb / s w trybie „pętli zwrotnej”, to znaczy, że jeden port jest podłączony bezpośrednio do drugiego. To wszystko jest tylko trochę voodoo tylko po to, aby zmusić pakiety do wyjścia, ale jeśli tego nie zrobisz, Linux po prostu zewrze ruch w jądrze (stąd pytanie OP). W powyższej odpowiedzi Casey nie jestem pewien, czy naprawdę konieczne było posiadanie zewnętrznego routera, czy nie, ale poniższe są całkowicie samodzielne. Dwa interfejsy to eth2 i eth3.

Podaj adresy IP interfejsom i umieść je w osobnych sieciach:

ifconfig eth2 10.50.0.1/24
ifconfig eth3 10.50.1.1/24

Następnie skonfigurujemy podwójny scenariusz NAT: dwie nowe fałszywe sieci wykorzystane do osiągnięcia drugiej. Po wyjściu z sieci NAT poznaj swoją fałszywą sieć. Po drodze napraw miejsce docelowe. I odwrotnie dla drugiej sieci:

# nat source IP 10.50.0.1 -> 10.60.0.1 when going to 10.60.1.1
iptables -t nat -A POSTROUTING -s 10.50.0.1 -d 10.60.1.1 -j SNAT --to-source 10.60.0.1

# nat inbound 10.60.0.1 -> 10.50.0.1
iptables -t nat -A PREROUTING -d 10.60.0.1 -j DNAT --to-destination 10.50.0.1

# nat source IP 10.50.1.1 -> 10.60.1.1 when going to 10.60.0.1
iptables -t nat -A POSTROUTING -s 10.50.1.1 -d 10.60.0.1 -j SNAT --to-source 10.60.1.1

# nat inbound 10.60.1.1 -> 10.50.1.1
iptables -t nat -A PREROUTING -d 10.60.1.1 -j DNAT --to-destination 10.50.1.1

Teraz powiedz systemowi, jak dostać się do każdej fałszywej sieci, i wstępnie wypełnij wpisy arp (pamiętaj o zastąpieniu adresów MAC, nie używaj moich):

ip route add 10.60.1.1 dev eth2
arp -i eth2 -s 10.60.1.1 00:1B:21:C1:F6:0F # eth3's mac address

ip route add 10.60.0.1 dev eth3 
arp -i eth3 -s 10.60.0.1 00:1B:21:C1:F6:0E # eth2's mac address

To oszukuje Linuksa na tyle, aby faktycznie umieścić pakiety na kablu. Na przykład:

ping 10.60.1.1

wychodzi eth2, źródłowy adres IP 10.50.0.1 otrzymuje NATted do 10.60.0.1, a jeśli chodzi o eth3, miejsce docelowe 10.60.1.1 dostaje NATted do 10.50.1.1. Odpowiedź ma podobną podróż.

Teraz użyj iperf do przetestowania przepustowości. Powiąż właściwe adresy IP i upewnij się, z którym adresem IP się kontaktujesz (fałszywy adres drugiego końca):

# server
./iperf -B 10.50.1.1 -s

# client: your destination is the other end's fake address
./iperf -B 10.50.0.1 -c 10.60.1.1 -t 60 -i 10

Upewnij się, że ruch naprawdę dociera do drutu:

tcpdump -nn -i eth2 -c 500

Możesz także oglądać / proc / przerywa, aby mieć absolutną pewność, że karta jest używana:

while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done

W każdym razie znalazłem ten post, szukając sposobu, jak to zrobić, dziękuję za pytania i mam nadzieję, że pomoże to każdemu znaleźć ten post w przyszłości.

Steve Kehlet
źródło
+1 Świetne rozwiązanie - to nawet nie wymaga aktywacji przekazywania IP! Właśnie tego potrzebowałem w tej chwili (do testowania 10 GB przez sprzężenie zwrotne).
Nils,
16

Jak zawsze - jestem trochę spóźniony - ale w dzisiejszych czasach można użyć sieciowych przestrzeni nazw, aby odizolować interfejsy i zapobiec lokalnemu przesyłaniu dalej (i majstrować przy iptables :)).

Utwórz przestrzenie nazw (wszystko odbywa się z wymaganymi uprawnieniami, np. Jako root):

ip netns add ns_server
ip netns add ns_client

Zauważ, że dostęp do statusu / konfiguracji interfejsów musi być teraz możliwy w kontekście przypisanej przestrzeni nazw - więc nie pojawią się one, jeśli uruchomisz odsłonięty link ip, ponieważ jest on uruchamiany w kontekście domyślnej przestrzeni nazw. Uruchomienie polecenia w przestrzeni nazw można wykonać za pomocą

ip netns exec <namespace-name> <command>

jako przedrostek.

Teraz przypisz przestrzenie nazw do interfejsów, zastosuj config i ustaw interfejsy w górę:

ip link set eth1 netns ns_server
ip netns exec ns_server ip addr add dev eth1 192.168.1.1/24
ip netns exec ns_server ip link set dev eth1 up
ip link set eth2 netns ns_client
ip netns exec ns_client ip addr add dev eth2 192.168.1.2/24
ip netns exec ns_client ip link set dev eth2 up

Teraz możesz uruchamiać aplikacje w przestrzeni nazw - dla uruchomienia serwera iperf

ip netns exec ns_server iperf -s -B 192.168.1.1

a klient:

ip netns exec ns_client iperf -c 192.168.1.1 -B 192.168.1.2

Ruch będzie teraz wysyłany przez interfejsy fizyczne, ponieważ cały stos sieci, interfejs, routing ... jest izolowany przez przestrzenie nazw, więc jądro nie jest w stanie dopasować adresów używanych w ruchu do lokalnych (dostępnych) interfejsów.

Jeśli zakończysz eksperymenty, po prostu usuń przestrzenie nazw:

ip netns del <namespace-name>

Interfejsy zostaną ponownie przypisane do domyślnej przestrzeni nazw, a cała konfiguracja wykonana w przestrzeni nazw zniknie (np. Nie trzeba usuwać przypisanych adresów IP).

Thomas Tannhäuser
źródło
Jest to o wiele prostsze niż sugerowana magia o podwójnym natarciu i nie wymaga żadnej koordynacji z innymi komputerami w sieci ani nie zakłada żadnej fizycznej topologii. Moim jedynym żądaniem byłoby dodanie poleceń w celu dodania tras.
Huckle
2

Ok, w końcu udało mi się skonfigurować moją konfigurację.

Chodzi o to, aby użyć innego fałszywego adresu, aby wymusić trasę tego fałszywego adresu do interfejsu 2, a następnie przetłumaczyć fałszywy adres na prawdziwy adres 2 za pomocą NAT / iptables.

Moja konfiguracja składa się z jednego routera, który mogę telnet między IF1 (interfejs 1) a IF2

W mojej konfiguracji FAKE_ADDR i IF1_ADDR są w tej samej podsieci.

ifconfig $IF1 $IF1_ADDR netmask 255.255.255.0
ifconfig $IF2 $IF2_ADDR netmask 255.255.255.0

iptables -t nat -A PREROUTING -d $FAKE_ADDR -i $IF2 -j DNAT --to-destination $IF2_ADDR
iptables -t nat -A POSTROUTING -s $IF2_ADDR -d $IF1_ADDR/24 -j SNAT --to-source $FAKE_ADDR

route add $FAKE_ADDR gw $ROUTER_ADDR

I na routerze:

route add $FAKE_ADDR gw $IF2_ADDR

Jeśli wyślę coś do FAKE_ADDR, pkt zostanie przesłane przez IF1 do routera, ponownie przesłane do IF2, wtedy FAKE_IP zostanie zastąpione przez IF2_ADDR. Pakiet jest przetwarzany przez serwer, wynik jest wysyłany z powrotem do IF1_ADDR, z IF2_ADDR, który jest zastępowany przez FAKE_ADDR.

Możliwe, że można zastosować prostszą konfigurację za pomocą tylko jednego kabla krosowego, ale ponieważ nie próbowałem, wolę podać moje działające rozwiązanie.

calandoa
źródło
jeśli router wysyła $ FAKE_ADDR na $ IF2_ADDR, to czy twoja reguła DNAT nie musi być „-i $ IF2” zamiast „-i $ IF1”?
cmcginty
Masz rację, Casey, poprawka wykonana.
calandoa
1

Odpowiedź udzielona powyżej przez Thomasa Tannhäusera była natychmiastowa!

Miałem podobną sytuację: pojedynczą maszynę z dwoma interfejsami enet. Mój plan polegał na użyciu jednego interfejsu jako serwera (odbiorcy), a drugiego jako klienta (nadawcy). Każdy interfejs byłby podłączony do routera, a iperf prowadziłby ruch przez router w celu pomiaru przepustowości, PPS, opóźnienia itp.

Niestety podejście iptables było nieintuicyjne i pełne problemów. Po kilku frustrujących godzinach porzuciłem ten plan ataku. Zainspirowany sugestią Thomasa odrobiłem pracę domową w przestrzeni nazw Linux IP i zacząłem doceniać prostotę i elegancję tego rozwiązania.

Poniżej znajduje się lista dokładnych poleceń, których użyłem do skonfigurowania mojej Fedory FC26, aby działała w tej roli. Dwa interfejsy to enp1s0 i enp3s0. Router ma dwa interfejsy o adresach 192.168.2.112 i 172.16.16.2. Każde złącze ENET FC26 jest podłączone bezpośrednio do odpowiedniego interfejsu routera.

# How to configure the IP Namespaces
ip netns add iperf-server
ip netns add iperf-client
ip link set enp1s0 netns iperf-server
ip link set enp3s0 netns iperf-client
ip netns exec iperf-server ip addr add dev enp1s0 192.168.2.139/20
ip netns exec iperf-client ip addr add dev enp3s0 172.16.16.2/24
ip netns exec iperf-client ip link set dev enp3s0 up
ip netns exec iperf-server ip link set dev enp1s0 up
ip netns exec iperf-server route add default gw 192.168.2.112
ip netns exec iperf-client route add default gw 172.16.16.1

# Test the interfaces and network using ping
ip netns exec iperf-client ping -c1 172.16.16.1
ip netns exec iperf-server ping -c1 192.168.2.112
ip netns exec iperf-server ping -c1 172.16.16.2
ip netns exec iperf-client ping -c1 192.168.2.139

# Start Iperf Server for UDP test
ip netns exec iperf-server iperf -u -s
# Run Client against Iperf server for UDP test
ip netns exec iperf-client iperf -u -c 192.168.2.139
RarkyMan
źródło
0

Wygląda na to, że chcesz zmienić swój system Linux w pole typu router / most / brama / zapora ogniowa. Następujące zasoby mogą być tym, czego szukasz:

Projekt routera Linux

Lista dystrybucji routera lub zapory

Linux LiveCD Router

Linux Journal - Router Linux

Aktualizacja na podstawie dalszych informacji:

Nie sądzę, żebyś mógł robić, co chcesz. System operacyjny zawsze patrzy na swoją wewnętrzną tabelę routingu i „widzi” oba adresy IP lokalnie. Następnie kieruje ruch w systemie operacyjnym i nigdy nie umieszcza go na kablu. Będziesz potrzebował drugiej maszyny lub dwóch maszyn wirtualnych (sprawdź Xen ).

Piotr
źródło
0

Wiele rzeczy do przejścia tutaj, więc nie mogę całkowicie zagwarantować mojej dokładności, ale pierwotne pytanie wydaje się szukać techniki znanej jako „wyślij do siebie” . Połączone wyszukiwanie pokazuje, co uważam za najlepiej utrzymaną łatkę jądra, jako górny link + dyskusje i łatki z innymi podejściami na różnych listach mailowych, szczególnie. LKML.

Myślę, że należy również spojrzeć na sieciowe przestrzenie nazw , wykonane za pomocą „ip netns” iproute2 . Wymaga to również dodatkowego interfejsu i magii routingu, więc może nie być nawet mniej skomplikowane niż masywna hoopla z iptables w innych odpowiedziach.

Komentarze na pewno są mile widziane, jeśli ktoś znajdzie coś przydatnego - jak, co, gdzie w Twojej implementacji.

lkraav
źródło
-1

oto jak to działa dla IPV6

przypisany statyczny Ips

/sbin/ifconfig eth1 inet6 add 2001:db8::1/127 
/sbin/ifconfig eth3 inet6 add 2001:db8::2/127 

skonfiguruj tylko trasy hosta do adresów „FAKE”

ip -6 route add 2001:db8::2/128 dev eth1 metric 1
ip -6 route add 2001:db8::1/128 dev eth3 metric 1

wypełnił tabelę Sąsiad ... jak arp

ip -6 neighbor add 2001:db8::1 lladdr 90:e2:ba:0d:75:e8 dev eth3 # eth1's mac address
ip -6 neighbor add 2001:db8::2 lladdr 90:e2:ba:0d:75:e9 dev eth1 # eth3's mac address

dodano wpisy ip6tables

ip6tables -t nat -A POSTROUTING -s 2001:db8::1 -d 2013::2 -j SNAT --to-source 2001:db8::1
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -j DNAT --to-destination 2001:db8::1
ip6tables -t nat -A POSTROUTING -s 2001:db8::2 -d 2013::1 -j SNAT --to-source 2001:db8::2
ip6tables -t nat -A PREROUTING -d 2001:db8::2 -j DNAT --to-destination 2001:db8::2
robm
źródło
Jakiej dystrybucji używasz? Kiedy ostatnio sprawdzałem, jądro nie ma tabeli NAT dla IPv6.
fukawi2,