Configuración de un cortafuegos

Antes de que leas esta parte del capítulo deberías tener ya instalado iptables como se describe en la sección anterior.

Introducción a la creación de cortafuegos

El propósito principal de un cortafuegos es proteger una red contra accesos maliciosos.

En un mundo perfecto, 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 relacionado con su seguridad. Más aún, confías en que cada usuario que accede a tus servicios. En ese mundo no necesitarías tener un cortafuegos.

Sin embargo, en el mundo real, los demonios pueden estar mal configurados y los agujeros de seguridad de servicios esenciales están disponibles libremente. Por ello, puede que quieras escoger qué servicios son accesibles para ciertas máquinas, puede que quieras limitar a qué máquinas o aplicaciones les permites tener acceso esterno, Alternativamente, puede que no confíes en algunas aplicaciones o usuarios. Y posiblemente estés conectado a Internet. En este mundo, un cortafuegos es esencial.

Sin embargo, no asumas que tener un cortafuegos hace redundante una configuración cuidadosa, ni que convierte en inofensiva una configuración negligente. No 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, pero debería ser parte esencial de tu estrategia de seguridad.

Significado de la palabra cortafuegos.

La palabra cortafuegos puede tener varios significados diferentes.

Es un dispositivo hardware o programa software vendido comercialmente por compañías como Symantec, que afirma o presume de que puede asegurar un ordenador casero o de sobremesa con acceso a Internet. Este tipo de cortafuegos 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.

Es un sistema situado entre Internet y una intranet. Para minimizar el riesgo de comprometer al propio 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 (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) se consideran relativamente seguras.

Con frecuencia es 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.

Cortafuegos con una zona desmilitarizada [no se describirá aquí]

Esta máquina efectúa enmascaramiento o encaminamiento, pero garantiza acceso público a parte de tu red, la cual, por tener IPs públicas y una estructura físicamente separada, es de hecho una red aparte con acceso directo a Internet. Estos servidores serán aquellos que deben ser fácilmente accesibles, tanto desde Internet como desde la red interna. Este tipo de cortafuegos tiene un mínimo de tres tarjetas de red.

Filtrado de paquetes

Este tipo de cortafuegos hace enrutado o enmascaramiento, pero no mantiene una tabla del estado de los flujos de comunicación. Es rápido, pero bastante limitado en su abilidad para bloquear paquetes inadecuados sin bloquearpaquetes deseados.

Ahora puedes empezar a construir tu cortafuegos

[Atención]

Atención

Esta introducción sobre cómo activar un cortafuegos no es una guía completa sobre protección de 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.

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.

El guión de configuración del cortafuegos instalado en la última sección es diferente del guión de configuración estandar. Sólo tiene dos de los objetivos normales: start y status. Los otros objetivos son clear y lock. Por ejemplo, cuando ejecutas:

/etc/rc.d/init.d/iptables start

el cortafuegos se reiniciará como en el arranque del sistema. El objetivo status presentará una lista de todas las reglas implementadas en la actualidad. El objetivo clean desactiva todas las reglas del cortafuegos y el objetivo lock bloqueará todos los paquetes de entrada y salida con la excepción de la interface loopback.

El arranque principal del cortafuegos se encuentra en el fichero /etc/rc.d/rc.iptables. Las siguientes secciones proporcionan tres de los diferentes métodos que pueden usasrse para un sistema.

[Nota]

Nota

Siempre deberías ejecutar las reglas del cortafuegos desde un guión. Esto asegura consistencia y un registro de qué se ha hecho. También permite retener comentarios que son esenciales para entender las largas reglas despues de escribirlas.

Cortafuegos Personal

Un Cortafuegos Personal se diseña para 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 en Linux 2.4 Cómo). Aún es aplicable para los núcleos Linux 2.6:

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

# Begin $rc_base/rc.iptables

# Insert connection-tracking modules 
# (not needed if built into the kernel)
modprobe ip_tables
modprobe iptable_filter
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ipt_state
modprobe ipt_LOG

# Enable broadcast echo Protection
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Disable Source Routed Packets
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route

# Enable TCP SYN Cookie Protection
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Disable ICMP Redirect Acceptance
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects

# Don¹t send Redirect Messages
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects

# Drop Spoofed Packets coming in on an interface, where responses 
# would result in the reply going out a different interface.
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

# Log packets with impossible addresses.
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians

# be verbose on dynamic ip-addresses  (not needed in case of static IP)
echo 2 > /proc/sys/net/ipv4/ip_dynaddr

# disable Explicit Congestion Notification 
# too many routers are still ignorant
echo 0 > /proc/sys/net/ipv4/tcp_ecn

# Set a known state
iptables -P INPUT   DROP
iptables -P FORWARD DROP
iptables -P OUTPUT  DROP
 
# These lines are here in case rules are already in place and the
# script is ever rerun on the fly. We want to remove all rules and
# pre-exisiting user defined chains before we implement new rules.
iptables -F
iptables -X
iptables -Z
 
iptables -t nat -F

# Allow local-only connections
iptables -A INPUT  -i lo -j ACCEPT

# Free output on any interface to any ip for any service 
# (equal to -P ACCEPT)
iptables -A OUTPUT -j ACCEPT

# Permit answers on already established connections
# and permit new connections related to established ones 
# (e.g. port mode ftp)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Log everything else. What's Windows' latest exploitable vulnerability?
iptables -A INPUT -j LOG --log-prefix "FIREWALL:INPUT "

