Proxmox: NAT für VMs einrichten

Dieser Artikel befasst sich mit der Nutzung von NAT für virtuelle Maschinen bei der Virtualisierungslösung Proxmox. Durch die Network Address Translation können die Ziel- oder Quell-IP-Adresse auf eine andere Adresse umgeschrieben werden. Für die VMs kann also eine IP-Adresse aus einem privaten Adressbereich genutzt werden.

Speziell geht es in dem Artikel auch um PAT, also einer Port Adress Translation. Wir schreiben also nicht nur die IP-Adresse um, sondern leiten den Traffic anhand des verwendeten Ports an die jeweilige virtuelle Maschine weiter, um einen Dienst von außen erreichbar zu machen.

Bridge für internes Netz anlegen

Nach einer Installation von Proxmox existiert standardmäßig nur eine Bridge, die für Bridged-Networking verwendet wird. Dabei kommunizieren die VMs über einen virtuellen Switch direkt mit dem Gateway. Diese Bridge heißt im offiziellen Proxmox Image vmbr0, je nach Hoster und Installationstemplate eventuell auch vmbr1.

Wir legen also eine weitere Bridge an, die ich nachfolgend als vmbr1 bezeichne. Sollte vmbr1 bereits existieren, kann diese natürlich auch vmbr2 genannt werden.

auto vmbr1
iface vmbr1 inet static
    address 10.0.0.254
    netmask 255.255.255.0
    bridge_ports none
    bridge_stp off
    bridge_fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o vmbr0 -j MASQUERADE
    post-down iptables -t nat -F

In meinem Beispiel habe ich den privaten IP-Bereich 10.0.0.0/24 genutzt, es kann aber natürlich auch ein anderer privater IP-Bereich genutzt werden. Durch die IPTables-Regeln wird die IP-Adresse von und zu den VMs entsprechend umgeschrieben. Wichtig ist hier auch die Angabe der richtigen Bridge nach dem Parameter -o, dies sollte die bereits existierende Bridge sein, die normalerweise die öffentliche IP-Adresse trägt. Auch das Forwarding aktivieren wir beim Hochfahren der Bridge, damit die Pakete anhand der Routing-Tabelle des Hosts weitergeleitet werden und ein Zugriff auf das Internet aus der VM heraus möglich ist.

Erreichbarkeit der Dienste in VMs

Um auch einzelne Dienste wie einen SSH-Server oder Webserver von außen zu erreichen, müssen weitere IPTables Regeln angelegt werden. Auf Basis des genutzten Ports leiten wir den Traffic an die jeweilige IP-Adresse und Port der VM.

iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 1022 -j DNAT --to 10.0.0.10:22

In diesem Beispiel leiten wir den eingehenden TCP-Traffic über Port 1022 an die virtuelle Maschine mit der IP-Adresse 10.0.0.10 und den Port 22 weiter. Üblicherweise lauscht auf diesem Port standardmäßig der SSH-Server. Von außen wäre der Dienst über Port 1022 ansprechbar.

Für einen Webserver könnten die Regeln also so aussehen:

iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 10.0.0.10:80
iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 443 -j DNAT --to 10.0.0.10:443

Dabei wird der Traffic, der auf Port 80 (http) oder 443 (https) eingeht, an die VM mit der IP-Adresse 10.0.0.10 geleitet. Die von außen erreichbaren Ports können natürlich nur einmal vergeben werden, habt ihr also eine VM mit einem weiteren Webserver, muss für die Erreichbarkeit von außen ein anderer Port gewählt werden:

iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to 10.0.0.20:80

Auch hier leiten wir eingehenden Traffic auf Port 8080 auf den Webserver mit Port 80, der in der virtuellen Maschine mit der IP 10.0.0.20 lauscht, weiter.

Damit die einzelnen Regeln auch nach einem Reboot des Hostsystems wieder angelegt werden, können diese in der folgenden Form an die vmbr1-Konfiguration angehängt werden:

post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 10.0.0.10:80

Alternativ ist auch die Auslagerung der Regeln in ein Bash-Script denkbar, welches beim Hochfahren der Bridge aufgerufen wird.

