Configuración de un cortafuegos

Antes de que leas esta parte del capítulo, ten en cuenta que asumimos que ya has instalado iptables como se describe en la sección anterior.

Introducción a los cortafuegos

El propósito principal de un cortafuegos es proteger una red contra accesos maliciosos, utilizando una única máquina como cortafuegos. Esto implica que el cortafuegos pasará a considerarse un punto único de fallo, pero puede facilitar mucho la vida a los administradores.

En un mundo perfecto, donde sabes que cada demonio o servicio de cada máquina está perfectamente configurado y es inmune a, por ejemplo, desbordamientos de memoria intermedia (buffer overflows) o cualquier otro problema imaginable respecto a su seguridad; y donde confías en que cada usuario que accede a tus servicios no pretende dañarlo, ¡no necesitarías un cortafuegos! Sin embargo, en el mundo real, los demonios pueden estar mal configurados, los agujeros de seguridad de servicios esenciales están disponibles libremente... Por ello, puedes querer escoger qué servicios son accesibles para ciertas máquinas, puedes querer limitar qué máquinas o aplicaciones permites que tengan acceso a Internet o, simplemente, puede que no confíes en algunas aplicaciones o usuarios. En estas situaciones, podrías beneficiarte utilizando un cortafuegos.

Sin embargo, no asumas que tener un cortafuegos hace redundante una configuración cuidadosa, ni que convierte en inofensiva una configuración negligente, ni que previene de que cualquiera explote un agujero de seguridad en un servicio que ofreces pero que no has actualizado o parcheado después de publicarse ese agujero de seguridad. A pesar de tener un cortafuegos, necesitas tener bien configuradas y actualizadas las aplicaciones y los demonios de tu sistema; ¡un cortafuegos no es la panacea!

Significado de la palabra cortafuegos.

La palabra cortafuegos puede tener varios significados diferentes.

Personal Firewall

Esto es una configuración o programa (si es para Windows, vendido comercialmente por compañías como Symantec), que afirma o pretende asegurar un ordenador casero o de sobremesa con acceso a Internet. Este asunto es importante para aquellos usuarios que no saben las formas en que se puede acceder a sus ordenadores a través de Internet y cómo desactivarlas, especialmente si están siempre conectados y además a través de enlaces de banda ancha.

Masquerading Router

Esto es una máquina situada entre Internet y una intranet. Para minimizar el riesgo de comprometer al mismo cortafuegos, debería, generalmente, tener sólo un papel: proteger la red interna. Aunque no está completamente exento de riesgos, las tareas de efectuar el encaminamiento y, ocasionalmente, el enmascaramiento IP[1] se consideran, comúnmente, inocuas.

BusyBox

Esto es, a menudo, un viejo ordenador que puede que hayas retirado y casi olvidado, que realiza enmascaramiento y funciones de encaminamiento, pero que, además, ofrece una serie de servicios, por ejemplo, almacenamiento de páginas web, correo, etc. Esto suele usarse para redes caseras, pero no puede seguir considerándose tan seguro, porque la combinación de servidor y encaminador en una sola máquina aumenta la complejidad de la configuración.

Filtrado de paquetes / red parcialmente accesible [se describe parcialmente aquí, ver BusyBox]

Efectúa encaminamiento o enmascaramiento, pero sólo permite el acceso a ciertos servicios, y a veces sólo a usuarios o máquinas específicas; mayormente usado en contextos empresariales que necesitan alta seguridad, a veces desconfiando de los empleados. Esta era la configuración más común de un cortafuegos en la época del núcleo Linux 2.2. Todavía es posible configurar un cortafuegos de esta manera, pero hace las reglas bastante complejas y largas.

Limitación de responsabilidad

NI EL AUTOR NI NADIE DEL EQUIPO DE LINUXFROMSCRATCH SON RESPONSABLES DE NINGÚN DAÑO QUE SE PRODUZCA DEBIDO A LAS ACCIONES QUE SE TOMEN BASADAS EN ESTE DOCUMENTO.

