Więc w twojej konfiguracji wszystkie pakiety, które próbujesz wysłać do sieci, początkowo pochodzące 10.0.0.1(ponieważ przechodzą przez tun0interfejs, a jego lokalny adres to 10.0.0.1). Przechwytujesz pakiety, na razie wszystko jest w porządku.
Teraz tun0wysyła pakiety dalej. Adres źródłowy to 10.0.0.1i chcesz, aby pakiety wychodziły przez inny interfejs ( wlp2s0w twoim przypadku). To jest routing, więc najpierw włączmy routing:
sysctl -w net.ipv4.ip_forward=1
Po tym, jeśli będziesz patrzeć tcpdumpna wlp2s0można zauważyć pakiety wyjechać z adresu źródłowego 10.0.0.1, a nie z adresem źródłowym wlan interfejsu (czego można się spodziewać chyba). Musimy więc zmienić adres źródłowy, który nazywa się źródłowym NAT . W Linuksie jest to łatwe przy pomocy netfilter / iptables :
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
Sprawdź także, czy Twój FORWARDłańcuch ma ACCEPTzasady, czy też musisz zezwolić na przekazywanie z następującymi elementami:
iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
Wszystko powinno działać teraz: jądro linuksa wykonuje routing, przenosi pakiety z tun0interfejsu do wlp2s0. netfilter powinien zmienić źródłowy adres IP 10.0.0.1na wlp2s0adres przypisany interfejsowi dla pakietów wyjściowych. Zapamiętuje wszystkie połączenia, a kiedy pakiety odpowiedzi wracają (jeśli są), zmienia adres docelowy wlp2s0interfejsu przypisanego do adresu 10.0.0.1(funkcja „conntrack”).
Powinno, ale tak nie jest. Wygląda na to, że netfilter myli się z tą skomplikowaną konfiguracją routingu i faktem, że ten sam pakiet najpierw przechodzi przez OUTPUTłańcuch, a następnie jest kierowany i dochodzi do PREROUTINGłańcucha. Przynajmniej w przypadku Debiana 8 nie działa.
Najlepszym sposobem na rozwiązanie problemu z filtrem sieciowym jest TRACEfunkcja:
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
Włączam śledzenie tylko pakietów ICMP, możesz użyć innego filtra do debugowania.
Pokaże, przez jakie tabele i łańcuchy przechodzi pakiet. Widzę, że pakiet nie przechodzi dalej przez FORWARDłańcuch (i nie jest przechwytywany przez nat/POSTROUTINGłańcuch, który faktycznie działa SNAT).
Poniżej znajduje się kilka podejść, aby to zadziałało.
PODEJŚCIE 1
Najlepszym sposobem na dezorientację netfiltra jest zmiana źródłowego adresu IP pakietów w tun0.caplikacji. To także najbardziej naturalny sposób. Musimy zmienić 10.0.0.1 na 10.0.0.2 w drodze powrotnej i 10.0.0.2 na 10.0.0.1 w drodze powrotnej.
Zmodyfikowałem za tun0.cpomocą kodu zmiany adresu źródłowego. Oto nowy plik i tutaj jest plik poprawek dla twojego tun0.c. Zmiany w nagłówku IP również wymagają korekty sumy kontrolnej , więc wziąłem trochę kodu z projektu OpenVPN . Oto pełna lista poleceń, które wykonuję po czystym ponownym uruchomieniu i tun0_changeip.curuchomieniu:
ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
Pamiętaj, że w takim przypadku nie musisz wyłączać filtrowania ścieżki zwrotnej , ponieważ wszystko jest legalne - tun0odbiera i wysyła tylko pakiety należące do jego podsieci. Możesz także wykonać routing oparty na źródłach zamiast na interfejsie.
PODEJŚCIE 2
Jest to możliwe, SNATzanim pakiet osiągnie tun0interfejs. Nie jest to jednak poprawne. W takim przypadku zdecydowanie musisz wyłączyć filtrowanie ścieżki zwrotnej :
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Teraz zrób SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT - do źródła ip.address.of.your.wlan.interface
Tutaj zmieniamy adres źródłowy tuż przed dotarciem pakietów do tun0urządzenia. tun0.ckod ponownie wysyła te pakiety „tak jak są” (ze zmienionym adresem źródłowym) i są one pomyślnie kierowane przez interfejs sieci WLAN. Ale możesz mieć dynamiczny adres IP na interfejsie WLAN i chcesz go użyć MASQUERADE(aby nie podawać jawnie adresu interfejsu). Oto jak możesz wykorzystać MASQUERADE:
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
Zwróć uwagę na 10.0.55.1adres IP „ ” - jest inny. Możesz tutaj użyć dowolnego adresu IP, to nie ma znaczenia. Pakiety osiągają nat/POSTROUTINGłańcuch wlp2s0interfejsu, jeśli wcześniej zmienimy źródłowy adres IP. A teraz nie jest zależny od statycznego adresu IP interfejsu wlan.
PODEJŚCIE 3
Możesz także użyć fwmark. W ten sposób nie trzeba SNATale można uchwycić tylko wychodzące pakiety:
Najpierw trzeba wyłączyć kanał zwrotny filtrowania dla tun0ponieważ będzie przekazywał pakiety, które należą do innej sieci:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John
# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John
To kolejny „hack” do routingu i netfiltra, który działa na moim pudełku Debiana 8, ale nadal zalecam pierwsze podejście, ponieważ jest bardziej naturalne i nie używa żadnych hacków.
Możesz również rozważyć zbudowanie aplikacji jako przejrzystego serwera proxy . Myślę, że byłoby to znacznie łatwiejsze niż analizowanie pakietów z urządzenia tun.
-j SNAT, nie-s SNAT