[LinuxFocus-icon]
Hogar  |  Mapa  |  Indice  |  Busqueda

Noticias | Arca | Enlaces | Sobre LF
Este documento está disponible en los siguientes idiomas: English  Castellano  ChineseGB  Deutsch  Francais  Nederlands  Russian  Turkce  

convert to palmConvert to GutenPalm
or to PalmDoc

Vincent Renardias
por Vincent Renardias
<vincent(at)renardias.com>

Sobre el autor:

Usuario de GNU/Linux desde 1993, Vincenct Renardias comenzó a involucrarse en su desarrollo en 1996: desarrollador de Debian, autor de la traducción francesa de The Gimp y el entorno GNOME, creador del grupo de usuarios de Linux en Marsella (PLUG), ... Actualmente director de I+D de la compañia EFB2, sigue contribuyendo al sistema GNU/Linux.



Taducido al español por:
Roberto Hernando (homepage)

Contenidos:

 

El filtrado de paquetes con Linux

[Illustration]

Resumen:

Este artículo ha sido publicado en un número especial sobre la seguridad de Linux Magazine France. El editor, los autores y los traductores han aceptado amablemente que todos los artículos de ese número especial sean publicados en LinuxFocus. En consecuencia, LinuxFocus os "ofrecerá" esos artículos a medida que se vayan traduciendo al inglés. Este resumen se reproducirá en todos los artículos que tengan el mismo origen.


Uno de los mejores medios para evitar los intentos de intrusión sigue siendo filtrar todas las entradas a la red que no se utilicen. Esta tarea habitualmente la desempeña una máquina que hace las veces de "firewall" (cortafuegos).
En este artículo, detallaremos los principios básicos para la implementación y configuración de dicho sistema.


_________________ _________________ _________________

 

¿Pasarela, Proxy-Arp o Puente Ethernet?

El mecanismo de filtrado puede considerarse como una malla que retiene ciertos paquetes no deseados. Lo más importante es encontrar el tamaño adecuado del mallado, así como el lugar donde ponerla.

Localización del cortafuegos en la red
Localización del cortafuegos

Para poder filtrar apropiadamente los paquetes, el mecanismo de filtrado debe intercalarse físicamente entre la red a proteger y el "resto del mundo". En la práctica, esto se hace con una máquina que tenga dos interfaces de red (normalmente Ethernet), una conectada a la red interna y la otra al router (encaminador) que permite el acceso al exterior. De esta forma, las comunicaciones pasarán obligatoriamente por el cortafuegos que las bloqueará o no según su contenido.
La máquina con el mecanismo de filtrado se puede configurar de 3 formas diferentes:

- gateway (pasarela) "simple": es la configuración más habitual. La máquina se utiliza como una pasarela entre dos redes o subredes. Las computadoras en la red local se deben configuradar para usar el cortafuegos, en vez del router, como su ruta por defecto.

- pasarela "Proxy-ARP": la configuración anterior implica la división de la red en dos subredes, con lo que se pierde la mitad de las direcciones IP disponibles, desperdiciándose un bit. Como ejemplo, en una subred con 16 direcciones (con una submáscara de 28 bits), sólo 14 estarán disponibles, ya que dos direcciones son para la red y el broadcast. Añadiendo 1 bit a la máscara de subred, bajamos de 14 a 6 direcciones disponibles (8 IPs menos las direcciones de red y broadcast). Cuando no se puede perder la mitad de las IPs disponibles se utiliza esta técnica, que está explicada un poco después en este artículo. Además, esta técnica no requiere ningún cambio en la configuración de red de las máquinas existentes, ni del router, ni de las computadoras protegidas.

- puente Ethernet (Ethernet bridge): instalando una pasarela Ethernet (no una pasarela IP) se consigue un mecanismo de filtrado invisible desde otras máquinas. Esta configuración se puede llevar a cabo sin asignar direcciones IP a las interfaces Ethernet. La máquina se convierte en indetectable mediante ping, traceroute, etc. Tengamos en cuenta que una implementación de filtrado por paquetes requiere un núcleo 2.2.x, ya que esta característica todavía no está implementada en los núcleos 2.4.x

 

Reglas básicas de filtrado