Este documento está pensado como una introducción a cómo configurar un cortafuegos - no es una guía completa sobre asegurar sistemas. Instalar cortafuegos es un asunto complejo que requiere una configuración cuidadosa. Los guiones que se mencionan aquí simplemente intentan dar ejemplos de cómo funcionan los cortafuegos, no intentan encajar en cualquier configuración imaginable y puede que no prevengan de cualquier ataque imaginable.

El propósito de este texto es, simplemente, darte una pista sobre cómo comenzar con los cortafuegos.

Será necesario adaptar estos guiones a tu situación específica para una configuración óptima, pero deberías hacer un estudio serio de la documentación de iptables y de los cortafuegos en general antes de enredar. Echa un vistazo a la lista de Enlaces para lecturas adicionales al final de esta sección para más detalles. Ahí encontrarás una lista de URLs que contienen información bastante detallada sobre cómo construir tu propio cortafuegos.

Crear un Núcleo con el cortafuegos activado

Si quieres que tu sistema Linux haga la función de cortafuegos debes empezar asegurándote de que tu núcleo ha sido compilado con las opciones pertinentes activadas [2].

Cómo configurar el núcleo, activando las opciones que se compilarán en el núcleo o como módulos, depende de tus preferencias y experiencia personales. Ten en cuenta que, para los guiones mencionados, se supone que se cargan antes los módulos necesarios.

Ahora puedes empezar a construir tu cortafuegos

Cortafuegos Personal

Se supone que un Cortafuegos Personal debe permitirte acceder a todos los servicios ofrecidos en internet, pero protegiendo tu sistema y tus datos.

A continuación incluimos una versión ligeramente modificada de la recomendada por Rusty Russell en Linux 2.4 Packet Filtering HOWTO (Filtrado de paquetes de Linux 2.4):

cat > /etc/rc.d/init.d/firewall << "EOF"
#!/bin/sh

# Inicio de $rc_base/init.d/firewall

# Inserta los módulos de seguimiento de la conexión (no es necesario si
# se compilaron en el kernel).
modprobe ip_tables
modprobe iptable_filter
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ipt_state
modprobe ipt_LOG

# Permite conexiones locales
iptables -A INPUT  -i lo -j ACCEPT
# Permite la salida por cualquier interfaz hacia cualquier ip para
# cualquier servicio (igual que -P ACCEPT)
iptables -A OUTPUT -j ACCEPT

# Permite responder a conexiones ya establecidas y permite conexiones
# nuevas relacionadas con otras ya establecidas (por ejemplo, ftp
# activo)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Registra todo lo demás: ¿Cuál es la última vulnerabilidad explotable
# de Windows?
iptables -A INPUT -j LOG --log-prefix "FIREWALL:INPUT "

# Establece una política sana:    no se acepta nada > /dev/null
iptables -P INPUT    DROP
iptables -P FORWARD  DROP
iptables -P OUTPUT   DROP

# muestra más información para direcciones ip dinámicas (no es necesario si se
# posee una dirección IP estática)
echo 2 > /proc/sys/net/ipv4/ip_dynaddr

# desactiva la Notificación de Congestión Explícita - demasiados
# enrutadores todavía lo ignoran
echo 0 > /proc/sys/net/ipv4/tcp_ecn

# Fin de $rc_base/init.d/firewall
EOF

Su guión es bastante simple, ignora todo el tráfico que llega a tu ordenador que no ha sido iniciado por él, pero si simplemente está navegando por internet, es improbable que excedas sus límites.

Si te encuentras frecuentemente con retrasos al acceder a servidores ftp, por favor, consulta BusyBox - ejemplo NŠ 4.

Incluso si tienes demonios o servicios ejecutándose en tu sistema, deberían ser inaccesibles desde cualquier parte que no sea tu propio ordenador. Si quieres permitir el acceso a ciertos servicios de tu máquina, como ssh o ping, echa un vistazo a BusyBox.

Encaminador (router) con enmascaramiento

