Cómo evitar que netfilter cambie automáticamente los puertos de origen

Cómo evitar que netfilter cambie automáticamente los puertos de origen

Observé que netfilter cambia el puerto de origen cuando se establece una conexión en el módulo conntrack. Necesito prevenir este comportamiento.

Esto es lo que he hecho para reproducir mi problema:

  1. Creo una regla de netfilter que realizará DNAT desde el puerto 2002 al 2003.

sudo iptables -w -t nat -A OUTPUT -s 192.168.30.3 -d 192.168.30.1 -p udp --sport 2001 --dport 2002 -j DNAT --to-destination :2003

  1. Luego creo una entrada de conntrack para simular una conexión de 192.168.30.1:2001 (Mi computadora) a 192.168.30.1:2003

sudo /sbin/conntrack -I -s 192.168.30.1 -d 192.168.30.3 -p udp --sport 2003 --dport 2001 --timeout 100000

  1. Finalmente, realizo una conexión a 192.168.30.1:2002 desde mi computadora con el puerto de origen 2001:

sudo nc -u -p 2001 192.168.30.1 2002

Debido a la regla DNAT de netfilter, esperaba un paquete de salida con el puerto de destino 2003 y el puerto de origen 2001. Sin embargo, en Wireshark observé que el puerto de origen cambió a un número aleatorio. Supongo que esto se debe a que mi computadora considera que existe una conexión en el puerto 2001 (debido a la entrada conntrack) y luego evita que el puerto de origen sea 2001 (¿verdad?). ¿Pero no quiero este comportamiento? ¿Cómo puedo forzar el uso del puerto número 2001?

Respuesta1

Para que DNAT funcione (en el sentido de que, para que el programa pueda reconocer las respuestas), será necesario realizar una "NAT inversa" que cambie el puerto de origen de los tráficos de respuesta de 192.168.30.1(a 192.168.30.3:2001) de 2003a .2002

Sin embargo, cuando hay tráficos que vienen desde 192.168.30.1:2003el 192.168.30.3:2001punto de vista de conntrack y que no son consecuencia del DNAT (porque según la entrada de conntrack creada, el host no es el que inició la conexión), la NAT inversa será inapropiada.

Por lo tanto, netfilter se ve "obligado" a realizar también SNAT para los tráficos que coinciden con la regla DNAT, de modo que pueda diferenciar los tráficos de respuesta (que también provienen de 192.168.30.1:2003) según el destino 192.168.30.3:$random.

Supongo que netfilter realizará NAT inversa para DNAT (que es un SNAT) antes de NAT inversa para SNAT (que es un DNAT), o logrará usar el destino antes de la NAT inversa para SNAT (es decir, 192.168.30.3:$random) como coincidencia para la NAT inversa para DNAT, de lo contrario el SNAT forzado no tendrá sentido. (Sin embargo, en el caso de no reversión, nada de esto es cierto AFAIK: DNAT se realizará en PREROUTING antes de SNAT en INPUT, y la coincidencia de destino en la regla SNAT, si corresponde, utilizará el valor resultante en DNAT)


La cuestión es que la historia anterior/el "problema" en su pregunta apenas tiene sentido en la realidad. Tomemos como ejemplo una VPN Wireguard de dos hosts: supongamos que desea configurar Endpoint=ambos hosts (para que cualquiera de ellos pueda iniciar la comunicación) y no desea que los valores se "actualicen" inesperadamente debido al SNAT forzado (suponiendo que en realidad podría activarse), lo que deberías hacer es simplemente un SNAT "siempre activo" que "complemente" el DNAT / es equivalente al NAT de reserva:

iptables -t nat -A INPUT -s 192.168.30.1 -d 192.168.30.3 -p udp --sport 2003 --dport 2001 -j SNAT --to-source :2002

lo cual normalmente no es necesario en el modelo cliente-servidor debido a la NAT inversa automática para DNAT.

PD: Sin embargo, todavía no debes llegar 192.168.30.1:2003; 192.168.30.1:2003de lo contrario, la NAT de origen forzada también se producirá si vuelves a llegar 192.168.30.1:2002antes de que se elimine la entrada de conntrack del primero. La regla SNAT adicional en INPUT tampoco debería causarle problemas adicionales.

Respuesta2

Puede configurar dos flujos que normalmente colisionarían en elconectartabla de búsqueda (lo que generalmente desencadena una reescritura del puerto de origen en el nuevo flujo para evitar la colisión) esté en diferenteszonas de seguimiento. Esta propiedad de zona adicional haceconectarno coincide/colisiona con un flujo existente en una zona de conexión diferente: no se producirá ninguna reescritura del puerto de origen.

Para su ejemplo específico, aquí hay una regla específica que evitará la colisión y, por lo tanto, evitará la reescritura del puerto de origen:

iptables -t raw -A OUTPUT -s 192.168.30.3 -d 192.168.30.1 -p udp --sport 2001  --dport 2002 -j CT --zone-orig 1

Normalmente, según el caso de uso, se utiliza un selector más sensato. A menudo se usa en la cadena PREROUTING con una interfaz entrante como selector al enrutar y, a menudo, se asocia con un valor de marca para que el enrutamiento también pueda verse afectado.


El caso de uso original que hizo aparecer esta opción es cuandoconectaren la misma pila de red (sin espacio de nombres de red adicional) con una configuración de enrutamiento compleja (por ejemplo: enrutamiento entre 4 LAN privadas diferentes usando las mismas direcciones IP, por ejemplo, entre 192.168.1.0/24 eth0 <-> eth1 10.1.0.0/24, yde nuevo192.168.1.0/24 eth2 <-> 10.1.0.0/24 eth3) puede ver dos flujos no relacionados con las mismas direcciones/puertos. ComoFiltro de redyconectarNo sé nada sobre enrutamiento (elconectarla tabla de búsqueda incluye solo direcciones) se les debe enseñar a considerar estos flujos por separado agregando una propiedad de zona vinculada manualmente a la topología de enrutamiento en elconectartabla de búsqueda.

(Aquí hay unenlace LWNcuando se propuso originalmente la característica).

Respuesta3

NAT cambia el puerto de origen para reducir el riesgo de un conflicto de puerto. ¿Qué debería pasar si ese deporte 2002 ya está ocupado en la máquina NAT?

Si tiene requisitos específicos para puertos específicos, entonces podría agregar SNATreglas específicas para eso, pero nuevamente, ¿qué pasa si varios clientes internos intentan usar el mismo puerto de origen?

Aquí deberíamos retroceder y reconocer que NAT es un truco creado para reducir el problema de la falta de direcciones IP públicas. La verdadera solución aquí es que todos tengan IP públicas que no sean NAT.

Hoy en día, cuando hablamos de NAT, nos referimos más a menudo a direcciones IP privadas detrás de una IP. En estos casos, en realidad se trata deTNA aPregunta similar relacionada con eso, estaba pensando en MASQUERADEel objetivo y noDNAT

información relacionada