[Anterior: Filtrado de paquetes] [Contenido] [Siguiente: Redireccionamiento de Tráfico]
La Traducción de Direcciones de Red, o NAT (Network Address Translation), es un sistema que se utiliza para asignar una red completa (o varias redes) a una sola dirección IP. NAT es necesario cuando la cantidad de direcciones IP que nos haya asignado nuestro proveedor de Internet sea inferior a la cantidad de ordenadores que queramos que accedan a Internet. NAT se describe en el RFC 1631.
NAT nos permite aprovechar los bloques de direcciones reservadas que se describen en el RFC 1918. Generalmente, una red interna se suele configurar para que use uno o más de estos bloques de red. Estos bloques son:
10.0.0.0/8 (10.0.0.0 - 10.255.255.255) 172.16.0.0/12 (172.16.0.0 - 172.31.255.255) 192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
Un sistema OpenBSD configurado para NAT tendrá como mínimo dos adaptadoras de red, una para Internet y la otra para la red interna. NAT se encargará de traducir los requerimientos desde la red interna, de modo que parezca que todos provienen del sistema OpenBSD en el que se encuentra configurado NAT.
Cuando un cliente en la red interna contacta con un máquina en Internet, envía paquetes IP destinados a esa máquina. Estos paquetes contienen toda la información de direccionamiento necesaria para que puedan ser llevados a su destino. NAT se encarga de estas piezas de información:
Cuando los paquetes pasan a través de la pasarela de NAT, son modificados para que parezca que se han originado y provienen de la misma pasarela de NAT. La pasarela de NAT registra los cambios que realiza en su tabla de estado, para así poder: a) invertir los cambios en los paquetes devueltos, y b) asegurarse de que los paquetes devueltos pasen a través del cortafuegos y no sean bloqueados. Por ejemplo, podrían ocurrir los siguientes cambios:
Ni la máquina interna ni el anfitrión de Internet se dan cuenta de estos pasos de traducción. Para la máquina interna, el sistema NAT es simplemente una pasarela a Internet. Para el anfitrión de Internet, los paquetes parecen venir directamente del sistema NAT; ni siquiera se da cuenta de que existe la estación interna.
Cuando el anfitrión de Internet responde a los paquetes internos de la máquina, los direcciona a la IP externa de la pasarela de NAT (24.5.0.5) y a su puerto de traducción (53136). La pasarela de NAT busca entonces en la tabla de estado para determinar si los paquetes de respuesta concuerdan con alguna conexión establecida. Entonces encontrará una única concordancia basada en la combinación de la dirección IP y el puerto, y esto indica a PF que los paquetes pertenecen a una conexión iniciada por la máquina interna 192.168.1.35. Acto seguido PF realiza los cambios opuestos a los que realizó para los paquetes salientes, y reenvía los paquetes de respuesta a la máquina interna.
La traducción de paquetes ICMP ocurre de forma parecida, pero sin la modificación del puerto de origen.
Para activar NAT en una pasarela de OpenBSD, además de activar PF, también hay que activar el reenvío de paquetes IP (IP forwarding):
# sysctl -w net.inet.ip.forwarding=1
# sysctl -w net.inet6.ip6.forwarding=1 (si se usa IPv6)
Para que este cambio sea permanente, hay que añadir las siguientes líneas al fichero /etc/sysctl.conf:
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
Estas líneas ya existen en la instalación determinada, pero como comentarios (prefijadas con #). Hay que quitar el signo # y guardar el fichero. El reenvío de IP se activará cuando se reinicie la máquina.
El formato general para las reglas de NAT en /etc/pf.conf es parecido al siguiente:
nat on extif [af] from src_addr [port src_port] to \
dst_addr [port dst_port] -> ext_addr
Esto nos llevaría a una forma muy básica de la línea, que quedaría parecida a la siguiente:
nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5
Esta regla indica que hay que realizar NAT en la interfaz tl0 para cualquier paquete que venga de 192.168.1.0/24, y sustituir la dirección IP de origen con 24.5.0.5.
Aunque la regla anterior es correcta, la forma no es la recomendable. El mantenimiento podría resultar difícil ya que cualquier cambio de los números de la red externa o interna requeriría que se cambiara la línea. Cómparese con la siguiente regla (tl0 es externa y dc0 interna), que es más fácil de mantener:
nat on tl0 from dc0/24 to any -> tl0
La ventaja debería ser obvia: podemos cambiar la dirección IP de cualquiera de las interfaces sin cambiar esta regla.
Cuando se especifica un nombre de interfaz para la dirección de traducción, como en el ejemplo anterior, la dirección IP se determina en el momento de carga de pf.conf, no sobre la marcha. Si se está usando DHCP para configurar la interfaz externa, esto puede representar un problema, ya que si la dirección IP asignada cambiara, entonces NAT seguiría traduciendo los paquetes salientes usando la dirección IP antigua. Como resultado, las conexiones salientes dejarían de funcionar. Para evitarlo, se puede indicar a PF que actualice automáticamente la dirección de traducción poniendo entre paréntesis el nombre de la interfaz:
nat on tl0 from dc0/24 to any -> (tl0)
Esto tiene una limitación importante: cuando el nombre de la interfaz va entre paréntesis, sólo se evalúa el primer alias IP en una interfaz.
Se puede establecer una asignación de tipo bidireccional usando la regla binat. Una regla binat establece una asignación de uno por uno entre la dirección IP interna y la dirección externa. Esto puede ser útil, por ejemplo, para colocar un servidor de web en la red interna con su propia dirección IP externa. Las conexiones desde Internet hacia la dirección externa se traducirán a la dirección interna, y las conexiones desde el servidor de web (como los requerimientos de DNS) se traducirán a la dirección externa. Los puertos TCP y UDP nunca se modifican con las reglas binat como se modifican con las reglas nat.
Ejemplo:
web_serv_int = "192.168.1.100"
web_serv_ext = "24.5.0.6"
binat on tl0 from $web_serv_int to any -> $web_serv_ext
Se pueden hacer excepciones a las reglas de traducción usando la clave no. Así, el ejemplo de NAT anterior se modificaría del siguiente modo:
no nat on tl0 from 192.168.1.10 to any
nat on tl0 from 192.168.1.0/24 to any -> 24.2.74.79
Y entonces los paquetes de toda la red 192.168.1.0/24 se traducirían a la dirección externa 24.2.74.79, a excepción de 192.168.1.10.
Nótese que la primera regla que concuerde será la que se aplique; si es una regla con la clave no, entonces el paquete no se traducirá. La clave no también se puede usar con reglas binat y rdr.
Para ver las traducciones de NAT activas se usa pfctl(8) con la opción y el argumento -s state. Esta opción muestra un listado de todas las sesiones de NAT actuales:
# pfctl -s state TCP 192.168.1.35:2132 -> 24.5.0.5:53136 -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT UDP 192.168.1.35:2491 -> 24.5.0.5:60527 -> 24.2.68.33:53 MULTIPLE:SINGLE
La explicación de esto (sólo de la primera línea) es:
[Anterior: Filtrado de paquetes] [Contenido] [Siguiente: Redireccionamiento de Tráfico]