Odpowiedz na tym samym interfejsie co przychodzący?

51

Mam system z dwoma interfejsami. Oba interfejsy są połączone z Internetem. Jeden z nich jest ustawiony jako domyślna trasa; efektem ubocznym jest to, że jeśli pakiet wejdzie na interfejs trasy innej niż domyślna, odpowiedź zostanie odesłana przez domyślny interfejs trasy. Czy istnieje sposób użycia iptables (lub czegoś innego) do śledzenia połączenia i wysłania odpowiedzi z powrotem przez interfejs, z którego pochodzi?

Shawn J. Goff
źródło

Odpowiedzi:

61
echo 200 isp2 >> /etc/iproute2/rt_tables
ip rule add from <interface_IP> dev <interface> table isp2
ip route add default via <gateway_IP> dev <interface> table isp2

Powyższe nie wymaga oznaczania pakietów za pomocą ipfilter. Działa, ponieważ wychodzące pakiety (odpowiedzi) będą miały adres IP, który był pierwotnie używany do łączenia się z drugim interfejsem jako adres źródłowy (z) w pakiecie wychodzącym.

Piotr
źródło
7
Wow, właśnie tego szukałem. W przypadku, gdy ktoś szuka, dla dystrybucji opartych na RH, możesz umieścić odpowiednie reguły i polecenia trasy w plikach o nazwach „reguły-eth0” lub „trasy-eth0” (na przykład), które zostaną dodane lub usunięte w ifup / ifdown. Umieść te pliki obok pliku ifcfg-eth0. W przypadku IPv6 wbudowana jest funkcja „route6-eth0”, ale (jeszcze) brak wbudowanej „reguły 6-eth0”.
Kyle Brantley,
18
Dla mnie zadziałało to tylko wtedy, gdy devip ruleip rule add from <interface_IP> table isp2
pominąłem
2
Możesz je utworzyć, gdy interfejs wzrośnie, dodając up ip rule add from <interface_IP> table isp2i up ip route add default via <gateway_IP> dev ppp0 table isp2do / etc / network / interfaces w ramach odpowiedniego interfejsu.
Oprawa
4
Musiałem usunąć dev <interface>z ip rule, aby działał na moim pudełku. Jeśli dobrze rozumiem, dev <interface>odfiltrowywałem pakiety, które były w jakiś sposób ustawione na niewłaściwym interfejsie, które musiały zostać przejęte do właściwego interfejsu przez przesłoniętą trasę, ale reguła filtrowania według interfejsu zapobiegała temu.
binki
2
Podobnie jak większość innych ludzi, musiałem usunąć dev <interface>z ip rulepoleceniem, aby to zadziałało. Zaktualizuj odpowiedź! Poza tym szczegółem działało to jak urok. Wielkie dzięki, @Peter!
MoonSweep
6