Un cortafuegos real tiene dos interfaces: uno conectado a una red interna, en este ejemplo eth0; y uno conectado a Internet, aquí ppp0. Para proporcionar la máxima seguridad contra accesos al cortafuegos, asegúrate de que no existen servidores ejecutándose en él, especialmente X11 y otros. Y, como regla general, el cortafuegos no debería acceder a ningún servicio que no sea de confianza[3].

cat > /etc/rc.d/init.d/firewall << "EOF"
#!/bin/sh

# Inicio de $rc_base/init.d/firewall

echo
echo "Estás utilizando la configuración de ejemplo para un cortafuegos"
echo "de la receta de cortafuegos escrita para LinuxFromScratch."
echo "Este ejemplo está lejos de ser completo, sólo está pensado"
echo "como referencia."
echo "La seguridad de un cortafuegos es una cuestión compleja, que"
echo "sobrepasa el alcance de las reglas de configuración citadas."
echo "Puedes encontrar información algo más detallada sobre"
echo "cortafuegos en el Capítulo 4 del libro BLFS."
echo "http://beyond.linuxfromscratch.org/"
echo

# Incluye los módulos de iptables (no es necesario si se compilaron
# dentro del núcleo).

modprobe ip_tables
modprobe iptable_filter
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ipt_state
modprobe iptable_nat
modprobe ip_nat_ftp
modprobe ipt_MASQUERADE
modprobe ipt_LOG
modprobe ipt_REJECT

# Permitir conexiones estrictamente locales
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Permitir reenvío
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -i ! ppp+	 -j ACCEPT

# Hacer enmascaramiento (no es necesario si la red interna no usa
# direcciones ip privadas)
iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE

# Registra todo para el depurado (la última de todas las reglas, pero
# antes de DROP/REJECT)
iptables -A INPUT   -j LOG --log-prefix "FIREWALL:INPUT  "
iptables -A FORWARD -j LOG --log-prefix "FIREWALL:FORWARD"
iptables -A OUTPUT  -j LOG --log-prefix "FIREWALL:OUTPUT "

# Establece una política sensata
iptables -P INPUT   DROP
iptables -P FORWARD DROP
iptables -P OUTPUT  DROP

# Muestra más información para direcciones ip dinámicas (no es necesario en el
# caso de IP estáticas)
echo 2 > /proc/sys/net/ipv4/ip_dynaddr

# Desactiva ExplicitCongestionNotification (Notificación Explícita de
# Congestión)
echo 0 > /proc/sys/net/ipv4/tcp_ecn

# Activa TCPsyncookies
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Activa Verificación de ruta = Protección contra engaños IP (IP spoofing)
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
	echo 1 > $f
done

# Activa el reenvío IP (IP forwarding)
echo 1 > /proc/sys/net/ipv4/ip_forward
EOF

Con este guión, tu red interna debería ser suficientemente segura contra ataques externos: nadie debería poder establecer una conexión nueva con ningún servicio interno y, si está enmascarado, incluso es invisible; además, tu cortafuegos debería ser casi inmune porque no hay servicios ejecutándose que un cracker pueda atacar.

Nota: Si la interfaz con la que estás conectando a Internet no utiliza ppp, necesitarás cambiar ppp+ por el nombre de la interfaz que estés utilizando. Si estás utilizando la misma interfaz para conectarte tanto a la red interna como a Internet, necesitas utilizar el nombre verdadero de la interfaz, como eth0, en ambas interfaces.

Si necesitas una seguridad más fuerte (por ejemplo, contra DOS - Denegación de Servicio - , robo de conexión, engaños, etc.) echa un vistazo a la lista de Enlaces para lecturas adicionales al final de esta sección.

BusyBox

Este escenario no es muy diferente al Masquerading Router, pero en este caso quieres ofrecer algunos servicios a tu red interna. Un ejemplo de esto es cuando quieres administrar tu máquina desde otro ordenador de tu red interna, o utilizarla como servidor intermedio (proxy) o servidor de nombres. Advertencia: Describir cómo proteger un servidor que ofrece servicios en Internet va mucho más allá del alcance de este documento, mira la Limitación de responsabilidad.

