Zugriff auf den DNAT'ted-Webserver über das LAN

12

Ich habe ein kleines Netzwerk mit einem Router, der eine Verbindung zum Internet, einem Server und einigen Arbeitsstationen in einem lokalen Netzwerk aufrechterhält.

Netzwerkkarte

Auf den Server kann über das Internet zugegriffen werden. In den iptables des Routers sind mehrere DNAT-Einträge wie folgt festgelegt:

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

Externe Pakete kommen über die ppp0Schnittstelle zum Router , und interne gehen von dort aus br-lan, wozu auch der Switch und der WLAN-Adapter gehören. Das Problem besteht darin, dass der Versuch, über eine (zugewiesene ppp0) DNS-aufgelöste externe IP-Adresse vom LAN aus auf den Server zuzugreifen, während der externe Zugriff problemlos funktioniert .

Die einzige Lösung, die ich erfinden konnte, besteht darin, statische Einträge zu Routern hinzuzufügen, die /etc/hostsauf die interne IP verweisen. Da es jedoch keine Platzhalter gibt (und diesem System mindestens drei Top-Level-Domains zugewiesen sind, ohne Dutzende von Subdomains zu zählen). das ist eher knusprig und störanfällig. Können Sie etwas Besseres vorschlagen?

Ich habe nur diese Frage gefunden , die nicht sehr hilfreich war.

Wenn dies relevant ist, führt der Router OpenWRT 10.03 Kamikaze mit dnsmasq aus.

Whitequark
quelle
Welche Version von OpenWRT?
Corey S.
@Corey 10.03 Stabil, aber das hat nichts mit openwrt selbst zu tun, oder?
Whitequark

Antworten:

3

Ich bin überrascht, dass nach fast 8 Jahren niemand erklärt hat, wie dies mit dem UCI-Konfigurationssystem, das standardmäßig in OpenWRT verwendet wird, richtig funktioniert.

Die Antwort von Steven Monday ist richtig, verwendet jedoch iptablesBefehle direkt. Dies ist eine niedrigere Ebene als das UCI-Konfigurationssystem und wird von den meisten OpenWRT-Benutzern am besten unberührt gelassen, wenn dies möglich ist.

Der korrekte Zugriff auf interne Server über ihre öffentlichen IP / Port-Kombinationen von einem anderen internen Host in der UCI aus erfolgt durch Aktivieren der Konfigurationsoption reflectionunter jedem bestimmten DNAT-Ziel in der Datei /etc/config/firewall. Dieses Verhalten ist hier dokumentiert .

Beispielsweise:

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'

Hinweis: Laut der angegebenen OpenWRT-Dokumentation reflectionist dies standardmäßig aktiviert. In meinen Tests war dies nicht der Fall.

vittorio88
quelle
15

Ich habe meine ursprüngliche Antwort gelöscht, weil ich nicht ganz sicher war, dass sie korrekt war. Ich hatte seitdem einige Zeit, ein kleines virtuelles Netzwerk von VMs einzurichten, um das betreffende Netzwerk zu simulieren. Die folgenden Firewall-Regeln haben bei mir funktioniert ( nur iptables-savefür die natTabelle im Format ):

-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

Die erste POSTROUTINGRegel ist eine einfache Möglichkeit, die Internetverbindung mit dem LAN zu teilen. Der Vollständigkeit halber habe ich es dort gelassen.

Die PREROUTINGRegel und die zweite POSTROUTINGRegel bilden zusammen die entsprechenden NATs, so dass Verbindungen zum Server über die externe IP-Adresse hergestellt werden können, unabhängig davon, ob die Verbindungen von außerhalb oder von innerhalb des LANs stammen. Wenn Clients im LAN über die externe IP-Adresse eine Verbindung zum Server herstellen, erkennt der Server, dass die Verbindungen von der internen IP-Adresse des Routers (192.168.2.1) stammen.

Interessanterweise stellt sich heraus, dass es einige Variationen der zweiten POSTROUTING-Regel gibt, die ebenfalls funktionieren. Wenn das Ziel in geändert wird, -j SNAT --to-source 192.168.2.1ist der Effekt (nicht überraschend) derselbe wie der folgende MASQUERADE: Der Server erkennt, dass Verbindungen von lokalen LAN-Clients von der internen IP-Adresse des Routers stammen . Wenn das Ziel dagegen in geändert wird -j SNAT --to-source 89.179.245.232, funktionieren die NATs weiterhin. Diesmal erkennt der Server jedoch, dass Verbindungen von lokalen LAN-Clients von der externen IP-Adresse des Routers stammen (89.179.245.232).

