Proxmox: redireccionar puerto con iptables y preservar la ip

Hace un par de años hice éste post sobre como redireccionar puertos a los contenedores que se encuentran dentro de un proxmox. Esta solución me fué de maravilla hasta que me di cuenta que el servidor nginx que estaba escuchando en los puertos 80 y 443 en lugar de guardar la IP del cliente que se conectaba, aparecía la IP del proxmox, cosa que creaba algunos problemas a la hora de bloquear intentos de acceso, ya que bloqueabas el acceso a todo el mundo… vamos… un pequeño problemilla de nada :P

Hace unos meses me propuse encontrar la solución pero hasta ahora no me ha sido urgente solucionarlo, ya que tengo que configurar otro proxmox con una ip compartida entre varios contenedores, cada uno de ellos con sus servicios y la cosa era mirar como afinaba esto… así que tras unos 4 días de estar rascando, aquí os traigo la solución :)

iptables -A PREROUTING -t nat -i vmbr0 -d 163.172.109.193 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.2:443
iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 443 -j ACCEPT
iptables -A FORWARD -i vmbr1 -j ACCEPT
iptables -A FORWARD -i vmbr0 -o vmbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i vmbr1 -o vmbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o vmbr0 -j MASQUERADE

– La primera regla de PREROUTING, los paquetes entran por la interfaz vmbr0 des de la ip 163.172.109.193, que es la ip pública del servidor. Mandamos todo el tráfico del 443 al contenedor que tiene la ip 192.168.1.2 al puerto 443.
– La segunda es para los paquetes de vuelta desde 192.168.1.2 por el puerto 443
– La tercera aceptamos todo lo que venga redireccionado de vmbr1, si no se activa esto, el contenedor no sabe salir a internet
– La cuarta y la quinta marcamos los paquetes de FORWARD que vayan de un interfaz a otro y los aceptamos
– La sexta hacemos un masquerade de todo el tráfico que venga de otras interfaces. Esto sirve para que todas las máquinas que tengan como gateway el servidor donde estamos configurando el iptables puedan salir a internet. Estos lo hacen con la IP pública del servidor.
Todos los puertos que estamos redireccionando son tcp, pero si tenemos que redireccionar el del DNS que es 53/udp pondríamos udp.

Siempre que trabajamos con iptables y tengamos de redirigir paquetes será importante activar el 1 al ip_forward

# echo 1 > /proc/sys/net/ipv4/ip_forward

Para que la configuración quede persistente, en el fichero /etc/network/interfaces del servidor proxmox vamos a configurarlo así:

auto vmbr0
iface vmbr0 inet static
        address 163.172.109.193/24
        gateway 163.172.109.1
        bridge_ports eth0
        bridge_stp off
        bridge_fd 0

auto vmbr1
iface vmbr1 inet static
        address  192.168.1.1
        netmask  255.255.255.0
        bridge_ports none
        bridge_stp off
        bridge_fd 0
        post-up echo 1 > /proc/sys/net/ipv4/ip_forward

Crearemos un fichero en /etc/firewall.conf con este contenido

# Generated by iptables-save v1.8.2 on Sat Apr  2 21:22:22 2022
*raw
:PREROUTING ACCEPT [2881509:824681435]
:OUTPUT ACCEPT [577184:3331071329]
COMMIT
# Completed on Sat Apr  2 21:22:22 2022
# Generated by iptables-save v1.8.2 on Sat Apr  2 21:22:22 2022
*filter
:INPUT ACCEPT [1370:354797]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [1093:378579]
-A FORWARD -d 192.168.1.2/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A FORWARD -d 192.168.1.2/32 -p tcp -m tcp --dport 443 -j ACCEPT
-A FORWARD -d 192.168.1.2/32 -p tcp -m tcp --dport 22 -j ACCEPT
-A FORWARD -i vmbr1 -j ACCEPT
-A FORWARD -i vmbr0 -o vmbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i vmbr1 -o vmbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
COMMIT
# Completed on Sat Apr  2 21:22:22 2022
# Generated by iptables-save v1.8.2 on Sat Apr  2 21:22:22 2022
*nat
:PREROUTING ACCEPT [85:4814]
:INPUT ACCEPT [67:3694]
:OUTPUT ACCEPT [1:60]
:POSTROUTING ACCEPT [1:60]
-A PREROUTING -d 163.172.109.193/32 -i vmbr0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80
-A PREROUTING -d 163.172.109.193/32 -i vmbr0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 192.168.1.2:443
-A PREROUTING -d 163.172.109.193/32 -i vmbr0 -p tcp -m tcp --dport 221 -j DNAT --to-destination 192.168.1.2:22
-A POSTROUTING -o vmbr0 -j MASQUERADE
COMMIT
# Completed on Sat Apr  2 21:22:22 2022

En mi caso estoy redirigiendo los puertos 80, 443 y 221 a sus respectivos puertos e ip. Destaco la tercera regla de FORWARD en la que tratamos el puerto 22 que ahí tendremos que poner el puerto de donde vienen las conexiones (22 en lugar de 221).

A continuación para aplicar los cambios usaremos

# iptables-restore < /etc/firewall.conf

Y para que se apliquen los cambios cada vez que iniciamos el servidor:

# vi /etc/network/if-up.d/iptables
#!/bin/sh
iptables-restore < /etc/firewall.conf
# chmod +x /etc/network/if-up.d/iptables

Gracias a todos los que me han dado apoyo mientras me peleaba con esto. Gracias por la paciencia :*

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *

Aquest lloc utilitza Akismet per reduir els comentaris brossa. Apreneu com es processen les dades dels comentaris.