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.)