Proxmox-Portweiterleitung zum Container hinter NAT

Proxmox-Portweiterleitung zum Container hinter NAT

Wir haben uns vor kurzem einen Server bei der Hetzner Serverauktion gekauft und möchten nun unseren bisherigen Rootserver migrieren. Bisher hatten wir nur Windows Server im Einsatz, möchten diesen nun aber mit Proxmox etwas modularer aufsetzen.

Wir haben eine einzelne öffentliche IP-Adresse und haben uns daher für die Verwendung von NAT mit einem internen Subnetz 10.0.0.0/24 entschieden.

Die Container haben Zugriff auf das Internet, daher funktioniert das problemlos.

Wir können jedoch keine Verbindung zu Servern herstellen, die über benutzerdefinierte Ports innerhalb der Container ausgeführt werden.

Wie kann ich die Ports richtig weiterleiten? Wir haben das Routing und die Portweiterleitung wie unten aufgeführt ausprobiert. Irgendetwas ist schiefgelaufen, die Ports sind nicht offen, wie Portscans zeigen. Im Proxmox-Host gibt es derzeit nur eine Firewall, die Firewall des Server-Hosts ist deaktiviert, daher weiß ich nicht, warum der Datenverkehr blockiert werden sollte.

Dies ist das aktuelle Setup der Proxmox-Netzwerkschnittstelle:

auto lo
iface lo inet loopback

iface lo inet6 loopback

auto eno1
iface eno1 inet static
        address public.ipv4/26
        gateway public.gateway
        up route add -net public.ipv4 netmask 255.255.255.192 gw public.ipv4 dev eno1
# route public.ipv4.range.start/26 via public.ipv4.range.start+1

iface eno1 inet6 static
        address public.ipv6/128
        gateway fe80::1

auto vmbr0
iface vmbr0 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 echo 1 > /proc/sys/net/ipv4/conf/eno1/proxy_arp
        post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o eno1 -j MASQUERADE
        post-down iptables -t nat -D POSTROUTING -s '10.0.0.0/24' -o eno1 -j MASQUERADE
        post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 28967 -j DNAT --to 10.0.0.4:28967
        post-up iptables -t nat -A PREROUTING -i vmbr0 -p udp --dport 28967 -j DNAT --to 10.0.0.4:28967
        post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 28967 -j DNAT --to 10.0.0.4:28967
        post-down iptables -t nat -D PREROUTING -i vmbr0 -p udp --dport 28967 -j DNAT --to 10.0.0.4:28967

iface vmbr0 inet6 static
        address public.ipv6+1/64

iptables -L -t nat:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             anywhere             tcp dpt:28967 to:10.0.0.4:28967
DNAT       udp  --  anywhere             anywhere             udp dpt:28967 to:10.0.0.4:28967

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  all  --  10.0.0.0/24          anywhere   

Die eno1-Schnittstelle wurde von ihrem Installationsskript automatisch generiert. Wir haben die Bridge und das NAT usw. hinzugefügt.

Client-Konfiguration:

auto lo
iface lo inet loopback
iface lo inet6 loopback

auto eth0
iface eth0 inet static
        address 10.0.0.4/24
        gateway 10.0.0.1

Der Client-Container hat derzeit keine Firewall.

Wir haben relativ wenig Erfahrung mit der Vernetzung innerhalb eines KWM-Hosts und sind daher für jede Hilfe sehr dankbar!

Antwort1

Wir haben etwas herausgefunden und ich werde es hier posten, falls es für irgendjemanden nützlich ist. (Haftungsausschluss: Wir haben dies nach stundenlangem Ausprobieren zusammengestellt, es funktioniert möglicherweise nur für unseren Hosting-Anbieter. Ich bin keineswegs ein Linux-Netzwerkexperte.)

/etc/network/interfaces:

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback
iface lo inet6 loopback

auto eno1
iface eno1 inet static
    address <hostpublicip>/26
    gateway <hostgateway>
    up route add -net <hostgateway-1> netmask 255.255.255.192 gw <hostgateway> dev eno1
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward # add this line