Ahora que sabemos dónde instalar nuestro filtro, debemos definir que tendrá que bloquear o qué aceptar.
Existen dos formas de configurar el filtro:

- La buena: no se permite pasar a ningún paquete, a no ser que lo autorice explícitamente alguna regla.
- La mala: (desgraciadamente, usada a menudo) los paquetes explícitamente prohibidos se paran, todos los demás se aceptan.

Es sencillo explicarlo: en el primer caso, olvidar una regla lleva a que un servicio no funcione apropiadamente o no funcione en absoluto.
En el segundo caso, olvidar una regla crea una vulnerabilidad potencial que puede ser difícil de encontrar... si la encontramos.

 

Netfilter

La aplicación de filtrado más utilizada con Linux 2.4 es Netfilter; reemplaza con creces a ípchains', utilizada con los núcleos Linux 2.2. Netfilter tiene dos partes: un componente del núcleo que debe compilarse en el núcleo y el comando íptables' que ya debería estar disponible en su sistema.

 

Ejemplo de configuración

Un ejemplo comentado es mejor que un gran discurso, describiremos cómo instalar y configurar un mecanismo de filtrado. Primero, la máquina se configurará como una pasarela mediante Proxy-ARP para limitar el número de direcciones IP y seguidamente configuraremos el sistema de filtrado.

El autor prefiere la distribución Debian para este tipo de instalación, pero cualquier otra distribución servirá.

Primero, compruebe que su núcleo soporta Netfilter. Si esto es así, deberá aparecer lo siguiente en los mensajes de arranque:

ip_conntrack (4095 buckets, 32760 max)
ip_tables: (c)2000 Netfilter core team

En otro caso, tendrá que recompilar el núcleo después de haber activado el componente Netfilter. Las correspondientes opciones se encuentran en el submenú "Network Packet Filtering (Filtrado de Paquetes de Red)" del menú "Networking Options (Opciones de Red)". Elija las opciones que necesite de la sección "Netfilter Configuration (Configuración de Netfilter)". Si duda, puede elegir todas. Además es mejor incluir Netfilter en el núcleo y no usar módulos. Si por una razón u otra los módulos de Netfilter desaparecen o no se cargan el filtrado podría no funcionar y mejor no hablamos de los peligros que esto conllevaría.

También debería instalar el paquete íproute2' (esto último no es obligatorio pero nuestro ejemplo lo utilizará, ya que nos permite simplificar el script de configuración). Con Debian, es suficiente con escribir el comando ápt-get install iproute'.
Con otras distribuciones, obtenga el paquete correspondiente de la forma habitual o bien puede instalarlo a partir del código fuente que puede obtener en la siguiente dirección:
ftp://ftp.inr.ac.ru/ip-routing/

Ahora hay que configurar las dos tarjetas Ethernet. Tengamos en cuenta que el núcleo de Linux cuando autodetecta el hardware detiene la búsqueda de tarjetas de red tan pronto como encuentra una. Por tanto, sólo se detectará la primera.
Una sencilla solución a este problema es añadir la siguiente línea al fichero lilo.conf: append="ether=0,0,eth1"

Después tendremos que configurar las interfaces Ethernet. El método que elegiremos nos permitirá utilizar la misma dirección IP para ambas tarjetas, con lo que ahorraremos una dirección.
Asumamos que tenemos la subred 10.1.2.96/28, que incluye las direcciones de la 10.1.2.96 a la 10.1.2.111. El router tendrá la dirección 10.1.2.97 y nuestra máquina de filtrado la 10.1.2.98. La interfaz eth0 se conectará al router a través de un cable cruzado RJ45 si ambas tarjetas se conectan directamente sin utilizar un hub o un switch; la interfaz eth1 se conectará al hub/switch y desde aquí a las máquinas de la red local.

Así pues, ambas interfaces se configurarán con los siguientes parámetros:

address  : 10.1.2.98
netmask  : 255.255.255.240
network  : 10.1.2.96
broadcast: 10.1.2.111
gateway  : 10.1.2.97

A continuación utilizaremos el siguiente script que deberemos ejecutar tras la configuración inicial de las tarjetas de red.

net.vars: Variables de configuración

