NAT 1: 1 z kilkoma identycznymi sieciami LAN

13

Chcę podłączyć kilka sieci LAN znajdujących się na odległych budynkach.
Witryna „centralna” ma komputer z systemem Linux i OpenVPN. Na każdej zdalnej stronie działa również OpenVPN.

  1. strona centralna ma sieć LAN o numerze 192.168.0.0/24
  2. kilka zdalnych stron jest również ponumerowanych 192.168.0.0/24
  3. Nie mogę / nie chcę / nie chcę / cokolwiek modyfikować numeracji LAN
  4. Nie mam kontroli nad większością zdalnych OpenVPN

Następnie muszę:
1. zdefiniować wirtualne sieci LAN
2. skonfigurować NAT 1: 1 dla każdej witryny
3. NAT 1: 1 należy skonfigurować na centralnym routerze

Mapa LAN .
Tak więc każda witryna ma sieć LAN 10.10.x.0 / 24.
Gdy komputer chce dotrzeć, powiedzmy, 192.168.0.44 na stronie 12, wystarczy wysłać paquet na 10.10.12.44

Obsługa VPN nie stanowi dla mnie problemu. Obecnie łączę ponad 60 witryn. Ale nie znajduję prostego sposobu na zrobienie tego NAT 1: 1.

Oto przykład pakietu wysłanego z witryny centralnej do witryny zdalnej i jego pakietu odpowiedzi:

wprowadź opis zdjęcia tutaj

Zrobiłem kilka testów z iptables NETMAP, ale nie mogę sprawić, aby działało, ponieważ nie znajduję sposobu na modyfikację źródła + miejsca docelowego po decyzji o routingu.
Wolę unikać nowej --client-natfunkcji OpenVPN.
Może muszę wymusić routing ip route? A może dwukrotnie zapętlić w stos sieciowy veth?

Uwaga: nie chcę używać maskarady. Tylko 1/1 NAT.

EDYCJA:
Nie jest to możliwe przy regularnej konfiguracji openVPN. Ponieważ pakiet ze zdalnej strony jest nierozróżnialny od pakietu z innej strony: oba mają podobne adresy źródłowe i docelowe, a oba pochodzą z tego samego interfejsu tun (lub tap). Więc nie jest możliwe, aby go pobrać.

Rozwiązanie 1: wykonaj translację NAT na zdalnych stronach. W moim przypadku niemożliwe. Muszę to zrobić tylko na stronie centralnej.

Rozwiązanie 2: skonfiguruj jedną sieć VPN dla każdej zdalnej witryny. Więc mam jeden tun dla każdego. Myślę, że to może być w porządku. Niezbyt wydajna pamięć, ale w porządku.

Rozwiązanie 3: skonfiguruj (niezaszyfrowany) tunel w sieci VPN dla każdej witryny. To da jeden interfejs dla każdego. Proste tunele nie są wieloplatformowe (ku memu knoledge). Na przykład GRE, ipip lub sit są w porządku dla Linuksa, ale na niektórych odległych stronach działa tylko jeden komputer z Windows, więc jest na nim zainstalowany openVPN. Tak niemożliwe jest ustawienie prostego tunelu. Inną opcją jest użycie bardziej skomplikowanego tunelu (który?), Ale narzut w systemie i na sysadminie może być większy niż w przypadku posiadania wielu sieci VPN

Rozwiązanie 4: skompiluj najnowszy openVPN, ponieważ zawiera on funkcję NAT 1: 1. Testuję w tym tygodniu.

Bertrand SCHITS
źródło
1
Dla rozwiązania 4 nie musisz kompilować. Większość głównych dystrybucji Linuksa skompilowała pakiety na oficjalnej stronie openVPN. Ale to nie zadziała, ponieważ opcja --client-nat to opcja, którą można wypychać. Więc twoi klienci muszą również używać najnowszej wersji RC (i mówisz, że nie masz kontroli nad zdalnymi witrynami).
Gregory MOUSSAT,
1
Cóż, mylę się: funkcja --client-nat jest w 100% w OpenVPN (myślałem, że używa ipfilter). Właśnie przetestowałem: działa również w systemie Windows. Zobacz moje rozwiązanie poniżej.
Gregory MOUSSAT,
Chciałbym wiedzieć, czy kiedykolwiek działało to i co zrobiłeś.
Michael Grant,

Odpowiedzi:

2

Bardzo podstawowym rozwiązaniem jest:
1. użyj OpenVPN 2.3 lub więcej (obecnie najnowsza wersja to 2.3-alpha) dla serwerów + klientów
2. użyj opcji konfiguracji OpenVPN poniżej
3. nie używaj niczego innego (bez ipfilter, żadnych sztuczek)

Po stronie serwera musisz ręcznie dystrybuować adresy VPN (więc nie ma serveropcji, musisz użyć ifconfiglub ifconfig-push):

# /etc/openvpn/server.conf
ifconfig 10.99.99.1 10.99.99.2
route 10.99.99.0 255.255.255.0
push "route 10.99.99.0 255.255.255.0"
push "client-nat dnat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat dnat 10.99.99.12 255.255.255.255 10.10.112.12"
push "client-nat dnat 10.99.99.13 255.255.255.255 10.10.113.13"

routeI push routei client-natlinie są wymagane, jeśli chcesz komunikować się bezpośrednio między routerami ( ping 10.99.99.1z odległym miejscu przechadzkę VPN). W przeciwnym razie możesz je odrzucić.

.

.

Teraz musisz wybrać wirtualny adres sieciowy. Zachowałem to samo, co w przykładzie: 10.10.0.0/16 Zezwalasz
na routing w tym celu:

# /etc/openvpn/server.conf
route 10.10.0.0 255.255.0.0
push "route 10.10.0.0   255.255.0.0"

