fragen stichworte

Wie erfolgt der Zugriff auf einen NAT-Server (LXC) über öffentliche IP-Adressen vom Client selbst in einem überbrückten Netzwerk?

Setup

   ____________________________             ____________________________ 
    | Host                     |             | Client                   |
    | Public IP:   66.66.66.66 |             |                          |
    | Internal IP: 10.0.3.1    | <---------> | Internal IP: 10.0.3.192  |
    ----------------------------             ----------------------------
  • Host mit öffentlicher IP-Adresse (= 66.66.66.66)
  • Linux Container (LXC), im restlichen Post als Client bezeichnet, wurde mit der Netzwerkoption veth gestartet, auf der ein Webserver ausgeführt wird.
  • Auf dem Host ist die Firewall mit ufw konfiguriert, und die entsprechenden Ports werden geöffnet und an den Client weitergeleitet. Dies funktioniert.

iptables Portweiterleitung im /etc/ufw/before.rules:

# nat Table rules
*nat
:PREROUTING ACCEPT [0:0]

-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.3.192:80
-A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.0.3.192:443
# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT

/etc/network/interfaces auf Host:

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
    address 66.66.66.66
    netmask 255.255.255.0
    network 66.66.66.0
    broadcast 66.66.66.255
    gateway 66.66.66.1
    # dns-* options are implemented by the resolvconf package, if installed
    dns-nameservers 8.8.8.8

/etc/network/interfaces auf Client:

# The loopback network interface
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 10.0.3.192
    netmask 255.255.255.0
    gateway 10.0.3.1
    broadcast 10.0.3.255

Port-Scan vom Client

Starting Nmap 5.21 ( http://nmap.org ) at 2014-04-18 18:46 CEST
Nmap scan report for 66.66.66.66
Host is up (0.00011s latency).
PORT    STATE  SERVICE
80/tcp  closed http
443/tcp closed https

Port-Scan von "außerhalb"

Starting Nmap 6.40 ( http://nmap.org ) at 2014-04-18 19:54 CEST
Nmap scan report for 66.66.66.66
Host is up (0.41s latency).
PORT    STATE SERVICE
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 1.28 seconds

iptables Konfiguration:

$ iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DNAT       tcp  --  anywhere             anywhere             tcp dpt:http to:10.0.3.192:80
DNAT       tcp  --  anywhere             anywhere             tcp dpt:https to:10.0.3.192:443
DNAT       tcp  --  anywhere             anywhere             tcp dpt:43211 to:10.0.3.192:22
DNAT       tcp  --  anywhere             anywhere             tcp dpt:http-alt to:10.0.3.192:8080

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  tcp  --  anywhere             10.0.3.192           tcp dpt:http
MASQUERADE  tcp  --  anywhere             10.0.3.192           tcp dpt:https
MASQUERADE  all  --  10.0.3.0/24         !10.0.3.0/24

Versionen

  • Ubuntu 12.04 (Host sowie Client)
  • LXC (1.0.3-0ubuntu1 ~ ubuntu12.04.1 ~ ppa1)

Gewünschtes Ergebnis

Ich möchte über die öffentliche IP vom Client selbst auf den Webserver an Port 80 des Clients zugreifen, z.

$ curl http://66.66.66.66
curl: (7) couldn't connect to host

sollte dasselbe Ergebnis wie

ergeben
$ curl http://10.0.3.192
<html>.....

Seltsam $ ping 66.66.66.66 vom Client im privaten Netzwerk funktioniert jedoch.


Was ich versucht habe

Ich sehe, dass dieses Problem sehr mit dem so genannten Hairpin NAT/Loopback NAT zusammenhängt, obwohl ich das Masquerading nicht mit den folgenden Regeln konfigurieren konnte, so dass es funktioniert (in /etc/ufw/before.rules danach) die PREROUTING -Einträge):

# nat Table rules
*nat
:POSTROUTING ACCEPT [0:0]

-A POSTROUTING -o eth0 -d 10.0.3.192 -p tcp --dport 80 -j MASQUERADE
-A POSTROUTING -o eth0 -d 10.0.3.192 -p tcp --dport 443 -j MASQUERADE

# don't delete the 'COMMIT' line or these nat table rules won't be processed
COMMIT

Meine Lösung für die Lösung ist, dass das überbrückte Netzwerk oder nur meine Unfähigkeit, die MASQUERADE-Regel korrekt an mein Setup anzupassen, das Problem ist. Anregungen und Kommentare, auch zum Aufbau allgemein, sind willkommen.

Verwandte Fragen oder Artikel, aber nicht hilfreich

antworten

(Ich habe zuerst geschrieben, es handelt sich um ein geroutetes Netzwerk und kein überbrücktes Netzwerk. Jetzt sehe ich, dass es LXC verwendet, also weiß ich es nicht. Aber wenn PREROUTING bereits funktioniert, hoffe ich, dass das, was ich unten geschrieben habe, funktionieren wird.)

Sie verwenden die PREROUTING-Kette. Diese Kette ändert nur Routing-Pakete, dh Pakete, die von woanders kommen. Pakete, die auf Host selbst generiert werden, werden nicht geroutet (sie sind nur ... Ausgabe, wie es jeder Host tun kann), so dass diese Kette niemals die Pakete von curl empfängt. curl hat wie üblich versucht, eine Verbindung zu Host herzustellen. Es gibt eine andere Kette, um lokal erzeugte Pakete abzufangen: OUTPUT.

Sie duplizieren also auch die DNAT-Regeln mit einigen Modifikationen in die OUTPUT-Kette (-t nat): OUTPUT möchte keine Eingabeschnittstelle. Sie ersetzen -i eth0 durch -o lo ! -s 127.0.0.0/8 oder einfach nur -d 66.66.66.66 oder etwas anderes. Sie benötigen jedoch eine Einschränkung. Andernfalls wird jede Webanforderung an einen beliebigen Ort an Client gesendet. Das erste Beispiel ist unabhängig von der IP-Adresse des Hosts, das zweite ist beliebig kürzer. Es handelt sich nicht um einen Tippfehler. Wenn Sie eine Verbindung zu 66.66.66.66 von sich selbst herstellen, handelt es sich um ein lokales Paket, also durch die lo -Schnittstelle. Aber da 127.0.0.1-ähnliche Ziele nicht umgeleitet werden können (curl http://127.0.0.1/ würde das Zeitlimit überschreiten, anstatt zu sagen, dass keine Verbindung hergestellt werden kann), wird 127.0.0.0/8 als Ausnahme betrachtet.

Und das ist es. Alles andere wird wie üblich von conntrack gehandhabt. Sie sollten die 2-Port-spezifischen MASQUERADE-Regeln entfernen. Sie werden nicht benötigt und können sogar stören (ich denke, wenn sie funktionieren, wird Client immer Host als Quelle auf dem Webserver angezeigt)

Die kurze Antwort lautet (mit -t nat):

-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.3.192
-A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.0.3.192
-A OUTPUT -o lo ! -s 127.0.0.0/8 -p tcp --dport 80 -j DNAT --to-destination 10.0.3.192
-A OUTPUT -o lo ! -s 127.0.0.0/8 -p tcp --dport 443 -j DNAT --to-destination 10.0.3.192