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.