6 comments Write a comment

  1. Für mich hat das beschriebene Vorgehen, egal ob als POSTROUTING mit -j MASQUARADE, oder einem -j SNAT, erst funktioniert, als ich generell MASQUARADING aktiviert habe: iptables -t nat -A POSTROUTING -j MASQUERADE

    Das mag aber spezifisch für mein Setup sein.

    • Danke an Scotty42,
      ich habe ewig gesucht um die Lösung für mein Problem in deinem Kommentar zu finden 🙂

  2. ich habe beim Hetzner einen Cloud Server zum TEST mit nur ein IP gemietet aber leider kann ich nicht auf dem Pfsense zugreifen.

    auto lo
    iface lo inet loopback

    auto ens3
    iface ens3 inet static
    address 65.21.190.110/32
    gateway 172.31.1.1
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A PREROUTING -i ens33 -p tcp -m multiport ! –dport 22,8006,80,443 -j DNAT –to 10.0.0.2
    post-up iptables -t nat -A PREROUTING -i ens33 -p udp -j DNAT –to 10.0.0.2

    auto vmbr0
    iface vmbr0 inet manual
    bridge-ports none
    bridge-stp off
    bridge-fd 0

    auto vmbr1
    iface vmbr1 inet static
    address 10.0.0.1/30
    bridge-ports none
    bridge-stp off
    bridge-fd 0
    post-up iptables -t nat -A POSTROUTING -s ‚10.0.0.0/30‘ -o ens33 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s ‚10.0.0.0/30‘ -o ens33 -j MASQUERADE

    auto vmbr2
    iface vmbr2 inet static
    address 192.168.55.2/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0

  3. Hallo Alen,

    Du nutzt in den Regeln „ens33“ und das tatsächliche Interface heißt „ens3“. Das kann nicht funktionieren.

  4. Hallo,

    ich habe folgendes Szenario:
    Server bei IONOS mit 3 IP Adressen
    Eingehend habe ich die Rules hinbekommen, das die jeweilige IP mit allen Ports auf eine bestimmte VM geht, ausgehend wird aber immer die IP vom PVE genommen.

    auto eth0
    iface eth0 inet manual

    iface eth1 inet manual

    auto vmbr0
    iface vmbr0 inet static
    address 85.xxx.xxx.45/32
    gateway 10.255.255.1
    bridge-ports eth0
    bridge-stp off
    bridge-fd 0

    auto vmbr1
    iface vmbr1 inet static
    address 85.xxx.xxx.2/32
    bridge-ports none
    bridge-stp off
    bridge-fd 0

    auto vmbr2
    iface vmbr2 inet static
    address 85.xxx.xxx.219/32
    bridge-ports none
    bridge-stp off
    bridge-fd 0

    auto vmbr20
    iface vmbr20 inet static
    address 10.0.0.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A POSTROUTING -s ‚10.0.0.0/24‘ -o vmbr1 -j MASQUERADE
    post-up iptables -t nat -A PREROUTING -d 85.xxx.xxx.2 -j DNAT –to-destination 10.0.0.2
    post-up iptables -t nat -A POSTROUTING -j MASQUERADE
    post-up iptables -t nat -A POSTROUTING -s ‚10.0.0.0/24‘ -o vmbr1 -j SNAT –to-source 85.xxx.x.2
    post-down iptables -t nat -D POSTROUTING -s ‚10.0.0.0/24‘ -o vmbr1 -j SNAT –to-source 85.xxx.xxx.2
    post-down iptables -t nat -F

    auto vmbr21
    iface vmbr21 inet static
    address 10.0.1.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A POSTROUTING -s ‚10.0.1.0/24‘ -o vmbr2 -j MASQUERADE
    post-up iptables -t nat -A PREROUTING -d 85.xxx.xxx.219 -j DNAT –to-destination 10.0.1.2
    post-up iptables -t nat -A POSTROUTING -j MASQUERADE
    post-up iptables -t nat -A POSTROUTING -s ‚10.0.1.0/24‘ -o vmbr2 -j SNAT –to-source 85.xxx.xxx.219
    post-down iptables -t nat -D POSTROUTING -s ‚10.0.1.0/24‘ -o vmbr2 -j SNAT –to-source 85.xxx.xxx.219
    post-down iptables -t nat -F

Schreibe einen Kommentar

Required fields are marked *.