Recientemente compramos un servidor en la subasta de servidores de Hetzner y queremos migrar nuestro servidor raíz anterior. Anteriormente usábamos solo el servidor Windows, pero ahora queremos configurarlo un poco más modular con proxmox.
Tenemos una única dirección IP pública, por lo que optamos por utilizar NAT con una subred interna 10.0.0.0/24.
Los contenedores pueden acceder a Internet, por lo que esto funciona bien.
Pero no podemos conectarnos a servidores que se ejecutan dentro de los contenedores a través de puertos personalizados.
¿Cómo puedo reenviar correctamente los puertos? Probamos el enrutamiento y el reenvío de puertos como se detalla a continuación. Algo salió mal, los puertos no están abiertos, como lo muestran los escaneos de puertos. Actualmente solo hay un firewall en el host de Proxmox, el firewall del host del servidor está deshabilitado, por lo que no sé por qué se debe bloquear el tráfico.
Esta es la configuración actual de la interfaz de red 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 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
La interfaz eno1 fue generada automáticamente por su script de instalación. Agregamos el puente y el NAT, etc.
Configuración del cliente:
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
El contenedor del cliente actualmente no tiene firewall.
Tenemos relativamente poca experiencia con la creación de redes dentro de un host KWM, por lo que cualquier ayuda será muy apreciada.
Respuesta1
Descubrimos algo y lo publicaré aquí en caso de que sea útil para alguien. (Descargo de responsabilidad: elaboramos esto después de horas de prueba y error, es posible que solo funcione para nuestro proveedor de alojamiento. No soy un experto en redes Linux de ninguna manera).
/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
La interfaz eno1 ya fue configurada por el script de instalación de nuestro proveedor de hosting (Hetzner), agregamos la post-up
línea para habilitar el reenvío de IP en el arranque.
Creamos la interfaz vmbr0 en proxmox y configuramos una dirección de subred; puede elegir cualquier rango de direcciones que desee. Optamos por 10.0.0.0/24. Luego debe cambiar la entrada del archivo de acuerdo con nuestro ejemplo anterior. Las líneas son obligatorias tal como están (excepto la IP, por supuesto). Si hay interfaces ipv6, déjelas en paz.
Ahora, cuando cree contenedores/VM, debe configurar la dirección IPv4 en estática y elegir cualquiera que se ajuste a su subrango ( 10.0.0.xxx/24
), y configurar la puerta de enlace como 10.0.0.1
.
Todos los reenvíos de puertos están definidos en el archivo /etc/network/interfaces.d/port_forwards
(debe ser creado por el usuario, todos los archivos en esa ruta se cargan en el archivo principal anterior con la source
línea). La dirección IP en el puerto reenviado es la dirección IP que asignó al contenedor durante la creación.
# 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
Con un script de reenvío de puertos personalizado llamado port_forward
que simplemente abrevia los iptables
comandos para mantener el archivo legible. Este archivo debe colocarse o vincularse /bin/
para que se cargue antes de montar la partición del usuario.
#!/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
Cada vez que se cambian los archivos, es necesario restablecer iptables de la siguiente manera:
iptables --flush
iptables -t nat --flush
iptables --delete-chain
ifreload --all
Esto también se puede poner en un archivo, le asignamos un nombre reload_network
y lo colocamos en la /usr/local/bin/
carpeta para acceder como un comando.