[Anterior: NAT: Traducción de Direcciones de Red] [Contenido] [Siguiente: Atajos para Crear Conjuntos de Reglas]
Cuando hay un servidor de NAT delante de la red de una oficina, todas las máquinas de la red tienen acceso a Internet. Pero, ¿qué ocurre si se necesita acceder desde el exterior a una de las máquinas que hay detrás de la pasarela de NAT? Aquí es donde entra en escena el redireccionamiento. El redireccionamiento permite enviar el tráfico entrante a una máquina que se encuentre detrás de una pasarela de NAT.
Veamos un ejemplo:
rdr on tl0 proto tcp from any to any port 80 -> 192.168.1.20
Esta regla redirecciona el tráfico TCP del puerto 80 (un servidor de web) a una máquina que se encuentra dentro de la red en 192.168.1.20. Así, aunque 192.168.1.20 esté detrás de la pasarela y dentro de la red, es accesible desde fuera de ella.
La parte from any to any de la regla rdr anterior puede ser bastante útil; si sabemos qué direcciones o subredes se supone que deben acceder al servidor de web por el puerto 80, podemos restringirlo con esa parte:
rdr on tl0 proto tcp from 27.146.49.0/24 to any port 80 -> \
192.168.1.20
Con esto se redireccionaría sólo la subred especificada. Nótese que esto implica que podemos redireccionar diversos anfitriones entrantes hacia diversas máquinas que se encuentren detrás de la pasarela. Esto puede ser bastante útil. Por ejemplo, podríamos permitir que usuarios que se encontraran en sitios remotos accedieran a sus propias máquinas de trabajo usando el mismo puerto y dirección IP en la pasarela, siempre y cuando supiéramos la dirección IP desde la que se conectarían:
rdr on tl0 proto tcp from 27.146.49.14 to any port 80 -> \
192.168.1.20
rdr on tl0 proto tcp from 16.114.4.89 to any port 80 -> \
192.168.1.22
rdr on tl0 proto tcp from 24.2.74.178 to any port 80 -> \
192.168.1.23
NOTA: Los paquetes traducidos deben pasar a través de la maquinaria de filtros y, dependiendo de las reglas de filtrado que se hayan definido, se bloquearán o se les permitirá el paso. La única excepción a esta regla se da cuando se usa la clave pass dentro de la regla de rdr; esto hace que los paquetes redireccionados pasen directamente a través de la maquinaria de filtrado.
También hay que tener en cuenta que, debido a que la traducción tiene lugar antes del filtrado, la maquinaria de filtrado verá el paquete traducido tal y como es después de que su dirección IP de destino y/o su puerto de destino han sido cambiados para que concuerden con la dirección y/o puerto de redireccionamiento especificados en la regla de rdr. Consideremos el siguiente escenario:
Regla de redireccionamiento:
rdr on tl0 proto tcp from 192.0.2.1 to 24.65.1.13 port 80 \
-> 192.168.1.5 8000
El paquete antes de procesar la regla de rdr:
El paquete después de procesar la regla de rdr:
La maquinaria de filtrado verá el paquete IP tal como es después de haber tenido lugar la traducción.
El redireccionamiento tiene algunas implicaciones de seguridad. Pinchar un agujero en el cortafuegos para permitir el paso de tráfico a la red interna protegida deja abierta la máquina interna a merced de un potencial compromiso de seguridad. Si, por ejemplo, se redireccionara el tráfico a un servidor de web interno y se descubriera una vulnerabilidad en el dæmon del servidor de web interno, o en un script de CGI que se ejecutara en el servidor de web, entonces esa máquina podría ser comprometida por un intruso desde Internet. El intruso tendría desde ahí un pasadizo a la red interna, una vez que se le ha permitido pasar a través del cortafuegos.
Estos riesgos se pueden minimizar manteniendo el sistema al que hay que acceder desde el exterior confinado firmemente en una red separada. Esta red separada es la que se suele denominar como una «Zona Desmilitarizada» (DMZ) o una Red de Servicio Privado (PSN). De este modo, si se comprometiera el servidor de web, los efectos se podrían limitar la red DMZ/PSN, filtrando con cuidado el tráfico con permiso para pasar desde y hacia la DMZ/PSN.
A menudo se utilizan reglas de redireccionamiento para reenviar conexiones entrantes desde Internet a un servidor local con una dirección privada en la red interna o LAN, como en:
server = 192.168.1.40
rdr on $ext_if proto tcp from any to $ext_if port 80 -> $server \
port 80
Pero cuando se comprueba la regla de redireccionamiento desde un cliente en la LAN, aquélla no funciona. El motivo es que las reglas de redireccionamiento sólo son válidas para los paquetes que pasan a través de la interfaz especificada ($ext_if, la interfaz externa en el ejemplo). Sin embargo, conectar la dirección externa del cortafuegos desde un anfitrión en la LAN no implica que los paquetes vayan a pasar a través de su interfaz externa. La pila TCP/IP del cortafuegos compara las direcciones de destino de los paquetes entrantes con sus propias direcciones y alias, y detecta las conexiones a sí misma en cuanto pasan la interfaz interna. Estos paquetes no pasan físicamente a través de la interfaz externa, y la pila no simula un pase de ese tipo en modo alguno. Así que PF nunca ve estos paquetes en la interfaz externa y, por lo tanto, la regla de redireccionamiento que especifica la interfaz externa no es válida.
Si añadiéramos una segunda regla de redireccionamiento para la interfaz interna tampoco obtendríamos el efecto deseado. Cuando el cliente local se conecta a la dirección externa del cortafuegos, el paquete inicial del «saludo» de TCP llega al cortafuegos a través de la interfaz interna. La regla de redireccionamiento es válida y la dirección de destino se sustituye con la del servidor interno. El paquete se reenvía de vuelta a través de la interfaz interna y llega al servidor interno. Pero no se ha traducido la dirección de origen y todavía contiene la dirección local del cliente, por lo que el servidor envía sus respuestas directamente al cliente. El cortafuegos nunca llega a ver la respuesta y no tiene la oportunidad de invertir correctamente la traducción. El cliente recibe una respuesta desde un punto de origen que no esperaba, y por lo tanto la bloquea. En consecuencia, falla el saludo inicial de TCP y no se puede establecer una conexión.
A pesar de esto, a menudo es deseable que los clientes internos de la LAN se conecten al mismo servidor interno que los clientes externos, y que lo hagan de forma transparente. Existen varias soluciones para este problema.
Se pueden configurar los servidores de DNS para que respondan a los requerimientos de los anfitriones locales de forma diferente a los requerimientos externos, de modo que los clientes locales reciban la dirección del servidor interno durante la resolución del nombre. Así se conectarán directamente al servidor local y el cortafuegos no estará en medio de este proceso. Esto reduce el tráfico local, ya que no hay que enviar los paquetes a través del cortafuegos.
Añadir una interfaz de red adicional al cortafuegos y trasladar el servidor local desde la red del cliente a una red dedicada (DMZ) permite redireccionar las conexiones de los clientes locales de la misma forma que se redireccionan las conexiones externas. El uso de redes separadas ofrece varias ventajas, incluida la mejora de la seguridad al aislar al servidor del resto de los anfitriones locales. Si el servidor (al que en nuestro caso se puede llegar desde Internet) llegara a ser comprometido, no podría acceder directamente a otros anfitriones, ya que todas los conexiones deben pasar a través del cortafuegos.
Se puede configurar una proxy (un servidor intermedio de almacenamiento que actúa de intermediario entre el cliente y el servidor al que se quiere acceder, y que aligera la conexión ofreciendo datos del servidor final que tenga almacenados) genérica de TCP en el cortafuegos, bien a la escucha en el puerto de reenvío o bien redireccionando las conexiones de la interfaz interna al puerto por el que está a la escucha. Cuando un cliente local se conecta al cortafuegos, la proxy acepta la conexión, establece una segunda conexión al servidor interno, y reenvía los datos entre esas dos conexiones.
Se pueden crear proxies simples usando inetd(8) y nc(1). La siguiente entrada de /etc/inetd.conf crea un conector (socket) que estará a la escucha, vinculado a la dirección de loopback (127.0.0.1) y al puerto 5000. Las conexiones se reenvían al puerto 80 del servidor 192.168.1.10.
127.0.0.1:5000 stream tcp nowait nobody /usr/bin/nc nc -w \
20 192.168.1.10 80
La siguiente regla de redireccionamiento reenvía el puerto 80 de la interfaz interna a la proxy:
rdr on $int_if proto tcp from $int_net to $ext_if port 80 -> \
127.0.0.1 port 5000
Con una regla adicional de NAT en la interfaz interna se puede obtener la traducción de la dirección de origen que falta y que se ha descrito antes.
rdr on $int_if proto tcp from $int_net to $ext_if port 80 -> \
$server
no nat on $int_if proto tcp from $int_if to $int_net
nat on $int_if proto tcp from $int_net to $server port 80 -> \
$int_if
Con esto se consigue que el paquete inicial del cliente sea traducido de nuevo cuando se reenvíe de vuelta a través de la interfaz interna, sustituyendo la dirección de origen del cliente con la dirección interna del cortafuegos. El servidor interno enviará una respuesta al cortafuegos, que puede invertir las traducciones de NAT y RDR cuando esté reenviando al cliente local. Esta construcción es bastante compleja, ya que crea dos estados separados para cada una de las conexiones reflejadas. Hay que tener cuidado para que la regla de NAT no sea válida para otro tráfico, por ejemplo para conexiones que se originen en anfitriones externos (a través de otros redireccionamientos) o en el mismo cortafuegos. Nótese que la regla rdr anterior hará que la pila de TCP/IP vea los paquetes que llegan a la interfaz interna con una dirección de destino dentro de la red interna. Para evitar que la pila envíe mensajes ICMP de redireccionamiento (indicando al cliente que puede llegar directamente a su destino, y rompiendo la reflexión), hay que desactivar los redireccionamientos en la pasarela, usando
# sysctl -w net.inet.ip.redirect=0
# sysctl -w net.inet6.ip6.redirect=0 (si se usa IPv6)
En general, se deberían usar las soluciones mencionadas anteriormente en lugar de ésta.
[Anterior: NAT: Traducción de Direcciones de Red] [Contenido] [Siguiente: Atajos para Crear Conjuntos de Reglas]