Hice dos experimentos. Esta es la red para ambos:
[private network] [public network]
A -------------------- R ----------------- B
192.168.0.5 192.168.0.1|192.0.2.1 192.0.2.8
A 's puerta de enlace predeterminada es R . R tiene activo el reenvío de IPv4 y la siguiente regla de iptables:
iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 50000
La intención es que todo TCP de A se enmascarará como 192.0.2.1 usando el puerto 50000 de R.
Publiqué un servicio TCP en el puerto 60000 en B usando nc -4l 192.0.2.8 60000
.
Luego abrí una conexión desde A :nc -4 192.0.2.8 60000
A comenzó a enviar paquetes que se veían así:
192.168.0.5:53269 -> 192.0.2.8:60000
R tradujo eso a
192.0.2.1:50000 -> 192.0.2.8:60000
Hasta aquí todo bien.
Luego trató de abrir el siguiente cliente en R : nc -4 192.0.2.8 60000 -p 50000
. Envié mensajes, no pasa nada. No se pueden ver paquetes en el tcpdump de R.
Debido a que la regla de enmascaramiento existe, o al menos porque está activa, hubiera esperado que R 'nc fallara con el mensaje de error "nc: Dirección ya en uso", que es lo que sucede si enlazo dos ncs al mismo puerto.
Luego esperé un tiempo para que el mapeo de conntrack muriera.
El segundo experimento consistió en tratar de abrir el cliente de R primero. R comienza a hablar con B muy bien. Si luego abro la conexión desde A , se ignoran sus paquetes. A SYN 's llegan a R , pero no son contestadas, ni siquiera por los errores ICMP. No sé si esto se debe a que R sabe que se quedó sin puertos enmascarados o porque Linux está completamente confundido (técnicamente enmascara el puerto, pero la conexión ya establecida interfiere de alguna manera).
Siento que el comportamiento del NAT es incorrecto. Pude configurar accidentalmente un puerto para enmascarar (particularmente, al no especificar --to-ports
durante la regla de iptables) y un servicio, y el núcleo caerá las conexiones en silencio. Tampoco veo nada de esto documentado en ningún lado.
Por ejemplo:
- Una hace una petición normal a B . R máscaras usando el puerto 50k.
- Una hace una consulta DNS para R . Siendo que T es recursivo, R (usando, por pura coincidencia, puerto efímero 50k) consulta el servidor de nombres autorizado Z en el puerto 53.
Acaba de ocurrir una colisión; R ahora está utilizando el puerto 50k para dos conexiones TCP separadas.
Supongo que es porque normalmente no publicas servicios en enrutadores. Pero, de nuevo, ¿dañaría el núcleo "tomar prestado" el puerto del conjunto de puertos TCP cuando se enmascara activamente?
Sé que puedo separar mis puertos efímeros de mi --to-ports
. Sin embargo, este no parece ser el comportamiento predeterminado. Tanto NAT como los puertos efímeros tienen por defecto 32768-61000, lo cual es espeluznante.
(Encontré el rango efímero al consultar / proc / sys / net / ipv4 / ip_local_port_range, y el rango NAT simplemente NATizando muchas solicitudes UDP en un experimento separado e imprimiendo el puerto de origen en el lado del servidor. No pude encontrar una forma de imprimir el rango usando iptables.)
fuente
Respuestas:
Supongo que la respuesta es "no, pero no importa mucho".
Asumí incorrectamente que R solo usaba la dirección de transporte de destino del paquete de respuesta para saber si se dirigía hacia A o hacia sí mismo. En realidad, parece usar toda la tupla de direcciones de transporte de origen-destino para identificar una conexión. Por lo tanto, en realidad es normal que NAT cree múltiples conexiones usando el mismo puerto ( propiedad de R ); No crea ninguna confusión. En consecuencia, los grupos de puertos TCP / UDP no importan.
Es bastante obvio ahora que lo pienso.
Esta es la parte de los experimentos donde me equivoqué.
La falla ocurre porque las direcciones de transporte de origen y destino son las mismas, no solo porque la dirección de origen es la misma.
Si lo hago, por ejemplo,
nc -4 192.0.2.8 60001 -p 50000
realmente funciona. Incluso si usa el mismo puerto que una máscara NAT.No lo hará, porque las conexiones enmascaradas y las conexiones iniciadas en R probablemente tendrán diferentes destinos.
Todavía estoy buscando una respuesta a prueba de balas para esto, pero todo parece apuntar a "es una consecuencia adversa de cómo se implementa, y es tan pequeño que estamos dispuestos a vivir con eso".
fuente