iptables: Cómo reenviar los puertos UDP y TCP al servidor detrás de la conexión VPN Wireguard

iptables: Cómo reenviar los puertos UDP y TCP al servidor detrás de la conexión VPN Wireguard

Entonces tengo un servidor VPS (KVM) que ejecuta Debian bullseye con una IP pública. Ese servidor también ejecuta un servidor Wireguard. En casa, tengo otro servidor (detrás de NAT) con un cliente Wireguard que está conectado a mi VPS. El túnel está en funcionamiento, lo que significa que puedo comunicarme correctamente a través de la VPN Wireguard.

+----------------------------------+             +-------------------------------
| Homeserver (behind NAT)          |             | VPS (KVM) with public IP     |
| 192.168.1.10                     |             | 1.2.3.4                      |
|         +------------------------|             |--------------------+         |
|         | wg-homeserver          | - - - - - - | wg-vps             |         |
|         | 192.168.200.2          |             | 192.168.200.1      |         |
|         +------------------------|             |--------------------+         |
|                                  |             |                              |
+----------------------------------+             +------------------------------+

Mi servidor doméstico ejecuta varios contenedores acoplables que escuchan en los puertos (en todas las direcciones IP), lo que significa que se puede acceder a estos puertos desde 192.168.1.0/24. Ahora necesito reenviar un puerto TCP y un puerto UDP en la dirección IP pública de mi VPS y reenviar el tráfico a través del enlace Wireguard a los mismos puertos en mi servidor doméstico:

1.2.3.4:10000/tcp -> 192.168.200.2:10000/tcp
1.2.3.4:10001/udp -> 192.168.200.2:10001/udp

El reenvío de IP está habilitado en ambas máquinas, lo que significa que cat /proc/sys/net/ipv4/ip_forwardmuestra 1.

Para reenviar el puerto TCP tengo estas reglas:

iptables -A FORWARD -d 192.168.200.2/32 -i wg-vps -p tcp --dport 10000 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 10000 -j DNAT --to-destination 192.168.200.2:10000

Cuando lo intento, ssh -p 10000 1.2.3.4no veo ningún paquete registrado wireguard -i wg-vps. Intenté muchas otras cosas pero no pude descubrir qué estoy haciendo mal o qué me falta.

De todos modos, en cuanto al puerto UDP creé esta regla, con un poco más de éxito:

iptables -t nat -A PREROUTING -d 1.2.3.4/32 -i eth0 -p udp --dport 10001 -j DNAT --to-destination 192.168.200.2:10001

Así es como envío mi paquete de prueba udp:

echo -n test | nc -4 -u 1.2.3.4 10001

Cuando hago esto, puedo ver tcpdump -i wg-vpsesto en el registro de mi VPS ( 4.5.6.7siendo mi dirección IP pública):

11:35:47.497622 IP 4.5.6.7.43357 > 192.168.200.2.10001: UDP, length 4

Lo que parece que está intentando hacer lo correcto y tomar el paquete, actualizar el destino 192.168.200.2y luego colocarlo en la interfaz Wireguard wg-vps. Pero tcpdump -i wg-homeserveren mi servidor doméstico nunca muestra la llegada de este paquete.

De hecho, noté que cuando estaba watch ip -s link show wg-homeserveren mi servidor doméstico, cada vez que enviaba un paquete udp a ese puerto, los errores de RX se incrementaban en uno. Entoncesalgollega hasta allí, pero sea lo que sea, no aparece tcpdumpy parece caer en algún lugar debajo. Lo cual es extraño porque tanto UDP como TCP a través del enlace Wireguard funcionan bien en ambas direcciones.

Hasta donde tengo entendido, tcpdumpmuestra paquetes anteriores a iptables, por lo que supongo que aunque el paquete parece estar escrito en la interfaz Wireguard, se descarta en algún lugar.

ACTUALIZAR: Ok, encontré una manera de habilitar el registro de Wireguard:

echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control

Y cuando sigue los registros, dmesg --followparece que Wireguard está descartando el paquete por este motivo:

wireguard: wg-homeserver: Packet has unallowed src IP (4.5.6.7) from peer 20 (xxxxxx)

Entonces creo que esto significa que no le gusta el hecho de que la dirección de origen sea la original de donde vino la solicitud. No quiero hacer SNAT, así que creo que tendré que enseñarle de alguna manera que debe permitir cualquier dirección de origen.

Lo que resulta ser la AllowedIPsconfiguración en la [Peer]sección de mi configuración de protección de cables. Esto resuelve el problema:

AllowedIPs = 0.0.0.0/0, ::0/0

Antes de esto había puesto las máscaras de interfaz similares a las que hay en la [Interface]sección, sin darme cuenta de que esto limitaría las direcciones de origen de los paquetes.

Sin embargo, esto secuestra todo el tráfico e intenta enrutarlo a través del enlace Wireguard wg-quicky AllowedIPscree que debería agregar una ruta y redirigir todo el tráfico a través de la VPN. Obviamente, esto no es deseado, pero afortunadamente hay una solución: Agregar Table = offa la [Interface]sección evitará que esto suceda.

Respuesta1

Consulte su tabla de reglas para comprender cómo se enrutan los paquetes salientes en el servidor doméstico. wg-quick agregará algunas reglas.

ip rule show

Para mí, tuve que eliminar algunas reglas generadas por wg-quick (que hace que reenvíe todos los paquetes a wg) y luego agregar reglas que reenvíen los puertos requeridos. Puede ver el número de tabla wg del comando anterior.

ip -4 rule add sport 80 table XXXXX
ip -4 rule add sport 443 table XXXXX

Lo anterior funcionó por un tiempo. Pero systemd-networkd eliminará las reglas personalizadas cuando expire el contrato de arrendamiento de DHCP o cuando el cable LAN se desconecte y se vuelva a conectar. Así que eliminé por completo wg-quick y utilicé systemd-networkd para configurar la interfaz wg y las reglas de enrutamiento.

información relacionada