iptables --set-mark - Kieruj różne porty przez różne interfejsy


15

Krótka historia,
3 interfejsy, eth0 (LAN), eth1 (ADSL), eth2 (4G).
eth0 -> eth1: Działa
(porty 80, 443, 4070) eth0 -> eth2: Nie dzieje się


To jest graficzne przedstawienie pomysłu:

Port 80 i 443 przez eth2,
a reszta przez eth1
wprowadź opis zdjęcia tutaj

Netscheme:

eth0: -ip 10.0.0.1 -net 10.0.0.0/8 -gw 10.0.0.1 (the servers own intf) 
eth1: -ip 192.168.1.74 -net 192.168.1.0/24 -gw 192.168.1.254 
eth2: -ip 192.168.1.91 -net 192.168.0.0/24 -gw 192.168.0.1 






Myślę, że ten nowy skrypt przekierowuje 22 i 4070 do odpowiedniej tabeli.
Jednak po przejściu do tej tabeli nie jest przekierowywana do eth2.




Ten skrypt działa, z wyjątkiem 22 i 4070!

(Port 80 nie został skomentowany i działa, ale przez eth1, co jest złe)

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main

iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
###  iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254


echo "201 eth2.out" >> /etc/iproute2/rt_tables

ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1



## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE









Stary skrypt:


  Ignore everything below unless you're interested in retracing my steps!!




Utworzyłem skrypt router.sh, aby skonfigurować moje środowisko na wypadek, gdyby zrobiłem coś złego. Mam 3 porty, które chcę wysłać do połączenia 4G, a pozostałe za pośrednictwem stacjonarnego połączenia ADSL. Aby to zrobić, poinstruowałem iptables, aby zmieniały paczki na domyślnej trasie i wysyłały je przez mój interfejs 4G, jeśli --dport == 443 | 80 | 4070

To jednak nie działa; Nadal jestem prowadzony przez mój telefon stacjonarny, bez względu na wszystko.

Tak wygląda mój skrypt:

#!/bin/bash

## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl

## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254


## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80


## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

Próbowałem również dodać te 3 do dolnej części skryptu:

iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"

Próbowałem także bez powodzenia:

iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1

Na koniec wypróbowałem:

## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

Trasowanie działa, mogę przeglądać internet, słuchać muzyki i co nie, ale robię to za pomocą niewłaściwego interfejsu. Od dłuższego czasu googlowałem i znalazłem fragmenty, aby zrozumieć, co robię i dlaczego to robię. Mógłbym kształtować ruch poprzez tc, ale jeśli jest to możliwe poprzez oznaczanie pakietów w iptables, pomogłoby to mi na dłuższą metę.

Domyślam się, że źle wykonuję zamówienie na różnych zasadach, głównie w części MASQUERADE ? a jeśli to w ogóle powinno tam być?

Czy ktoś może wyjaśnić, w jaki sposób port DNAT może powiedzieć tcp: 80 z interfejsu zewnętrznego (jednego lub obu protokołów) do wewnętrznej przestrzeni adresowej 10.0.0.0?



Wyjścia:

root@Netbridge:~# route -n Kernel IP routing table Destination    

Gateway         Genmask         Flags Metric Ref    Use Iface<br>
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth1<br>
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0<br>
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2<br>
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1


root@Netbridge:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:4e  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0

eth1      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:58  
          inet addr:192.168.1.74  Bcast:192.168.1.255  Mask:255.255.255.0

eth2      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:62  
          inet addr:192.168.0.91  Bcast:192.168.0.255  Mask:255.255.255.0

Postępował zgodnie z tymi instrukcjami:
ruch wyjściowy na różnych interfejsach oparty na miejscu docelowym
iptables-forward-specific-port-to-specific-nic
Wśród kilku innych powiązanych wątków.


Przykro mi, ale czy istnieje powód, aby nie wiązać apache tylko localhostz adresem i adresem eth2interfejsu?
Jan Marek