.

.

Musisz teraz poinstruować klienta, aby używał NAT 1: 1:

# /etc/openvpn/ccd/client_11
ifconfig-push 10.99.99.11 10.99.99.1
push "client-nat snat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat snat 192.168.0.0 255.255.255.0 10.10.11.0"
push "client-nat dnat 10.10.10.0 255.255.255.0 192.168.0.0"
iroute 10.10.11.0 255.255.255.0
iroute 10.10.111.0 255.255.255.0

W pierwszym wierszu ustaw adres routera zdalnego. Uwaga na sterownik Windows wymagający specjalnych adresów.
Druga i ostatnia linia pozwalają odległemu routerowi komunikować się z jego interfejsu 10.99.99.x.
Trzecia i czwarta linia zawierają źródłowy i docelowy NAT 1: 1
Piąty wiersz mówi OpenVPN, co zrobić z odpowiednimi pakietami.

Ta metoda pozwala łączyć witryny z identycznymi (lub nie) adresami LAN, bez hostowania w tle.

Gregory MOUSSAT
źródło
1
Proste, genialne.
Bertrand SCHITS,
Próbowałem tego, ale nie udało mi się go uruchomić. Korzystam z systemu Linux po obu stronach. Coś jest dziwnego lub czegoś nie rozumiem w pełni. Twój ifconfig-push w pliku client_11 (pierwszy wiersz), czy nie powinna to być maska ​​sieci dla drugiego argumentu zamiast 10.99.99.1? Po drugie, dlaczego korzystasz z tej trzeciej sieci 10.10.111.0/24? Wygląda na to, że próbujesz użyć sieci 111 do komunikacji między stronami. Czy nie można bezpośrednio użyć sieci 10.10? Wreszcie, bez względu na to, co próbuję, nie widzę (w tcpdump) snat i dnat wpływających na pakiety na kliencie.
Michael Grant,
Nie bardzo proste, ale wciąż genialne.
Neurotransmitter
4

Zrobiłem coś podobnego z prawdziwymi interfejsami, ale nie rozumiem, dlaczego to nie działa z interfejsami VPN.

Chodzi o to, że ponieważ masz tę samą podsieć dostępną w różnych interfejsach na tym routerze, komplikuje to routing. Zasadniczo, gdy pakiet dla 10.10.13.123 wchodzi do routera, jest on DNATed przed routingiem do 192.168.0.123, więc musisz być w stanie powiedzieć routingowi, że był przeznaczony dla 192.168.0.123 na interfejsie VPN13 .

Można to zrobić za pomocą znaków zapory i reguł routingu korzystających z tych znaków. SNAT i DNAT należy wykonać przy użyciu zapory sieciowej NETMAP. W przypadku SNAT jest to ten sam problem, w POSTROUTINGU straciłeś informacje, że pakiet pochodzi z tego lub innego interfejsu i wszystkie one mają adres źródłowy 192.168.0.x. Potrzebujesz więc znaku, aby przenosić te informacje - od PREZENTACJI do maglera, po PREZENTACJĘ nat. Możesz użyć tego samego znaku, ale wtedy oznaczałoby to, że te pakiety korzystałyby z tej alternatywnej tabeli routingu, więc musisz zduplikować globalną tabelę routingu.

Dla każdej sieci zrobiłbyś:

lnet=192.168.0.0/24
if10=eth0 if11=tun0 if12=tun1 if13=tun2

n=0
for site in 10 11 12 13; do
  table=$site
  net=10.10.$site.0/24
  n=$(($n + 1))
  eval "interface=\$if$site"
  inmark=$(($n * 2)) outmark=$(($n * 2 + 1))

  iptables -t nat -A PREROUTING -d "$net" -j NETMAP --to "$lnet"
  iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -m mark --mark "$inmark"/0xf -j NETMAP --to "$net"
  iptables -t mangle -A PREROUTING -i "$interface" -j MARK --set-mark "$inmark"/0xf
  iptables -t mangle -A PREROUTING -d "$net" -j MARK --set-mark "$outmark"/0xf
  ip rule add fwmark "$outmark"/0xf table "$table"
  ip route add "$lnet" dev "$interface" table "$table"
done

Powyżej używamy pierwszych 4 bitów znaku , aby umożliwić routing do 7 sieci w ten sposób.

Stéphane Chazelas
źródło
1
Dziękuję za odpowiedź. Testowałem to, ale to nie działa. Testowałem tylko z jedną siecią LAN, bez rezultatu. Używam tcpdump do monitorowania pakietów, a kiedy wysyłam pakiet ze strony zdalnej do strony centralnej, nawet nic nie widzę (?! Jak to możliwe?). Z twoimi wskazówkami staram się konstruować odpowiedź krok po kroku. Nie jestem pewien, czy mi się uda.
Bertrand SCHITS,
2
Moja odpowiedź dotyczy tylko tego, co robić na stronie centralnej. Zakładam, że poprawnie konfigurujesz routing w innych witrynach. Na przykład prawdopodobnie musisz dodać trasę do 10.10.0.0/16 przez tunel VPN na zdalnych stronach. Być może będziesz musiał powiedzieć openvpn, aby przepuścił te pakiety. W skrócie, używając tcpdump, aby zobaczyć, które pakiety docierają gdzie i jak właściwe podejście. cel LOG iptables jest także twoim przyjacielem.
Stéphane Chazelas,
2
Jeśli nie widzisz żadnych pakietów, musisz zajrzeć do dziennika openvpn. Prawdopodobnie znajdziesz upuszczone pakiety. W takim przypadku należy użyć „iroute 192.168.0.0 255.255.255.0” dla każdego klienta w
katalogu