Beachten Sie schließlich, dass Ihr Original PREROUTING/ Ihre DNATRegel mit -i ppp0nicht funktioniert, da die Regel niemals mit Paketen von LAN-Clients übereinstimmt (da diese nicht über die ppp0Schnittstelle in den Router gelangen ). Es wäre möglich, dies durch Hinzufügen einer zweiten PREROUTINGRegel nur für die internen LAN-Clients zu bewerkstelligen, sie wäre jedoch unelegant (IMO) und müsste weiterhin explizit auf die externe IP-Adresse verweisen.

Selbst nachdem ich eine "Haarnadel-NAT" -Lösung (oder "NAT-Loopback" - oder "NAT-Reflection" - oder wie auch immer man es nennt) ausführlich ausgearbeitet habe, glaube ich immer noch, dass eine Split-Horizon-DNS-Lösung - Bei externen Clients, die auf die externe IP aufgelöst werden, und bei internen Clients, die auf die interne IP aufgelöst werden, ist dies der ratsamere Weg. Warum? Weil mehr Menschen verstehen, wie DNS funktioniert, als wie NAT funktioniert, und ein großer Teil des Aufbaus guter Systeme darauf abzielt, Teile zu verwenden, die gewartet werden können. Es ist wahrscheinlicher, dass ein DNS-Setup verstanden und somit korrekt verwaltet wird als ein geheimes NAT-Setup (IMO natürlich).

Steven Montag
quelle
Das funktioniert einwandfrei, vielen Dank! Ich bin damit einverstanden, dass das DNS-Setup besser ist, aber Sie können damit nicht verschiedene Ports auf derselben externen IP an verschiedene Computer im LAN weiterleiten. Wie auch immer, ich bin der einzige, der dieses Setup jemals aufrechterhalten wird, also ist es in Ordnung.
Whitequark
Ich bin froh zu hören, dass dies für Sie funktioniert hat!
Steven Montag
Was ist "IMO"? Internationale Meteororganisation www.imo.net?
Jonathan Komar
@ Macmadness86 IMO == Meiner Meinung nach
Steven Montag
3

Eine gängige Lösung besteht darin, Ihre internen Hosts auf einen lokalen DNS-Server zu verweisen, der die richtige "interne" Adresse für diese Hostnamen zurückgibt.

Eine andere Lösung - und diese verwenden wir, wenn ich an unseren Cisco-Firewalls arbeite - besteht darin, DNS-Antworten auf der Firewall neu zu schreiben, die diesen Adressen entsprechen. Ich glaube nicht, dass es Tools für Linux gibt, die dies derzeit tun.

Sie sollten in der Lage sein, das Routing auf Ihrem Gateway so zu konfigurieren, dass Sie das Richtige tun. Möglicherweise müssen Sie die Server so konfigurieren, dass sie ihre extern zugeordnete IP-Adresse kennen (z. B. indem Sie sie einer Dummy-Schnittstelle zuweisen). Bei dieser Konfiguration würde die Kommunikation von einem internen System zu einem anderen internen System - unter Verwendung der "externen" Adresse - über den Router erfolgen.

larsks
quelle
Hmm. Schlagen Sie also vor, die externe IP den Serverschnittstellen hinzuzufügen und dann den Router so zu konfigurieren, dass alle Pakete an die externe IP weitergeleitet werden, die aus dem LAN an diesen Server gesendet werden? Interessant, ich werde es bald testen.
Whitequark
Können Sie die Konfiguration vorschlagen? Ich habe Folgendes versucht:, 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 10und es funktioniert nicht.
Whitequark
Was ist in Routing-Tabelle 10? Auf den internen Servern möchten Sie wahrscheinlich, dass sie sowohl eine lokale 192.168.xx-Adresse (für die lokale Kommunikation) als auch die öffentliche Adresse (als Alias) auf ihrer primären Schnittstelle haben.
Larsks
2

Sie müssen NAT Loopbackeine SNAT-Regel hinzufügen, damit Pakete, die von Ihrem LAN an Ihren Server gesendet werden, über den Router zurückgeleitet werden:

-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
quelle
Leider funktioniert das nicht. Ich habe ursprünglich die -i ppp0Option in meiner fraglichen Regel verpasst , da dies von einer anderen Kette gehandhabt wurde. Diese Regel würde das Weiterleiten von Paketen aus dem LAN verhindern (und wenn ich sie aktivieren würde, würden Pakete von einer falschen Quelle stammen und zurückgewiesen werden).
Whitequark
Hast du es versucht? Es wirkt sich nur auf Pakete aus Ihrem LAN aus, die an diesen ganz bestimmten Ports an Ihre Server-IP gesendet werden.
SiegeX
Ja, habe ich. (Und ich habe auch versucht, die erste Regel zu ändern). Beispielsweise sendet dig ein Paket an 192.168.2.1 # 53 und erhält dann eine unerwartete Antwort von 192.168.2.10 # 53, mit oder ohne Ihre Regel.
Whitequark
0

larsks Kommentar zum Hosten einer internen Version des Namespace \ domain ist im Allgemeinen die Art und Weise, wie ich dieses Problem in der Vergangenheit behandelt habe. Natürlich benötigen Sie dazu intern einen DNS-Server.

CurtM
quelle
Ja, ich habe geschrieben, dass ich dnsmasq benutze. Irgendwelche Ideen zum Einrichten der automatischen Substitution?
Whitequark
Ich weiß nichts über OpenWRT und Kamikaze, aber basierend auf dem, was ich gerade lese - was ist, wenn Sie Folgendes zu Ihrer Datei /etc/dnsmasq.conf "cname = ext-hostname.domain.com, int-hostname.domain.com" hinzugefügt haben?
CurtM
Soweit ich feststellen konnte, unterstützt dnsmasq cnamekeine Masken und ist daher aufgrund der Anzahl der Subdomains für mich nicht anwendbar.
Whitequark
0

Ich habe die folgende Lösung gefunden, damit mein Gastnetzwerk Verbindungen zu Ports herstellen kann, die von meinem WAN-LAN-Netzwerk weitergeleitet wurden. Dieses Skript befindet sich in meinem Abschnitt "Netzwerk -> Firewall -> Benutzerdefinierte Regeln":

# 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}

Um Neustarts zu unterstützen, musste ich Folgendes von der ssh-Befehlszeile auf openwrt ausführen (ansonsten glaube ich, dass es eine Race-Bedingung gibt, bei der einige Regeln hinzugefügt und dann während des Neustarts gelöscht wurden):

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

NAT Reflection ist für Verbindungen innerhalb des LAN-Netzwerks zu sich selbst eingerichtet, jedoch nicht zu anderen Netzwerken, wenn Sie mehrere Schnittstellen erstellt haben, um den Datenverkehr zu isolieren. Ich habe versucht, eine Weiterleitungsregel über die Webschnittstelle zu konfigurieren, die jedoch den gesamten Datenverkehr an einen Port aus dem Gastnetzwerk an diesen LAN-Host sendet. Mit den oben genannten Aktionen werden nur Anforderungen an die WAN-IP abgefangen, nicht der gesamte Netzwerkverkehr.

Stattdessen könnte ein interner DNS verwendet werden, aber nur, wenn alle Portforwards nur an einen einzelnen Host gehen. Wenn Sie über mehrere Hosts verfügen, auf denen Sie verschiedene Ports weiterleiten, können Sie die Regeln für verschiedene Ports an verschiedene tgthostIP-Adressen und Ports wiederholen .

BMitch
quelle
In aktuellen Kerneln gibt es ein conntrackMatch-Modul. Und alles, was Sie brauchen, um das Problem zu lösen, ist die folgende einzige Regel:iptables -t nat -A POSTROUTING --dst <lan-net> ! --src <lan-gw-ip> -m conntrack --ctstate DNAT --ctorigdst <wan-gw-ip> -j MASQUERADE
Anton Danilov
@ AntonDanilov schön, das gefällt mir. Die Regeln, die ich verwendete, basierten auf Reflection-NAT-Regeln, die bereits in OpenWRT für Verbindungen aus demselben Subnetz vorhanden waren. Ich bin mir nicht sicher, ob sie andere Gründe dafür hatten, als möglicherweise geschrieben zu werden, bevor conntrack verfügbar war.
BMitch