@JanMarek: Nie ma tu mowy o apaczu. A dla twojej informacji, powiązanie gniazda na ethXadresie IP uniemożliwi hostom w sieci ethXLAN dostęp do lokalnego serwera za pomocą ethYadresu IP i nie uniemożliwi hostom ethYdostępu do serwera za pomocą ethXadresu IP. Pamiętaj, że Linux używa słabego modelu hosta.
BatchyX,

OK, jest możliwe więcej serwerów WWW, nie tylko serwer Apache ... Myślę, że ten serwer WWW z interfejsem eth2 może być prostym rozwiązaniem. Ale mogę się mylić, wiem.
Jan Marek

Odpowiedzi:


6

BatchyX już bardzo dobrze wyjaśnia iptables i routing, więc wykorzystam swoje lenistwo i przejdę bezpośrednio do skryptu.

Powinien NAT cały ruch do portu 80,443,22,4070 do 192.168.0.91. Cała reszta będzie NAT przez 192.168.1.254.

Ponownie przeprowadzam testy i kończę zgodnie z tym przewodnikiem . W tym przewodniku brakuje 3 ostatnich wierszy mojego skryptu. O czym dowiedziałem się z innego portu, ale straciłem kontakt z tym linkiem.

Jest to sprawdzony skrypt roboczy.

Potrzebujesz domyślnej trasy

Jedną rzeczą, której nie umieściłem w skrypcie, jest ustawienie domyślnej trasy. Powinno być

route add default gw 192.168.1.254

Gdy to zrobisz route -n, powinna to być jedyna domyślna trasa (Dest: 0.0.0.0)

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1

fw-router.sh

# Reset / Flush iptables
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P AKCEPTACJA WEJŚCIA
iptables -P FORCEARD ACCEPT
iptables -P AKCEPTACJA WYJŚCIA

# Reset / Flush / Setup IP Route (tabela 4)
Tabela spłukiwania ip route 4
ip route show table main | grep -Ev ^ default | podczas czytania TRASA; do ip route dodaj tabelę 4 $ ROUTE; gotowy
ip route add table 4 default via 192.168.0.1

#Zaznacz pakiet z pasującym D.Port
iptables -t mangle -A PREROUTING -p tcp --port 22 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --port 80 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --port 443 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --port 4070 -s 10.0.0.0/24 -j MARK --set-mark 4

#SNAT Rules
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.1.74
iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source 192.168.0.91

#IP Route
reguła ip dodaj fwmark 4 tabela 4
pamięć podręczna opróżniania trasy IP

Stos #IP
# To jest brakująca część przewodnika
echo 1> / proc / sys / net / ipv4 / ip_forward
dla f w / proc / sys / net / ipv4 / conf / * / rp_filter; wykonaj echo 0> $ f; gotowy
echo 0> / proc / sys / net / ipv4 / route / flush

PS1: Krótko mówiąc, MASQUERADEnie działa (w większości przypadków, a zdecydowanie w twoim przypadku) dla NAT z wieloma zewnętrznymi adresami IP, które wymagają pewnego rodzaju równoważenia obciążenia lub DNAT do obsługi ruchu przychodzącego. Potrzebujesz SNATkontroli kierunku.

PS2: Czyste iptables nie są wystarczające.


Przede wszystkim pozdrawiam, że przechodzę bezpośrednio do skryptu :) Spróbuję tego wieczoru, gdy wrócę do środowiska, w którym będzie działać!
Torxed,

hmm, może wymagać ciężkiej korekty. Daj mi znać wynik.
John Siu,

Zmieniony, powinien już działać.
John Siu,

Słodko, skontaktuje się z Tobą w krótkim czasie: D
Torxed 21.12.12

Kocham cię, tyle bólu głowy, a ty go rozwiązałeś! Dziękuję Ci!
Torxed,

6

