Wyjściowy ruch na różnych interfejsach na podstawie portu docelowego

23

Moje pytanie jest w zasadzie takie samo, jak zezwalaj tylko na określony ruch wychodzący na niektórych interfejsach .

Mam dwa interfejsy eth1(10.0.0.2) i wlan0(192.168.0.2). Moja domyślna trasa to eth1. Powiedzmy, że chcę przejść przez cały ruch https wlan0. Teraz, jeśli użyję rozwiązania sugerowanego w drugim pytaniu, ruch https przejdzie wlan0, ale nadal będzie miał adres źródłowy eth1(10.0.0.2). Ponieważ ten adres nie jest dostępny dla wlan0bramy, odpowiedzi nigdy nie wrócą. Najłatwiejszym sposobem byłoby prawidłowe ustawienie add-binda w aplikacji, ale w tym przypadku nie ma to zastosowania.

Myślę, że muszę przepisać src-addr:

# first mark it so that iproute can route it through wlan0
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2

Teraz tcpdump widzi, że wychodzące pakiety są w porządku, a pakiety przychodzące docierają do 192.168.0.2, jednak prawdopodobnie nigdy nie kończą się w aplikacji, ponieważ wszystko, co kiedykolwiek widzę, to to, że aplikacja wysyła ponownie pakiet SYN, chociaż SYN- ACK zostało już odebrane.

Pomyślałem więc, że może też muszę przepisać adres przychodzący:

iptables -A PREROUTING -t nat -i wlan0 -p tcp --sport 443 -j DNAT --to 10.0.0.2

ale to też nie działało. Więc utknąłem tutaj. Jakieś sugestie?

Rumpel
źródło

Odpowiedzi:

24

Jesteś blisko

Rzeczywisty powód, dla którego aplikacja nie widzi ruchu powrotnego, wynika z wbudowanej w jądro ochrony przed fałszowaniem adresów IP. Tzn. Ruch powrotny nie jest zgodny z tabelą routingu i dlatego jest odrzucany. Możesz to naprawić, wyłączając ochronę przed fałszowaniem:

sudo sysctl net.ipv4.conf.wlan0.rp_filter=0

Ale nie poleciłbym tego. Bardziej właściwym sposobem jest utworzenie alternatywnej instancji routingu.

  1. Znak jest konieczny. Zatrzymaj to.
  2. Źródłowy NAT jest również niezbędny.
  3. Końcowa DNAT jest niepotrzebna, więc możesz ją usunąć.

Upewnij się, że masz iproutezainstalowany pakiet. Jeśli masz ippolecenie, oznacza to, że jesteś ustawiony (co wygląda na to, że tak, ale jeśli nie, to najpierw).

Edytuj /etc/iproute2/rt_tablesi dodaj nową tabelę, dodając następujący wiersz:

200 wlan-route

Następnie musisz skonfigurować nową tabelę routingu o nazwie wlan-routez domyślną bramą i utworzyć reguły warunkowo wysyłające ruch do tej tabeli. Zakładam, że twoja domyślna brama to 192.168.0.1. Oczywiście musi to pasować do Twojej rzeczywistej sieci, a nie tylko moich założeń.

ip route add default via 192.168.0.1 dev wlan0 table wlan-route
ip rule add fwmark 0x1 table wlan-route

Twój końcowy skrypt z adnotacjami wyglądałby tak:

# Populate secondary routing table
ip route add default via 192.168.0.1 dev wlan0 table wlan-route
# Anything with this fwmark will use the secondary routing table
ip rule add fwmark 0x1 table wlan-route
# Mark these packets so that iproute can route it through wlan-route
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2
bahamat
źródło
Dziękujemy za poświęcenie czasu na przyjrzenie się temu. Jednak tego już używałem (jak opisano w drugim pytaniu), więc mam skonfigurowaną dodatkową trasę, ale nadal jest taka sama. SYN-ACK wracają do 192.168.0.2, ale najwyraźniej nigdy nie docierają do aplikacji.
rumpel
Wróć i przeczytaj moją odpowiedź jeszcze raz. Zwróciłem się z tym.
bahamat
Część o ochronie przed fałszowaniem? Bez zmian nawet po próbie. Przepraszam, przeczytaj kilka razy tam iz powrotem, ale jeszcze nie dostałem tego, czego mi brakuje.
rumpel
Musisz dodać srcopcję do ip routepoleceń, aby określić poprawny adres źródłowy.
David Schwartz,
@DavidSchwartz: POSTROUTING SNATzajmie się tym.
bahamat
8

rozwiązanie Bahamata jest poprawne; Proszę jednak zauważyć, że jedynym sposobem na wykonanie tej pracy było wyłączenie rp_filter dla każdego interfejsu w systemie, nie tylko dwóch (w tym przypadku eth1 i wlan0) zaangażowanych w NATing.

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
echo 1 > /proc/sys/net/ipv4/route/flush

(patrz WAŻNA uwaga na końcu tej strony: Advanced Routing Howto - zamieszczony tam link już nie istnieje, ale znalazłem go przez maszynę powrotną)

Davide C.
źródło
Dzięki za te odpowiedzi, ja również mogłem uzyskać rozwiązanie bahamatów działające, biorąc pod uwagę twoją odpowiedź.
Dynalon
dla mnie na dość standardowym polu ubuntu 12.04 LTS, oprócz wyłączenia rp_filter i opróżnienia pamięci podręcznej tras musiałem również usunąć nazwę interfejsu z argumentów iptables. nie miał wystarczająco dużo czasu, aby dowiedzieć się, dlaczego.
Costin Gușă
0

Jedna sugestia: zawsze należy używać --sportzamiast --dportw łańcuchu wyjściowym.

NAT zmieniają dporti to sprawi, że twoja reguła będzie niewykonalna.

użytkownik73451
źródło
2
Czy jest coś, czego nie dostaję? Dport, podobnie jak w porcie docelowym, nie może się zmienić. Jest to port usługi, do której próbuje dotrzeć sesja, np. Http, ssh, smtp. Albo pomyliłeś sport i dport, albo brakuje mi czegoś oczywistego. : P
Ktoś
0

Myślę, że potrzebna jest poniżej:

ip ru add from 192.168.0.2 table 3 prio 300
ip ro add table 3 default via 192.168.0.1 dev wlan0
użytkownik181234
źródło