Dostęp do serwera sieciowego DNAT'ted z sieci LAN

12

Mam małą sieć z routerem, który utrzymuje połączenie z Internetem, serwerem i niektórymi stacjami roboczymi w sieci lokalnej.

Mapa sieci

Serwer powinien być dostępny z Internetu, aw routerze iptables ustawiono kilka wpisów DNAT, takich jak:

-A PREROUTING -i ppp0 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10

Pakiety zewnętrzne przychodzą do routera przez ppp0interfejs, a pakiety wewnętrzne z br-lan, które faktycznie obejmują przełącznik i adapter WLAN. Problem polega na tym, że podczas gdy dostęp zewnętrzny działa dobrze, próba uzyskania dostępu do serwera z sieci LAN za pomocą zewnętrznego adresu IP rozpoznanego przez DNS (przypisanego ppp0) kończy się niepowodzeniem.

Jedynym rozwiązaniem, które udało mi się wymyślić, jest dodanie statycznych wpisów do routera /etc/hostswskazujących na wewnętrzny adres IP, ale ponieważ nie ma symboli wieloznacznych (i mam co najmniej trzy domeny najwyższego poziomu przypisane do tego systemu, nie licząc dziesiątek subdomen), to raczej chrupiące i podatne na awarie. Czy możesz zasugerować coś lepszego?

Znalazłem tylko to pytanie , które nie było zbyt pomocne.

Jeśli to istotne, router działa z OpenWRT 10.03 Kamikaze z dnsmasq.

Whitequark
źródło
Jaka wersja OpenWRT?
Corey S.,
@Corey 10.03 Stabilny, ale to nie ma nic wspólnego z samym openwrt, prawda?
whitequark

Odpowiedzi:

3

Dziwi mnie, że po prawie 8 latach nikt nie wyjaśnił, jak to zrobić poprawnie, używając systemu konfiguracji UCI używanego domyślnie w OpenWRT.

Odpowiedź Stevena Monday jest poprawna, ale używa ona iptablesbezpośrednio poleceń, które są niższą warstwą niż system konfiguracji UCI i najlepiej pozostawić je nietkniętym przez większość użytkowników OpenWRT, jeśli to możliwe.

Prawidłowym sposobem dostępu do wewnętrznych serwerów za pośrednictwem ich publicznych kombinacji adresów IP / portów z innego wewnętrznego hosta w UCI jest włączenie opcji konfiguracji w reflectionramach każdego określonego celu DNAT w pliku /etc/config/firewall. To zachowanie jest tutaj udokumentowane .

Na przykład:

config redirect option target 'DNAT' option src 'wan' option dest 'lan' option proto 'tcp' option src_dport '44322' option dest_ip '192.168.5.22' option dest_port '443' option name 'apache HTTPS server' option reflection '1'

Uwaga: Zgodnie ze wskazaną dokumentacją OpenWRT reflectionjest domyślnie włączona. W moich testach tak nie było.

vittorio88
źródło
15

Usunąłem pierwotną odpowiedź, ponieważ nie byłem w pełni pewien, że jest poprawny. Od tego czasu miałem trochę czasu na skonfigurowanie małej wirtualnej sieci maszyn wirtualnych w celu symulacji danej sieci. Oto zestaw reguł zapory, które działały dla mnie (w iptables-saveformacie, tylko dla nattabeli):

-A PREROUTING -d 89.179.245.232/32 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10
-A POSTROUTING -s 192.168.2.0/24 -o ppp0 -j MASQUERADE
-A POSTROUTING -s 192.168.2.0/24 -d 192.168.2.10/32 -p tcp -m multiport --dports 22,25,80,443 -j MASQUERADE

Pierwsza POSTROUTINGzasada to prosty sposób udostępniania połączenia internetowego LAN. Zostawiłem to dla kompletności.

PREROUTINGZasada i druga POSTROUTINGzasada wspólnie ustalić odpowiednie NAT, dzięki czemu połączenia z serwerem poprzez zewnętrzny adres IP może się zdarzyć, niezależnie od tego, czy połączenia pochodzą z zewnątrz lub od wewnątrz sieci LAN. Gdy klienci w sieci LAN łączą się z serwerem za pomocą zewnętrznego adresu IP, serwer widzi połączenia jako pochodzące z wewnętrznego adresu IP routera (192.168.2.1).

