Переадресация портов Proxmox на контейнер за NAT

Переадресация портов Proxmox на контейнер за NAT

Недавно мы купили сервер на аукционе серверов Hetzner и хотим перенести наш предыдущий корневой сервер. Раньше мы использовали только сервер Windows, но теперь мы хотим настроить его немного более модульно с помощью proxmox.

У нас есть один публичный IP-адрес, поэтому мы решили использовать NAT с внутренней подсетью 10.0.0.0/24.

Контейнеры могут получить доступ к Интернету, так что все работает нормально.

Но мы не можем подключиться к серверам, работающим внутри контейнеров, через пользовательские порты.

Как правильно перенаправить порты? Мы попробовали маршрутизацию и переадресацию портов, как указано ниже. Что-то пошло не так, порты не открыты, как показывает сканирование портов. В настоящее время на хосте Proxmox есть только брандмауэр, брандмауэр хоста сервера отключен, поэтому я не знаю, почему трафик должен блокироваться.

Это текущая настройка сетевого интерфейса proxmox:

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 нат:

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   

Интерфейс eno1 был автоматически сгенерирован их установочным скриптом. Мы добавили мост и NAT и т. д.

Конфигурация клиента:

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

В настоящее время клиентский контейнер не имеет брандмауэра.

У нас сравнительно мало опыта работы с сетями внутри хоста KWM, поэтому любая помощь будет высоко оценена!

решение1

Мы кое-что придумали, и я опубликую это здесь, на случай, если это кому-то пригодится. (Отказ от ответственности: мы создали это после нескольких часов проб и ошибок, это может сработать только для нашего хостинг-провайдера. Я ни в коем случае не эксперт по сетям Linux.)

/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

Интерфейс eno1 уже был настроен установочным скриптом нашего хостинг-провайдера (Хецнер), мы добавили post-upстроку для включения переадресации IP при загрузке.
Мы создали интерфейс vmbr0 в proxmox и настроили адрес подсети, вы можете выбрать любой диапазон адресов, который вам нравится. Мы выбрали 10.0.0.0/24. Затем вам нужно изменить запись файла в соответствии с нашим примером выше. Строки обязательны в том виде, в котором они есть (кроме IP, конечно). Если есть какие-либо интерфейсы ipv6, оставьте их в покое.

Теперь при создании контейнеров/виртуальных машин вам нужно задать статический адрес IPv4 и выбрать любой, который соответствует вашему поддиапазону ( 10.0.0.xxx/24), а также установить шлюз как 10.0.0.1.

Все переадресации портов определены в файле /etc/network/interfaces.d/port_forwards(должен быть создан пользователем, все файлы по этому пути загружаются в указанный выше основной файл со строкой source). IP-адрес в переадресациях портов — это IP-адрес, который вы назначили контейнеру во время создания.

# 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

С помощью пользовательского скрипта переадресации портов, который называется , port_forwardкоторый просто сокращает iptablesкоманды, чтобы файл оставался читаемым. Этот файл должен быть помещен или связан с ним, /bin/чтобы он загружался до монтирования пользовательского раздела.

#!/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

Каждый раз при изменении файлов необходимо сбрасывать iptables следующим образом:

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

Его также можно поместить в файл, мы дали ему имя reload_networkи поместили в /usr/local/bin/папку, чтобы получить к нему доступ как к команде.

Связанный контент