Poniższe polecenia tworzą alternatywną tabelę routingu eth1dla pakietów, które mają znak 1 (z wyjątkiem pakietów do hosta lokalnego). ipKomenda jest od iproute2 suite (Ubuntu: iproute Install iproute http://bit.ly/software-small , iproute-doc Install iproute-doc http://bit.ly/software-small ).

ip rule add fwmark 1 table 1
ip route add 127.0.0.0/0 table 1 dev lo
ip route add 0.0.0.0/0 table 1 dev eth1

Druga połowa zadania polega na rozpoznawaniu pakietów, które muszą uzyskać znak 1; następnie użyj iptables -t mangle -A OUTPUT … -j MARK --set-mark 1tych pakietów, aby zostały przekierowane przez tabelę routingu 1. Myślę, że następujące czynności powinny to zrobić (zastąp 1.2.3.4 adresem interfejsu trasy innej niż domyślna):

iptables -t mangle -A OUTPUT -m conntrack --ctorigdst 1.2.3.4 -j MARK --set-mark 1

Nie jestem pewien, czy to wystarczy, być może potrzebna jest kolejna reguła dla przychodzących pakietów, aby powiedzieć modułowi conntrack, aby je śledził.

Gilles „SO- przestań być zły”
źródło
Miły. Zapomniałem o znakowaniu. To powinno mnie tam zabrać.
Shawn J. Goff,
5

Miałem problemy z lokalnie generowanymi pakietami z rozwiązaniem sugerowanym przez Petera, stwierdziłem, że następujące poprawia to:

echo 200 isp2 >> /etc/iproute2/rt_tables
ip rule add from <interface_IP> table isp2 priority 900
ip rule add from dev <interface> table isp2 priority 1000
ip route add default via <gateway_IP> dev <interface> table isp2
ip route add <interface_prefix> dev <interface> proto static scope link src <interface_IP> table isp2

UWAGA: Możesz napotkać problemy ze składnią czwartej linii powyżej. W takich przypadkach składnia czwartego polecenia może być następująca:

ip rule add iif <interface> table isp2 priority 1000
Héctor Sánchez
źródło
Próbowałem tyle, ale nic nie działało w moim scenariuszu, z wyjątkiem tego… wielkie dzięki.
agaggi
3

Zakładam, że używasz Linuksa, a ponadto korzystasz z dystrybucji opartej na RedHat / CentOS. Inne Uniksy i dystrybucje będą wymagały podobnych kroków - ale szczegóły będą inne.


Zacznij od przetestowania (zauważ, że jest to bardzo podobne do odpowiedzi @ Peter. Zakładam, że:

  • eno0 to isp0 i ma ogólną domyślną bramę
  • eno1 to isp1 i ma adres IP / zakres 192.168.1.2/24 z bramą 192.168.1.1

Polecenia są następujące:

$ echo 200 isp1 >> /etc/iproute2/rt_tables
$ ip rule add from eno1 table isp1
$ ip route add default via 192.168.1.1 dev eno1 table isp1

Zapora ogniowa nie jest w żaden sposób zaangażowana. Pakiety odpowiedzi zawsze były wysyłane z właściwego adresu IP, ale wcześniej były wysyłane za pomocą niewłaściwego interfejsu. Teraz te pakiety z poprawnego adresu IP będą wysyłane za pośrednictwem odpowiedniego interfejsu.


Zakładając, że powyższe zadziałało, możesz teraz wprowadzić trwałe zmiany reguły i trasy. Zależy to od używanej wersji Uniksa. Tak jak poprzednio, zakładam dystrybucję Linuksa opartą na RH / CentOS.

$ echo "from eno1 table isp1" > /etc/sysconfig/network-scripts/rule-eno1
$ echo "default via 192.168.1.1 dev eno1 table isp1" > /etc/sysconfig/network-scripts/route-eno1

Sprawdź, czy zmiana sieci jest trwała:

$ ifdown eno1 ; ifup eno1

Jeśli to nie zadziała, w późniejszych wersjach RH / CentOS musisz także skorzystać z jednej z dwóch opcji:

  • Nie używaj domyślnego NetworkManager.service ; Zamiast tego użyj network.service . Nie zbadałem dokładnych kroków niezbędnych do tego. Mogę sobie wyobrazić, że obejmuje standardową chkconfig lub systemctl nakazuje, aby włączyć / wyłączyć usługi.
  • Zainstaluj pakiet NetworkManager-dispatcher-routing-rules

Osobiście wolę instalować pakiet reguł, ponieważ jest to prostsze i bardziej obsługiwane podejście:

$ yum install NetworkManager-dispatcher-routing-rules

Innym silnym zaleceniem jest włączenie filtrowania arp, ponieważ zapobiega to innym powiązanym problemom z podwójnymi konfiguracjami sieci. Za pomocą RH / CentOS dodaj następującą zawartość do pliku /etc/sysctl.conf:

net.ipv4.conf.default.arp_filter=1
net.ipv4.conf.all.arp_filter=1
zaTricky
źródło