Uwaga: Rozważyłem tylko pierwszy skrypt, ignorując stary.

  • Nie musisz ręcznie modyfikować modułów netfilter za pomocą aktualnych iptables. Jest to konieczne tylko w przypadku niestandardowych modułów do śledzenia połączeń.
  • Nie mieszaj routei ip route. To jest czyste zło. Po prostu używaj ipwszędzie i zapomnij o ifconfigiroute
  • /etc/iproute2/rt_tablesnie resetuje się po ponownym uruchomieniu. Ciągłe dołączanie tego samego wpisu nie jest dobrym pomysłem, wystarczy zrobić to tylko raz. Pamiętaj, że rt_tableswystarczy zdefiniować aliasy nazw na wartości liczbowe, nie zmieni to żadnej konfiguracji.

  • Teraz dla iptables: W swoim FORWARDłańcuchu upuszczasz pakiety przychodzące z sieci LAN do 4G. To jest złe. FORWARDhak jest stosowany po routingu jest wykonywana. W tym momencie wszystkie routing zasad jest wykonywany i już wiadomo, czy pakiet powinien zostać wysłany do 4G czy ADSL. Zmiana trasy nie jest wykonywana w FORWARDani później FORWARD(cóż, technicznie, zmiana trasy może być wykonana POSTROUTINGw ciężkich przypadkach, ale wracając do sedna).

Teraz twój routing: pamiętaj, że Ubuntu domyślnie włącza filtrowanie ścieżek zwrotnych. Filtrowanie ścieżki zwrotnej działa w następujący sposób: Kiedy jądro odbierze pakiet (może być przekazany lub nie) z interfejsu A, odwróci adres źródłowy i adres docelowy oraz sprawdzi, czy wynikowy pakiet powinien zostać przekierowany przez interfejs A. Jeśli tak nie jest, pakiet jest odrzucany jako próba fałszowania adresu.

W przypadku pakietów otrzymanych od eth0nie stanowi to problemu. W przypadku pakietów otrzymanych z eth1nie stanowi to również problemu, ponieważ podczas odwracania źródłowego adresu IP i docelowego adresu IP jądro będzie domyślną trasą w tabeli main. W przypadku pakietów otrzymanych od eth2, których nie zaznaczasz, jest to problem, ponieważ jądro uderzy w domyślną trasę w tabeli maini uzna, że ​​pakiety te powinny były zostać odebrane eth1. Najłatwiejszym rozwiązaniem jest wyłączenie filtrowania ścieżki zwrotnej w eth1:

sysctl -w net.ipv4.conf.eth1.rp_filter=0

Wszystkie świetne komentarze i tak, z mojej strony jest trochę błędna logika, na przykład dołączanie do rt_tables za każdym razem, a zwłaszcza nie czyszczenie niektórych tabel tak dobrze, jak powinienem, ale się tam dostanę :) Dam wszystko i zobaczę jeśli to działa, jeśli tak, to +50 dla ciebie, a co najważniejsze, uratowałeś mansa przed pocięciem na kawałki i pokoje! :)
Torxed

1
Poniższy skrypt działa, ale pan również zasługuje na wdzięczność, daliście mi kilka rzeczy do przemyślenia, a rp_filter = 0 pomógł mi daleko! : D
Torxed,

@BatchyX bardzo pouczające, głosuj też na ciebie.
John Siu,

@ Torxed Post, który widziałem wspominając rp_filter dla WSZYSTKIEGO interfejsu, musi być wyłączony. Nie jestem pewien, czy to działa w inny sposób.
John Siu,

@JohnSiu: Musisz tylko wyłączyć filtr RP na interfejsach, na których jest problematyczny. W takim przypadku jest to eth1, ponieważ nie ma trasy prowadzącej do tego interfejsu, gdy znaki nie są ustawione. eth2 nie ma takiego problemu, ponieważ domyślna trasa przechodzi do tego interfejsu. W przypadku eth0 przydatne jest utrzymywanie włączonego filtru rp, w przeciwnym razie ktoś w sieci LAN mógłby sfałszować pakiet IP z adresem źródłowym w Internecie i adresem docelowym w sieci LAN, a router chętnie go zaakceptuje i przekaże dalej wróć do ... eth0.
BatchyX,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.