Se cauteloso. Cada servicio que ofrezcas y tengas activado hace tu configuración más compleja y tu máquina menos segura. Calcula los riesgos de servicios mal configurados o de ejecutar un servicio con un fallo explotable, riesgos ambos a los que, principalmente, un cortafuegos debería ser inmune. Mira la introducción a Masquerading Router para más detalles.

Si los servicios que quieres ofrecer no necesitan acceder a Internet, como un servidor samba o un servidor de nombres de uso sólo interno, esto es bastante simple y todavía podría ser aceptable desde el punto de vista de la seguridad. Basta añadir, dentro del guión, las siguientes líneas antes de las reglas de registro.
iptables -A INPUT	-i ! ppp+				-j ACCEPT
iptables -A OUTPUT	-o ! ppp+				-j ACCEPT

Si tus demonios tienen que acceder a la red, como puede necesitar squid, podrías abrir en general OUTPUT y restringir INPUT.
iptables -A INPUT	-m state --state ESTABLISHED,RELATED	-j ACCEPT
iptables -A OUTPUT						-j ACCEPT

Sin embargo, no es recomendable en general dejar OUTPUT sin restricciones: pierdes cualquier control sobre troyanos que quieran "llamar a casa", y algo de redundancia en caso de que tengas (mal) configurado un servicio que mande avisos de su existencia al mundo.

Si prefieres tener esta protección, puedes restringir INPUT y OUTPUT en todos los puertos, excepto aquellos que sea absolutamente necesario tener abiertos. Qué puertos tener abiertos depende de tus necesidades: mayormente los encontrarás buscando los accesos fallidos en tus ficheros de registro.

Examina los siguientes ejemplos:

  1. Squid está almacenando la web:

    iptables -A OUTPUT	-p tcp --dport 80			-j ACCEPT
    iptables -A INPUT	-p tcp --sport 80	-m state --state ESTABLISHED \
       -j ACCEPT

  2. Tu servidor de nombres caché (por ej., dnscache) hace sus consultas mediante udp:

    iptables -A OUTPUT	-p udp --dport 53			-j ACCEPT
    iptables -A INPUT	-p udp --sport 53	-m state --state ESTABLISHED \
       -j ACCEPT

  3. Alternativamente, si queres poder hacer ping a tu máquina para asegurarte de que está viva:

    iptables -A INPUT	-p icmp	-m icmp --icmp-type echo-request	\
       -j ACCEPT
    iptables -A OUTPUT	-p icmp	-m icmp --icmp-type echo-reply	-j 
    ACCEPT

  4. Si accedes frecuentemente a servidores ftp o IRC, puedes advertir ciertos retardos debido a que, algunas implementaciones de estos demonios tienen la característica de consultar el nombre de usuario de tu máquina, utilizando identd. Aunque en realidad esto no es peligroso, tener un identd en ejecución no es recomendable, pues se sabe que algunas implementaciones son vulnerables.

    Para evitar estos retardos puedes rechazar las peticiones con un 'tcp-reset':

    iptables -A INPUT	-p tcp --dport 113			-j REJECT \
       --reject-with tcp-reset
    iptables -A OUTPUT	-p tcp --sport 113	-m state --state RELATED \
       -j ACCEPT

  5. Para registrar y descartar paquetes inválidos, sobre todo paquetes inofensivos que llegaron tarde al filtro de red, o exploraciones de puertos:

    iptables -I INPUT 1	-p tcp	-m state --state INVALID	-j LOG \
       --log-prefix "FIREWALL:INVALID"
    iptables -I INPUT 2	-p tcp	-m state --state INVALID	-j
    DROP

  6. Todo lo que venga del exterior no debería tener una dirección privada. Este es un ataque común llamado IP-spoofing:

    iptables -t nat -A PREROUTING	-i ppp+	-s 10.0.0.0/8		-j DROP
    iptables -t nat -A PREROUTING	-i ppp+	-s 172.16.0.0/12	-j DROP
    iptables -t nat -A PREROUTING	-i ppp+	-s 192.168.0.0/16	-j
    DROP

  7. Para simplificar la depuración y ser justos con aquellos que quieren acceder a un servicio que tienes inhabilitado, adrede o por error, deberías usar REJECT en aquellos paquetes que son anulados.

    Obviamente, esto debe hacerse directamente después de registrarlos, como últimas líneas antes de que los paquetes sean anulados:

    iptables -A INPUT						-j REJECT
    iptables -A OUTPUT		-p icmp --icmp-type 3		-j ACCEPT