PREFIX=10.1.2
DMZ_ADDR=$PREFIX.96/28
# Definiciones de la Interfaz
BAD_IFACE=eth0
DMZ_IFACE=eth1
ROUTER=$PREFIX.97


net-config.sh: script de configuración de red

#!/bin/sh
# Descomentar la siguiente línea para visualizar los comandos tras su ejecución
# set -x
# Se leen las variables definidas en el fichero anterior
source /etc/init.d/net.vars
# Se borran las rutas actuales de la red local
ip route del $PREFIX.96/28 dev $BAD_IFACE
ip route del $PREFIX.96/28 dev $DMZ_IFACE
# Se define que la red local es accesible a través de eth1
# y el router a través de eth0.
ip route add $ROUTER dev $BAD_IFACE
ip route add $PREFIX.96/28 dev $DMZ_IFACE
# Se activa Proxy-ARP para las dos interfaces
echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp
# Activamos "IP forwarding" para permitir a los paquetes que llegan a una tarjeta
# enrutarse hacia la otra
echo 1 > /proc/sys/net/ipv4/ip_forward

Volvamos al mecanismo Proxy-ARP requerido para nuestra configuración.
Cuando un máquina habla con otra en la misma red, necesita conocer la dirección Ethernet (o dirección MAC o dirección hardware) correspondiente a su dirección IP. Entonces la máquina origen difunde ("hace un broadcast") la pregunta "¿cuál es la dirección MAC de la interfaz cuya dirección IP es 1.2.3.4?", y la máquina destino debe responder.

Aquí tenemos un ejemplo de dicha "charla" vista usando tcpdump:
- la petición: la máquina 172.16.6.72 pregunta la dirección MAC correspondiente a la dirección IP 172.16.6.10.
19:46:15.702516 arp who-has 172.16.6.10 tell 172.16.6.72
- la respuesta: la máquina 172.16.6.10 da su número de tarjeta.
19:46:15.702747 arp reply 172.16.6.10 is-at 0:a0:4b:7:43:71

Esto nos conduce al final de esta pequeña explicación: las peticiones ARP se hacen mediante difusión, por lo que están limitadas a una única red física. Así pues la petición de una máquina protegida para encontrar la dirección MAC del router debería ser bloqueada por la máquina de filtrado. Activando la característica Proxy-ARP solventaremos este problema pidiendo explícitamente que las peticiones y respuestas ARP que lleguen por una tarjeta se propaguen hacia la otra, y viceversa.

En este punto, debería tener una red trabajando con una máquina controlando todo el tráfico entre la red local y el exterior.

Ahora, debemos configurar el filtrado mediante Netfilter.
Netfilter permite actuar directamente en el flujo de paquetes. En la configuración básica los paquetes son controlados por tres cadenas de reglas:
- INPUT: para los paquetes que llegan a través de una interfaz,
- FORWARD: para todos los paquetes transmitidos desde una interfaz hacia la otra,
- OUTPUT: para los paquetes que salen de una interfaz.

El comando íptables' permite añadir, cambiar o borrar reglas en cada una de estas cadenas para modificar el entorno de filtrado.
Más aún, cada cadena tiene una política por defecto, esto es, sabe qué hacer cuando ninguna regla en la cadena afecta a un paquete.

Las cuatro opciones más comunes son:
- ACCEPT: el paquete puede pasar,
- REJECT: el paquete es rechazado y se envía el paquete de error asociado (ICMP Port Unreachable, TCP RESET, según el caso),
- LOG: escribe una notificación de paquete en syslog,
- DROP: el paquete es ignorado y no se envía ninguna respuesta.

Flujo de paquetes en las cadenas estándar

Flujo de paquetes

Aquí están las principales opciones de iptables que nos permiten manipular cadenas enteras. Las explicaremos con detalle más tarde:

-N: crea una nueva cadena.
-X: borra una cadena vacía.
-P: cambia la política por defecto de una cadena.
-L: lista las reglas en una cadena.
-F: elimina todas las reglas en una cadena.
-Z: pone a cero los contadores de bytes y paquetes que han pasado por la cadena.

