[OpenBSD]

[Anterior: Filtrado de paquetes] [Contenido] [Siguiente: Redireccionamiento de tráfico (reenvío de puertos)]

PF: Traducción de Direcciones de Red (NAT)


Índice de contenidos


Introducción a NAT

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, "The IP Network Address Translator (NAT)".

NAT nos permite aprovechar los bloques de direcciones reservadas que se describen en el RFC 1918, "Address Allocation for Private Internets". 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.

Cómo funciona 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.

Reenvío de paquetes IP

Dado que NAT se utiliza casi siempre en los enrutadores y pasarelas de red, probablemente será necesario habilitar el reenvío de IP (IP Forwarding) para que los paquetes puedan viajar entre las interfaces de red de la máquina OpenBSD. El reenvío de IP se habilita mediante el mecanismo sysctl(3):

# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1 (if using 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.

Configuración de NAT

NOTA: Esta información es para OpenBSD 4.7. La configuración de NAT era notablemente diferente en versiones anteriores.

NAT se especifica como un parámetro opcional nat-to por una regla de salida pass. A menudo, en lugar de establecer directamente la regla pass, se usa una regla match. Cuando un paquete es seleccionado por una regla match, los parámetros de dicha regla (por ejemplo, nat-to) se recuerdan y se aplican al paquete cuando se ve afectado por la regla match coincidente. Esto permite que toda una clase de paquetes sea manipulada por una sola regla match y a continuación las decisiones específicas sobre la conveniencia de autorizar el tráfico se puede hacer con las reglas block y pass.

El formato general para las reglas de NAT en /etc/pf.conf es parecido al siguiente:

match out on interface [af] \
   from src_addr to dst_addr \
   nat-to ext_addr [pool_type] [static-port]
...
pass out [log] on interface [af] [proto protocol] \
   from ext_addr [port src_port] \
   to dst_addr [port dst_port]
match
Cuando un paquete atraviesa el conjunto de reglas y coincide con una regla match, todos los parámetros opcionales especificados en dicha regla se recuerdan para un uso futuro (se convierte en "adherente").
pass
Esta regla permite que el paquete sea transmitido. Si el paquete previamente obtuvo una correspondencia con una regla match en el que los parámetros se han especificado, se aplicarán a este paquete. Las reglas pass pueden tener sus propios parámetros; estos tienen prioridad sobre los parámetros especificados en una regla match.
out
Especifica la dirección del fujo del paquete donde se aplica esta regla. nat-to solo puede especificarse para paquetes salientes.
log
Los paquetes coincidentes se registran mediante pflogd(8). Normalmente solo se registra el primer paquete coincidente. Para registrar todos los paquetes, use log (all).
interface
El nombre o grupo de la interfaz de red sobre la que se transmiten los paquetes.
af
La familia de direcciones, que será inet para IPv4 ó inet6 para IPv6. PF suele ser capaz de determinar este parámetro basándose en la dirección (o direcciones) de origen/destino.
protocol
El protocolo (por ejemplo tcp, udp, icmp) de paquetes permitido. Si se especifica src_port o dst_port, el protocolo must también debe darse.
src_addr
La dirección de origen (interna) de los paquetes que vayan a ser traducidos. La dirección de origen se puede especificar como:
src_port
El puerto de origen en la capa 4 de la cabecera del paquete. Los puertos se pueden especificar como: La opción port no se suele usar en las reglas de nat por que el objetivo suele ser traducir las direcciones de todo el tráfico sin tener en cuenta el puerto, o los puertos, que se estén utilizando.
dst_addr
La dirección de destino de los paquetes que hay que traducir. La dirección de destino se especifica del mismo modo que la dirección de origen.
dst_port
El puerto de destino en la capa Layer 4 de la cabecera del paquete. Este puerto se especifica del mismo modo que el puerto de origen.
ext_addr
La dirección externa (la traducción) en la pasarela NAT a la que se traducirán los paquetes. La dirección externa se puede especificar como:
pool_type
Especifica el tipo de reserva de direcciones a usar para la traducción.
static-port
Informa a PF para no traducir el puerto origen en paquetes TCP y UDP.

Esto nos llevaría a una forma muy básica de estas líneas, que quedaría parecida a la siguiente:

match out on tl0 from 192.168.1.0/24 to any nat-to 24.5.0.5
pass on tl0 from 192.168.1.0/24 to any
O se puede usar simplemente
pass out on tl0 from 192.168.1.0/24 to any nat-to 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:

pass out on tl0 from dc0:network to any nat-to 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:

pass out on tl0 from dc0:network to any nat-to (tl0)

Este método funciona para traducir tanto direcciones IPv4 como IPv6.

Asignación bidireccional (asignación 1:1)

Se puede establecer una asignación de tipo bidireccional usando la regla binat-to. Una regla binat-to establece una asignación de uno a uno entre la dirección IP interna y la dirección externa. Esto puede ser útil, por ejemplo, para colocar un servidor 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 web (como las peticiones DNS) se traducirán a la dirección externa. Los puertos TCP y UDP nunca se modifican con las reglas binat-to como se modifican con las reglas nat.

Ejemplo:

web_serv_int = "192.168.1.100"
web_serv_ext = "24.5.0.6"

pass on tl0 from $web_serv_int to any binat-to $web_serv_ext

Excepciones a las reglas de traducción

Si se necesita traducir la mayoría del tráfico, pero incluyendo excepciones en algunos casos, asegúrese de que las excepciones son manejadas por una regla de filtrado que no incluya el parámetro nat-to. Así, el ejemplo de NAT anterior se modificaría del siguiente modo:

pass out on tl0 from 192.168.1.0/24 to any nat-to 24.2.74.79
pass out on tl0 from 192.168.1.208 to any

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

Comprobación del estado de NAT

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
   fxp0 TCP 192.168.1.35:2132 -> 24.5.0.5:53136 -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT
   fxp0 UDP 192.168.1.35:2491 -> 24.5.0.5:60527 -> 24.2.68.33:53   MULTIPLE:SINGLE

La explicación de esto (solo de la primera línea) es:

fxp0
Indica la interfaz a la que está asociado el estado. Aparecerá la palabra self si el estado es floating.
TCP
El protocolo que está usando la conexión.
192.168.1.35:2132
La dirección IP (192.168.1.35) de la máquina en la red interna. El puerto de origen (2132) se muestra después de la dirección. ésta también es la dirección que se sustituye en la cabecera IP.
24.5.0.5:53136
La dirección IP (24.5.0.5) y el puerto (53136) en la pasarela a la que se están traduciendo los paquetes.
65.42.33.245:22
La dirección IP (65.42.33.245) y el puerto (22) al que se está conectando la máquina interna.
TIME_WAIT:TIME_WAIT
Indica el estado en el que PF cree que se encuentra la conexión TCP.

[Anterior: Filtrado de paquetes] [Contenido] [Siguiente: Redireccionamiento de tráfico (reenvío de puertos)]


[back] www@openbsd.org
$OpenBSD: nat.html,v 1.13 2011/03/13 07:16:15 ajacoutot Exp $