NAT: Network Address Translation
NAT: Network Address Translation
[!tip] NAT en una frase NAT es el mecanismo que permite que múltiples dispositivos en tu red local compartan una sola IP pública, traduciéndolos automáticamente.
El problema: pocas IPs públicas, muchos dispositivos
Cada dispositivo que se conecta a Internet necesita una IP pública. Pero las IPv4 se agotaron en 2011. La solución: NAT.
Tu red local (192.168.1.x — IPs privadas)
┌─────────────────────────────────────────┐
│ Laptop (192.168.1.5) ──┐ │
│ Teléfono (192.168.1.6) ──┤ │
│ Smart TV (192.168.1.7) ──┤ │
│ Servidor NAS (192.168.1.8) ──→ Router ──→ IP pública: 85.23.45.67 (una sola!)
│ Consola (192.168.1.9) ──┘ │
└─────────────────────────────────────────┘
¿Cómo funciona NAT?
SNAT (Source NAT) — El más común
Cuando tu laptop hace una petición a Internet:
Dentro de tu red:
Origen: 192.168.1.5:54321
Destino: 93.184.216.34:80
Fuera de tu red (en el router):
Origen: 85.23.45.67:12345 (¡cambia el origen!)
Destino: 93.184.216.34:80
Respuesta:
Destino: 85.23.45.67:12345 (el servidor responde a la IP pública)
Origen: 93.184.216.34:80
Router traduce de vuelta:
Destino: 192.168.1.5:54321
El router mantiene una tabla de traducción:
┌─────────────┬─────────────┬─────────────┬─────────────┐
│ Internal IP │ Internal PT │ External IP │ External PT │
├─────────────┼─────────────┼─────────────┼─────────────┤
│ 192.168.1.5 │ 54321 │ 85.23.45.67 │ 12345 │
│ 192.168.1.6 │ 54322 │ 85.23.45.67 │ 12346 │
│ 192.168.1.7 │ 54323 │ 85.23.45.67 │ 12347 │
└─────────────┴─────────────┴─────────────┴─────────────┘
[!tip] Cada conexión tiene un puerto diferente Si dos dispositivos acceden al mismo servidor, el router les asigna puertos externos diferentes para poder distinguir las respuestas.
DNAT (Destination NAT) — Port forwarding
Cuando alguien desde Internet quiere acceder a un servicio en tu red:
Alguien en Internet:
Origen: 123.45.67.89:54321
Destino: 85.23.45.67:8080
Router traduce:
Origen: 123.45.67.89:54321
Destino: 192.168.1.100:3000
Resultado: La petición llega a tu servidor en localhost:3000
# En el router (iptables):
# Redirigir puerto 8080 del router al puerto 3000 del servidor interno
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:3000
# Y permitir el tráfico:
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 3000 -j ACCEPT[!warning] Port forwarding expone tu red al Internet Cuando haces port forwarding, estás abriendo una puerta desde Internet directamente a tu servidor interno. Esto es un riesgo de seguridad. NUNCA expongas servicios directamente a Internet sin un firewall o reverse proxy.
Masquerading (NAT dinámico)
Masquerading es una forma de SNAT donde el router usa su propia IP como origen:
# En Linux (iptables):
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
# ← Todo el tráfico de la red 192.168.1.0/24 que salga por eth0
# se mascarea con la IP de eth0[!tip] ¿Diferencia entre SNAT y Masquerade?
- SNAT: IP fija (útil si tu IP pública es estática)
- Masquerade: IP dinámica (útil si tu IP cambia, como en conexión móvil)
- En la práctica, masquerade es más común porque la mayoría de conexiones domésticas tienen IP dinámica
NAT y Docker
El problema: contenedores detrás de NAT
Tu máquina (192.168.1.5)
├── Docker container (172.17.0.2)
│ └── App en puerto 3000
├── Docker container (172.17.0.3)
│ └── PostgreSQL en puerto 5432
# ¿Cómo accedes desde tu máquina?
curl http://localhost:3000 → Connection refused (si no mapeaste el puerto)
curl http://localhost:5432 → Connection refused
# ¿Por qué?
# El contenedor está en 172.17.0.2 (red interna de Docker)
# Tu máquina no sabe cómo llegar allí
Solución: -p (port mapping) = DNAT
docker run -p 3000:3000 mi-app
# Docker hace DNAT automáticamente:
# Puerto 3000 del host → Puerto 3000 del contenedor
# Es como hacer port forwarding pero automáticoRed interna de Docker
Docker usa una red bridge: 172.17.0.0/16
Contenedor A (172.17.0.2) ──┐
├── Red bridge de Docker
Contenedor B (172.17.0.3) ──┘
│
│ NAT hacia tu red local
│
192.168.1.5 (tu máquina)
[!tip] Puertos entre contenedores
- Entre contenedores: Se comunican por la red interna de Docker (sin NAT, sin
-p). Usa el nombre del servicio como hostname.- Del host al contenedor: Necesitas
-p(DNAT). El contenedor NO es accesible desde el host por defecto.- Del Internet al contenedor: Necesitas
-p+ firewall abierto.
NAT y bases de datos
¿Por qué NO expones la base de datos a Internet?
# INCORRECTO: Base de datos accesible desde Internet
docker run -p 5432:5432 postgres:16
# Cualquiera en Internet puede intentar conectar a tu PostgreSQL
# CORRECTO: Base de datos solo accesible desde otros contenedores
docker run postgres:16 # Sin -p
# Solo accesible desde otros contenedores en la misma red Docker
Pattern común en Docker Compose
services:
# Frontend accesible desde Internet (a través de reverse proxy)
web:
build: ./frontend
ports:
- "80:80"
- "443:443"
# Backend accesible desde el frontend (red interna)
api:
build: ./backend
expose:
- "3000" # Solo dentro de Docker, no al host
# NUNCA uses ports: aquí
# Base de datos solo accesible desde el backend
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
# Sin ports, sin expose — solo volumen de datos
volumes:
pgdata:NAT Traversal (cuando las cosas se complican)
El problema: P2P detrás de NAT
Cuando dos dispositivos detrás de NAT quieren comunicarse directamente (P2P):
Dispositivo A (NAT) Dispositivo B (NAT)
192.168.1.5:54321 ──→ 85.23.45.67:12345 192.168.2.10:12345 ──→ 91.123.45.67:54321
(NAT table) (NAT table)
A no conoce B, B no conoce A. ¿Cómo se conectan?
Soluciones
| Técnica | Descripción | Uso |
|---|---|---|
| STUN | Descubre tu IP pública y mapeo de puertos | WebRTC, VoIP |
| TURN | Reenvía todo el tráfico a través de un servidor | Cuando P2P directo no funciona |
| ICE | Combina STUN + TURN para la mejor ruta | WebRTC |
| UPnP / NAT-PMP | Permite que aplicaciones abran puertos automáticamente | Raro hoy en día (seguridad) |
Resumen
- NAT permite que múltiples dispositivos compartan una IP pública
- SNAT traduce direcciones de origen (todos los dispositivos salientes)
- DNAT traduce direcciones de destino (port forwarding, acceso entrante)
- Docker usa NAT por defecto — necesitas
-ppara exponer contenedores - Nunca expongas bases de datos directamente a Internet
- IPv6 elimina la necesidad de NAT (cada dispositivo tiene IP pública)
[!quote] La clave NAT es un "parche" para la escasez de IPv4. Funciona bien para la mayoría de casos, pero rompe la conectividad P2P directa. IPv6 lo resolverá eventualmente.
Conexión con el resto de la wiki
| Concepto tocado | Artículo en profundidad |
|---|---|
| Puertos y localhost | [[12-puertos]] |
| Servidores y procesos | [[14-servidores-procesos]] |
| Reverse proxy | [[14-servidores-procesos]] (Nginx/Caddy como proxy) |