Para modificar una cadena se dispone de los siguientes comandos:
-A: añade una regla al final de una cadena.
-I: inserta una nueva regla en una posición dada en una cadena.
-R: reemplaza una cadena dada en una cadena
-D: borra una regla en una cadena, bien usando su número o bien describiendo la regla.

Veamos un pequeño ejemplo práctico: bloquearemos las respuestas PING (es decir el tipo écho-reply' de los paquetes ICMP) que lleguen desde una máquina dada.
Primero, veamos que podemos hacer PING a la máquina dada:

# ping -c 1 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes
64 bytes from 172.16.6.74: icmp_seq=0 ttl=255 time=0.6 ms

--- 172.16.6.74 ping statistics ---

1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.6/0.6/0.6 ms
Ahora, añadimos una regla en la cadena INPUT que interceptará los paquetes que vengan de la máquina 172.16.6.74 ('-s 172.16.6.74') del tipo ICMP-Reply ('-p icmp --icmp-type echo-reply'). Estos paquetes se ignorarán ('-j DROP').
# iptables -A INPUT -s 172.16.6.74 -p icmp --icmp-type echo-reply -j DROP

Hagamos de nuevo ping a la máquina:

# ping -c 3 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes

--- 172.16.6.74 ping statistics ---

3 packets transmitted, 0 packets received, 100% packet loss

Como se esperaba, la respuesta no pasa. Podemos comprobar que se han bloqueado las tres respuestas (3 paquetes, para un total de 252 bytes):

# iptables -L INPUT -v
Chain INPUT (policy ACCEPT 604K packets, 482M bytes)
 pkts bytes target     prot opt in    out     source       destination
  3   252   DROP       icmp --  any   any     172.16.6.74    anywhere

Para volver a la situación inicial, sólo tenemos que borrar la primerar regla de la cadena INPUT:

# iptables -D INPUT 1

Y el PING debería funcionar de nuevo:

# ping -c 1 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes
64 bytes from 172.16.6.74: icmp_seq=0 ttl=255 time=0.6 ms

--- 172.16.6.74 ping statistics ---

1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.6/0.6/0.6 ms
#

¡Funciona!

Puede añadir otras cadenas a las 3 predefinidas (que nunca podrá eliminar) y hacer que cierto tráfico vaya por ellas. Esto puede ser útil, por ejemplo, para impedir reglas duplicadas en varias cadenas.

Pasemos a configurar las reglas necesarias para un cortafuegos mínimo. Permitirá ssh, DNS, http y smtp y nada más.
Para simplificar, los comandos de configuración se han escrito en un script. El script comienza borrando la configuración actual antes de establecer una nueva. Este pequeño truco permite ejecutar el script cuando la configuración está activa sin el riesgo de duplicar reglas.

rc.firewall

#!/bin/sh

# Borrando las reglas
iptables -F
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD


# La cadena se construye según la dirección.
# bad = eth0 (exterior)
# dmz = eth1 (interior)
iptables -X bad-dmz
iptables -N bad-dmz
iptables -X dmz-bad
iptables -N dmz-bad
iptables -X icmp-acc
iptables -N icmp-acc
iptables -X log-and-drop
iptables -N log-and-drop

# Cadena específica utilizada para registrar los paquetes antes de bloquearlos
iptables -A log-and-drop -j LOG --log-prefix "drop "
iptables -A log-and-drop -j DROP

# Los paquetes con el indicador TCP activados se eliminan
# y lo mismo para los que no tienen ningún indicador (a menudo usado por Nmap)
iptables -A FORWARD -p tcp --tcp-flags ALL ALL -j log-and-drop
iptables -A FORWARD -p tcp --tcp-flags ALL NONE -j log-and-drop

# Los paquetes de clases de direcciones reservadas se eliminan
# y lo mismo para multicast
iptables -A FORWARD -i eth+ -s 224.0.0.0/4 -j log-and-drop
iptables -A FORWARD -i eth+ -s 192.168.0.0/16 -j log-and-drop
iptables -A FORWARD -i eth+ -s 172.16.0.0/12 -j log-and-drop
iptables -A FORWARD -i eth+ -s 10.0.0.0/8 -j log-and-drop

# Los paquetes 	que pertenezcan a una conexión ya establecida se aceptan
iptables -A FORWARD -m state --state INVALID -j log-and-drop
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# La cadena se transmite según el correspondiente paquete de origen
iptables -A FORWARD -s $DMZ_ADDR -i $DMZ_IFACE -o $BAD_IFACE -j dmz-bad
iptables -A FORWARD -o $DMZ_IFACE -j bad-dmz
# El resto se ignora
iptables -A FORWARD -j log-and-drop

# ICMPs aceptados
iptables -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type echo-request -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A icmp-acc -j log-and-drop

# Cadena exterior -> interior
# se aceptan correo, DNS, http(s) y SSH
iptables -A bad-dmz -p tcp --dport smtp -j ACCEPT
iptables -A bad-dmz -p udp --dport domain -j ACCEPT
iptables -A bad-dmz -p tcp --dport domain -j ACCEPT
iptables -A bad-dmz -p tcp --dport www -j ACCEPT
iptables -A bad-dmz -p tcp --dport https -j ACCEPT
iptables -A bad-dmz -p tcp --dport ssh -j ACCEPT
iptables -A bad-dmz -p icmp -j icmp-acc
iptables -A bad-dmz -j log-and-drop

# Cadena interior -> exterior
# se aceptan correo, DNS, http(s) y telnet
iptables -A dmz-bad -p tcp --dport smtp -j ACCEPT
iptables -A dmz-bad -p tcp --sport smtp -j ACCEPT
iptables -A dmz-bad -p udp --dport domain -j ACCEPT
iptables -A dmz-bad -p tcp --dport domain -j ACCEPT
iptables -A dmz-bad -p tcp --dport www -j ACCEPT
iptables -A dmz-bad -p tcp --dport https -j ACCEPT
iptables -A dmz-bad -p tcp --dport telnet -j ACCEPT
iptables -A dmz-bad -p icmp -j icmp-acc
iptables -A dmz-bad -j log-and-drop

# Cadenas para la propia máquina
iptables -N bad-if
iptables -N dmz-if
iptables -A INPUT -i $BAD_IFACE -j bad-if
iptables -A INPUT -i $DMZ_IFACE -j dmz-if

# Interfaz externa
# sólo se acepta SSH en esta máquina
iptables -A bad-if -p icmp -j icmp-acc
iptables -A bad-if -p tcp --dport ssh -j ACCEPT
iptables -A bad-if -p tcp --sport ssh -j ACCEPT
ipchains -A bad-if -j log-and-drop

# Interfaz interna
iptables -A dmz-if -p icmp -j icmp-acc
iptables -A dmz-if -j ACCEPT

Unas pocas palabras sobre la calidad de servicio. Linux puede modificar el campo ToS ("Tipo de Servicio") y cambiar su valor para dar al paquete una prioridad distinta. Por ejemplo, el siguiente comando cambia los paquetes SSH salientes para mejorar la respuesta de las conexiones.

iptables -A OUTPUT -t mangle -p tcp --dport ssh -j TOS --set-tos Minimize-Delay

De la misma forma, para las conexines FTP puede usar la opción '--set-tos Maximize-Throughput' para mejorar la tasa de transferencia en detrimento de la interactividad de la sesión.

Ya está. Ahora conoce lo básico para configurar un sistema eficiente de filtrado de paquetes. Sin embargo, tenga en cuenta que un cortafuegos no es la panacea en lo que a seguridad se refiere. Sólo es una preocupación más. Configurar un cortafuegos no le exime de utilizar contraseñas fuertes, actualizar el sistema con los últimos parches de seguridad, utilizar un sistema de detección de intrusos, etc.

 

Referencias

 

Formulario de "talkback" para este artículo

Cada artículo tiene su propia página de "talkback". A través de esa página puedes enviar un comentario o consultar los comentarios de otros lectores
 Ir a la página de "talkback" 

Contactar con el equipo de LinuFocus
© Vincent Renardias, FDL
LinuxFocus.org
Información sobre la traducción:
fr --> -- : Vincent Renardias <vincent(at)renardias.com>
fr --> en: Georges Tarbouriech <gt(at)linuxfocus.org>
en --> es: Roberto Hernando (homepage)

2003-05-14, generated by lfparser version 2.34