Co ciekawe, okazuje się, że istnieje kilka odmian drugiej reguły POSTROUTING, które również działają. Jeśli cel zostanie zmieniony na -j SNAT --to-source 192.168.2.1, efekt jest (co nie jest zaskakujące) taki sam jak MASQUERADE: serwer widzi połączenia od lokalnych klientów LAN jako pochodzące z wewnętrznego adresu IP routera . Z drugiej strony, jeśli zmieniono cel na -j SNAT --to-source 89.179.245.232, wówczas NAT nadal działają, ale tym razem serwer widzi połączenia od lokalnych klientów LAN jako pochodzące z zewnętrznego adresu IP routera (89.179.245.232).

Na koniec zauważ, że twoja oryginalna PREROUTING/ DNATreguła z -i ppp0nie działa, ponieważ reguła nigdy nie pasuje do pakietów pochodzących od klientów LAN (ponieważ te nie wchodzą do routera przez ppp0interfejs). Można by to zrobić, dodając drugą PREROUTINGregułę tylko dla wewnętrznych klientów LAN, ale byłoby to nieeleganckie (IMO) i nadal musiałoby jawnie odnosić się do zewnętrznego adresu IP.

Teraz, nawet po dokładnym opisaniu rozwiązania „szpilka do włosów NAT” (lub „pętla NAT”, „odbicie NAT” lub cokolwiek innego, jak wolą to nazywać), nadal uważam, że rozwiązanie DNS z dzielonym horyzontem - -z klientami zewnętrznymi korzystającymi z zewnętrznego adresu IP i klientami wewnętrznymi korzystającymi z wewnętrznego adresu IP --- byłaby bardziej wskazana droga. Dlaczego? Ponieważ więcej osób rozumie, jak działa DNS, niż rozumie, jak działa NAT, a duża część budowania dobrych systemów decyduje się na części, które można konserwować. Konfiguracja DNS jest bardziej zrozumiała, a zatem poprawnie utrzymywana, niż tajemna konfiguracja NAT (oczywiście IMO).

Steven Monday
źródło
Działa to doskonale, dziękuję bardzo! Zgadzam się, że konfiguracja DNS jest lepsza, ale nie można za jej pomocą przekazywać różnych portów tego samego zewnętrznego adresu IP do różnych komputerów w sieci LAN. W każdym razie jestem jedynym, który kiedykolwiek utrzyma tę konfigurację, więc jest w porządku.
whitequark
Cieszę się, że to zadziałało!
Steven poniedziałek
Co to jest „IMO”? Międzynarodowa Organizacja Meteorologiczna www.imo.net?
Jonathan Komar
@ macmadness86 IMO == Moim zdaniem
Steven poniedziałek
3

Częstym rozwiązaniem jest skierowanie wewnętrznych hostów na lokalny serwer DNS, który zwraca poprawny „wewnętrzny” adres dla tych nazw hostów.

Innym rozwiązaniem - i używamy tego, gdy pracuję nad naszymi zaporami Cisco - jest przepisanie odpowiedzi DNS na zaporze ogniowej, które odpowiadają tym adresom. Nie sądzę, że istnieją narzędzia dla Linuksa, które teraz to robią.

Powinieneś być w stanie skonfigurować routing na swojej bramie, aby postępować właściwie. Konieczne może być skonfigurowanie serwerów, aby były świadome ich zewnętrznie zmapowanego adresu IP (np. Poprzez przypisanie go do fikcyjnego interfejsu). W tej konfiguracji komunikacja z jednego systemu wewnętrznego do innego systemu wewnętrznego - przy użyciu jego „zewnętrznego” adresu - przebiegałaby przez router.

Larsks
źródło
Hmm Sugerujesz więc dodanie zewnętrznego adresu IP do interfejsów serwerów, a następnie skonfigurowanie routera, aby przekazywał wszystkie pakiety do zewnętrznego adresu IP przychodzącego z sieci LAN do tego serwera? Ciekawe, wkrótce to przetestuję.
whitequark
Czy możesz zasugerować konfigurację? Próbowałem tego: ip rule add to 89.179.245.232 dev br-lan table 10; ip route add 89.179.245.232 via 192.168.2.10 dev br-lan table 10i to nie działa.
whitequark
Co zawiera tabela routingu 10? Na wewnętrznych serwerach prawdopodobnie chcesz, aby miały zarówno lokalny adres 192.168.xx (do komunikacji lokalnej), jak i adres publiczny (jako alias) na głównym interfejsie.
larsks
2

To, o co prosisz, nazywa się NAT Loopbacki wymaga dodania reguły SNAT, aby pakiety pochodzące z Twojej sieci LAN na Twój serwer wracały przez router:

-A POSTROUTING -p tcp -s 192.168.2.0/24 -d 192.168.2.10 -m multiport --dports 22,25,80,443 -j SNAT --to-source 89.179.245.232
SiegeX
źródło
Niestety to nie działa. Pierwotnie przegapiłem -i ppp0opcję w omawianej regule, ponieważ była ona obsługiwana przez inny łańcuch; reguła ta zapobiegałaby routingowi pakietów przychodzących z sieci LAN (a gdybym ją włączył, pakiety będą pochodzić z niewłaściwego źródła i zostaną odrzucone).
whitequark
Próbowałeś tego? Wpłynie to tylko na pakiety z Twojej sieci LAN przechodzące do adresu IP twojego serwera na tych bardzo określonych portach.
SiegeX,
Tak. (Próbowałem też zmienić pierwszą zasadę). Np. Dig wysyła pakiet do 192.168.2.1 # 53, a następnie otrzymuje nieoczekiwaną odpowiedź z 192.168.2.10 # 53, z twoją regułą lub bez.
whitequark
0

Komentarz larsks na temat hostowania wewnętrznej wersji przestrzeni nazw \ domena jest ogólnie sposobem, w jaki radziłem sobie z tym problemem w przeszłości. Oczywiście, aby to zrobić, potrzebujesz serwera DNS wewnętrznie.

CurtM
źródło
Tak, napisałem, że używam dnsmasq. Jakieś pomysły na konfigurację automatycznej zamiany?
whitequark
Nic nie wiem o OpenWRT i Kamikaze, ale na podstawie tego, co czytam - co jeśli dodałeś następujące elementy do /etc/dnsmasq.conf "cname = ext-hostname.domain.com, int-hostname.domain.com"
CurtM,
O ile udało mi się ustalić, dnsmasq cnamenie obsługuje masek, a zatem nie dotyczy mnie z powodu liczby subdomen.
whitequark
0

Wymyśliłem następujące rozwiązanie, aby umożliwić mojej sieci gości połączenie z portami, które zostały przekierowane z mojej sieci WAN do LAN. Ten skrypt jest umieszczony w mojej sekcji „Sieć -> Zapora -> Reguły niestandardowe”:

# lookup the public IP (DDNS resolves to this)
wanip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

# Guest network to LAN
# srcname is the guest network name, this needs to match for iptables
srcname=guest
# CIDR notation of guest and lan networks
srcnet=192.168.15.0/24
tgtnet=192.168.10.0/24
# router (openwrt) IP on lan network
tgtrouter=192.168.10.1
# host on lan network where ports are normally forwarded
tgthost=192.168.10.5
# ports to forward as a list or range
tcpports=8080,9090
udpports=12345

prechain=prerouting_${srcname}_rule
postchain=postrouting_${srcname}_rule

# reset the tables to prevent duplicate rules
iptables -t nat -F ${prechain}
iptables -t nat -F ${postchain}

iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP SNAT" -j SNAT --to-source ${tgtrouter}
iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP SNAT" -j SNAT --to-source ${tgtrouter}

Aby wesprzeć ponowne uruchomienie, musiałem uruchomić następujące polecenie z wiersza poleceń ssh na openwrt (w przeciwnym razie uważam, że istnieje warunek wyścigu, w którym niektóre reguły zostały dodane, a następnie usunięte podczas ponownego uruchamiania):

uci set firewall.@include[0].reload="1"
uci commit firewall

Odbicie NAT jest skonfigurowane dla połączeń w sieci LAN z samym sobą, ale nie z innymi sieciami, jeśli utworzono wiele interfejsów do izolowania ruchu. Próbowałem skonfigurować regułę przekazywania z interfejsu internetowego, ale wysyła on cały ruch do portu z sieci gościa do tego hosta LAN. Powyższe przechwytuje tylko żądania do WAN IP zamiast całego ruchu sieciowego.

Zamiast tego można użyć wewnętrznego DNS, ale tylko wtedy, gdy wszystkie przekierowania portów idą tylko do jednego hosta. Jeśli masz wiele hostów, na których przekazujesz różne porty, możesz powtórzyć reguły dla różnych portów dla różnych tgthostadresów IP i portów.

BMitch
źródło
W obecnych jądrach znajduje się conntrackmoduł dopasowania. Aby rozwiązać problem, wystarczy zastosować jedną taką zasadę:iptables -t nat -A POSTROUTING --dst <lan-net> ! --src <lan-gw-ip> -m conntrack --ctstate DNAT --ctorigdst <wan-gw-ip> -j MASQUERADE
Anton Daniłow
@AntonDanilov miło, podoba mi się to. Reguły, których użyłem były oparte na regułach NAT refleksji już w OpenWRT dla połączeń z tej samej podsieci. Nie jestem pewien, czy mieli jakieś inne powody, niż być może napisane, zanim conntrack był dostępny.
BMitch