Esto son sólo ejemplos para mostrarte las capacidades del nuevo código de cortafuegos en los núcleos Linux-2.4. Consulta la página de manual de iptables. Allí encontrarás más. Los números de puerto que necesitarás para esto puedes encontrarlos en /etc/services, en caso de que no los hayas encontrado mediante "prueba y error" en tus ficheros de registro.

Si añades tus servicos ofrecidos o accedidos como se muestra anteriormente, quizás incluso en FORWARD o para comunicación de la red interna, y borras las cláusulas generales, obtienes un filtrado de paquetes al estilo antiguo.

Notas del Editor

Finalmente, quiero recordarte uno de los factores que no debemos olvidar: El esfuerzo gastado atacando un sistema se corresponde con el valor de lo que el cracker espera obtener. ¡Si eres responsable de activos tan valiosos que ya tienes en cuenta un gran esfuerzo por parte de los potenciales crackers, afortunadamente no tendrás necesidad de esta receta!

¡Se cauteloso!

    Henning Rohde

PS: Y recuerda siempre: ¡Estar seguro no es una cuestión de status-quo pero uno nunca debe parar de tener cuidado!

PPS: Si cualquiera de estos guiones falla, por favor avísame. Intentaré seguir cualquier fallo.

Información Extra

firewall.status

Si quieres examinar las cadenas que componen tu cortafuegos y el orden en el que las reglas hacen efecto:

cat > /etc/rc.d/init.d/firewall.status << "EOF"
#!/bin/sh

# Inicio $rc_base/init.d/firewall.status

echo "iptables.mangling:"
iptables -t mangle  -v -L -n --line-numbers

echo
echo "iptables.nat:"
iptables -t nat	    -v -L -n --line-numbers

echo
echo "iptables.filter:"
iptables	    -v -L -n --line-numbers
EOF

firewall.stop

Si necesitas desactivar el cortafuegos, este guión lo hará:

cat > /etc/rc.d/init.d/firewall.stop << "EOF"
#!/bin/sh

# Inicio $rc_base/init.d/firewall.stop

# desactivar IP-Forwarding 
echo 0 > /proc/sys/net/ipv4/ip_forward

iptables -Z
iptables -F
iptables -t nat         -F PREROUTING
iptables -t nat         -F OUTPUT
iptables -t nat         -F POSTROUTING
iptables -t mangle      -F PREROUTING
iptables -t mangle      -F OUTPUT
iptables -X
iptables -P INPUT       ACCEPT
iptables -P FORWARD     ACCEPT
iptables -P OUTPUT      ACCEPT
EOF

Notas

[1]

reescribir las cabeceras IP de los paquetes que enruta desde clientes con direcciones IP privadas hacia Internet, para que parezcan que provienen del mismo cortafuegos

[2]

Si necesitas ayuda sobre cómo configurar, compilar e instalar un núcleo nuevo, repasa el capítulo VIII del libro LFS Instalación del núcleo y Hacer el sistema LFS arrancable; ten en cuenta que necesitarás reiniciar para ejecutar realmente el nuevo núcleo.

[3]

Piensa en un servidor de nombres dando respuestas que hacen que bind falle o, incluso peor, que implementan un gusano a través de un desbordamiento de memoria.