# End $rc_base/rc.iptables
EOF

El 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ás navegando por Internet es improbable que excedas sus límites.

Si te encuentras frecuentemente con retrasos al acceder a servidores ftp, consulta ejemplo Nº 4 de BusyBox.

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 por si mismo a ningún servicio que no sea de confianza (Piensa en un servidor de nombres dando respuestas que hacen que un demonio de tu sistema falle o, incluso peor, que implementan un gusano mediante un desbordamiento de memoria).

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

# Begin $rc_base/rc.iptables

echo
echo "You're using the example configuration for a setup of a firewall"
echo "from Beyond Linux From Scratch."
echo "This example is far from being complete, it is only meant"
echo "to be a reference."
echo "Firewall security is a complex issue, that exceeds the scope"
echo "of the configuration rules below."
echo "You can find additional information"
echo "about firewalls in Chapter 4 of the BLFS book."
echo "http://www.linuxfromscratch.org/blfs"
echo

# Insert iptables modules (not needed if built into the kernel).

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

# Enable broadcast echo Protection
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Disable Source Routed Packets
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route

# Enable TCP SYN Cookie Protection
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Disable ICMP Redirect Acceptance
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects

# Don¹t send Redirect Messages
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects

# Drop Spoofed Packets coming in on an interface where responses
# would result in the reply going out a different interface.
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

# Log packets with impossible addresses.
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians

# Be verbose on dynamic ip-addresses  (not needed in case of static IP)
echo 2 > /proc/sys/net/ipv4/ip_dynaddr

# Disable Explicit Congestion Notification 
# Too many routers are still ignorant
echo 0 > /proc/sys/net/ipv4/tcp_ecn

# Set a known state
iptables -P INPUT   DROP
iptables -P FORWARD DROP
iptables -P OUTPUT  DROP
 
# These lines are here in case rules are already in place and the
# script is ever rerun on the fly. We want to remove all rules and
# pre-exisiting user defined chains before we implement new rules.
iptables -F
iptables -X
iptables -Z
 
iptables -t nat -F

# Allow local connections
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Allow forwarding if the initiated on the intranet
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD  -i ! ppp+ -m state --state NEW      -j ACCEPT

# Do masquerading
# (not needed if intranet is not using private ip-addresses)
iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE

# Log everything for debugging 
# (last of all rules, but before policy rules)
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 "

# Enable 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. Mas aún, tu cortafuegos debería ser casi inmune porque no hay servicios ejecutándose que un cracker pueda atacar.

[Nota]

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, poe ejemplo eth1.

BusyBox

Este escenario no es muy diferente al Router enmascarado, pero en este caso quieres ofrecer algunos servicios a tu red interna. Un ejemplo de esto es cuando quieres administrar tu cortafuegos desde otro ordenador de tu red interna, o utilizarlo como servidor intermedio (proxy) o servidor de nombres.

[Nota]

Nota

Describir cómo proteger un servidor que ofrece servicios en Internet va mucho más allá del alcance de este documento. Para más información, consulta las referencias al final de esta sección.

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. Generalmente un cortafuegos no debería ejecutar sevicios adicionales. Mira la introducción a Router enmascarado 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 web, como puede necesitar squid, podrías abrir OUTPUT en general 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:

  • 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
  • Tu servidor recolector de nombres (por ej., named) hace sus consultas mediante udp:

                    iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
  • 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
  • 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 consultarle a un identd en tu máquina tu nombre de usuario para usarlo como nombre de ingreso. Aunque en realidad esto no es peligroso, tener un identd en ejecución no es recomendable porque muchos expertos en seguridad afirman que el servicio muestra demasiada información adicional.

    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
  • 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 -p tcp -m state --state INVALID \
      -j LOG --log-prefix "FIREWALL:INVALID"
    iptables -I INPUT -p tcp -m state --state INVALID -j DROP
  • Todo lo que venga del exterior no debería tener una dirección privada. Este es un ataque común llamado IP-spoofing:

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

    Hay otras direcciones que también puedes querer bloquear: 0.0.0.0/8, 127.0.0.0/8, 224.0.0.0/3 (multicast y experimental), 169.254.0.0/16 (Link Local Networks), y 192.0.2.0/24 (red de pruebas definida por IANA).

  • Si tu cortafuegos es un cliente DHCP, necesitarás permitir dichos paquetes:

                    iptables -A INPUT  -i ppp0 -p udp -s 0.0.0.0 --sport 67 \
       -d 255.255.255.255 --dport 68 -j ACCEPT
  • Para simplificar la depuración y ser justos con aquellos que quieren acceder a un servicio que tienes inhabilitado, adrede o por error, podrías usar REJECT en aquellos paquetes que son anulados.

    Obviamente, esto debe hacerse directamente después de registrarlos, justo antes de que los paquetes sean anulados:

    iptables -A INPUT -j REJECT

Esto son sólo ejemplos para mostrarte las capacidades del código de cortafuegos en los núcleos Linux. 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.

Conclusión

Finalmente, hay un hecho que no debes olvidar: El esfuerzo gastado atacando un sistema se corresponde con el valor de lo que el cracker espera obtener. Si eres responsable de información valuosa, necesitarás invertir tiempo para protegerla correctamente.

Información extra

Last updated on 2005-04-09 16:21:16 +0200