auto vmbr0
iface vmbr0 inet static
    address 10.0.0.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0

    post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o eno1 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s '10.0.0.0/24' -o eno1 -j MASQUERADE
    post-down iptables -t nat -F
    post-up   iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1
    post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1

Die eno1-Schnittstelle wurde bereits durch das Installationsskript unseres Hosting-Anbieters eingerichtet (Hetzner), haben wir die post-upZeile hinzugefügt, um die IP-Weiterleitung beim Booten zu aktivieren.
Wir haben die vmbr0-Schnittstelle in Proxmox erstellt und eine Subnetzadresse eingerichtet. Sie können jeden beliebigen Adressbereich wählen. Wir haben uns für 10.0.0.0/24 entschieden. Dann müssen Sie den Dateieintrag gemäß unserem obigen Beispiel ändern. Die Zeilen sind so, wie sie sind, erforderlich (außer der IP natürlich). Wenn es IPv6-Schnittstellen gibt, lassen Sie diese unverändert.

Wenn Sie jetzt Container/VMs erstellen, müssen Sie die IPv4-Adresse auf statisch setzen und eine beliebige auswählen, die zu Ihrem Teilbereich passt ( 10.0.0.xxx/24), und das Gateway als festlegen 10.0.0.1.

Alle Portweiterleitungen sind in der Datei definiert /etc/network/interfaces.d/port_forwards(muss vom Benutzer erstellt werden, alle Dateien in diesem Pfad werden mit der Zeile in die obige Hauptdatei geladen source). Die IP-Adresse in den Portweiterleitungen ist die IP-Adresse, die Sie dem Container bei der Erstellung zugewiesen haben.

# your network interface
iface vmbr0 inet static
    # minecraft container as example
    post-up port_forward -t 10.0.0.201 -p tcp -d 22     -s 22201 # external port 22201 for direct ssh to container
    post-up port_forward -t 10.0.0.201 -p tcp -m -d 25566,25576
    post-up port_forward -t 10.0.0.201 -p udp -m -d 25566,25576
    # follow with all the port forwards you need

Mit einem benutzerdefinierten Portweiterleitungsskript, port_forwarddas die Befehle einfach abkürzt, iptablesdamit die Datei lesbar bleibt. Diese Datei muss platziert oder verknüpft werden, /bin/damit sie geladen wird, bevor die Benutzerpartition gemountet wird.

#!/bin/bash
# abbr for iptables dnat

usage() { echo "Usage: $0 -t <container_ip> -p <tcp/udp/etc> -d <port> [-s <external port if different>] [-m flag if ports will be comma separated list, not compatible with -s]" 1>&2; exit 0; }

while getopts t:p:d:s::m flag
do
    case "${flag}" in
        t) target_ip=${OPTARG};;
        p) protocoll=${OPTARG};;
        d) dest_port=${OPTARG};;
        s) src_port=${OPTARG};;
        m) multiport=1 ;;
        *) usage ;;
    esac
done

if [[ -z "$src_port" ]]; then
    src_port="$dest_port"
fi

if [[ "$multiport" -eq 1 ]]; then
    iptables -t nat -A PREROUTING -i eno1 -p "$protocoll" -m multiport --dports "$dest_port" -j DNAT --to "$target_ip"
else
    iptables -t nat -A PREROUTING -i eno1 -p "$protocoll" --dport "$src_port" -j DNAT --to "$target_ip":"$dest_port"
fi

Jedes Mal, wenn die Dateien geändert werden, muss iptables wie folgt zurückgesetzt werden:

iptables --flush
iptables -t nat --flush
iptables --delete-chain
ifreload --all

Dies kann auch in eine Datei eingefügt werden. Wir haben sie benannt reload_networkund in dem Ordner abgelegt, /usr/local/bin/auf den per Befehl zugegriffen werden kann.

verwandte Informationen