0.1 Filtrado de paquetes en Linux

El filtrado de paquetes es una t’ecnica que consiste, normalmente, en descartar aquellos paquetes que llegan (salen) hasta (desde) nuestro host a un puerto o con un contenido no deseado. En el primer caso los paquetes se filtran atendiendo al puerto al que van dirigidos (por ejemplo, todo lo que no vaya al puerto 80 deber’ia ser ignorado si un servidor s’olo deber’ia ofrecer servicio Web). En el segundo el payload de los paquetes es analizado y dependiendo de este pueden ser eliminados (por ejemplo, todo aquel paquete que utilice el protocolo del eMule deber’ia ser destru’ido). Otra situaci’on muy com’un puede ser no transmitir paquetes que vengan o vayan desde o hacia un determinado rango de direcciones IP.

El filtrado de paquetes se realiza normlamente en los cortafuegos. Por ejemplo, en la universidad se filtran todos los paquetes de entrada que no provengan del tr’afico Web o SSH, y se analiza el contenido de los paquetes para eliminar el tr’afico generado por la mayor’ia de las aplicaciones P2P de compartici’on de ficheros (como eMule). Sin embargo, existen situaciones donde esto no es suficiente. Qu’e pasar’ia si los paquetes no deseados llegan desde otro host situado en la misma red que la nuestra y cuyo tr’afico no es filtrado por el cortafuegos?

0.1.1 En Linux el filtrado de paquetes se realiza a nivel del kernel

Para controlar c’omo se filtran los paquetes el kernel utiliza una tabla de filtrado de paquete y la utilidad que permite manipularla se llama iptables. Por tanto, el kernel ha debido ser compilado con esta opci’on o habr’a que cargar el m’odulo correspondiente. Finalmente, la utilidad de la que hablamos deber’a estar instalada.

Habilitando el kernel El kernel se habilita para filtrar paquetes cuando cargamos el m’odulo iptable_filter. Esto se hace escribiendo:

root# insmod iptable_filter

o modificando el fichero correspondiente para que dicha carga se haga cuando la m’aquina arranca.

Si por lo que sea no queremos habilitar el kernel cargando el m’odulo correspondiente s’olo nos queda la opci’on de compilar uno nuevo y usarlo.

Instalaci’on de iptables

Debian Linux:
 
root# apt-get install iptables

Fedora Core Linux:
 
root# yum install iptables

Gentoo Linux:
 
root# emerge iptables

0.1.2 El proceso de filtrado

El kernel maneja tres listas de reglas en su tabla de filtrado de paquetes. Las listas se llaman tambi’en cadenas (chains, en ingl’es). Bien, en concreto las cadenas que manejaremos se llaman input, output and forward.

Input controla los paquetes que entran en el host, output los que son generados en el host y lo avandonan y forward los que vienen desde el exterior pero no van dirigidos a ning’un proceso del host. Una figura (http://www.netfilter.org/documentation/HOWTO/packet-filtering-HOWTO-6.html) aclara el tema:

                          _____  
Incoming                 /     \          Outgoing  
Packets ->[Routing ]--->|FORWARD|-------> Packets  
          [Decision]     \_____/        ^  
               |                        |  
               v                       ____  
              ___                     /    \  
             /   \                   |OUTPUT|  
            |INPUT|                   \____/  
             \___/                       ^  
               |                         |  
               +----> Local Process -----+

As’i, cada vez que un paquete alcanza una cadena se utiliza una lista de reglas para saber si abandonamos (drop, en ingl’es) o aceptamos el paquete.

Finalmente indicar que la lista forward se utiliza s’olo cuando configuramos nuestro host como un router (o NAT) con cortafuegos.

0.1.3 Uso de iptables

Mostrar la lista de reglas de una cadena

root# iptables --list  
Chain INPUT (policy ACCEPT)  
target     prot opt source               destination  
 
Chain FORWARD (policy ACCEPT)  
target     prot opt source               destination  
 
Chain OUTPUT (policy ACCEPT)  
target     prot opt source               destination  
 
root# iptables --verbose --list INPUT  
Chain INPUT (policy ACCEPT 115 packets, 15731 bytes)  
pkts bytes target     prot opt in     out     source               destination

Crear una nueva cadena Aparte de las tres cadenas que existen por defecto (INPUT, OUTPUT y FORWARD), el usuario puede crear cadenas nuevas:

root# iptables --new new_chain

As’i, cuando un paquete “acierta” con una regla de una cadena, la acci’on puede ser que pase a ser procesado por la nueva cadena. Esto se hace para reducir el n’umero de reglas por cadena y que as’i sean m’as f’aciles de manejar.

Si ninguna de las reglas de la nueva cadena procesa el paquete, el proceso de chequeo contin’ua por la siguiente regla que referenciaba a la nueva cadena.

Resetear las estad’isticas de una cadena Pone a cero los contadores de la cadena:

root# iptables --zero chain_name

Cambiar el comportamiento por defecto de una cadena Por defecto las cadenas INPUT, OUTPUT y FORWARD est’an en modo ACCEPT, significando que dejan pasar los paquetes. Esto puede modificarse cambiando lo que define como “policy” de la cadena. Un ejemplo que evita que podamos transmitir ning’un paquete:

root# iptables --policy OUTPUT DROP

Los posibles modos de una regla o de una cadena son:

ACCEPT:
Aceptar el paquete.
DROP:
Destruir el paquete.
REJECT:
Destruir el paquete pero enviando un paquete ICMP de puerto inalcanzable.
QUEUE:
Pasar al paquete al espacio de usuario. Se utiliza para procesar los paquetes que llegan por un determinado proceso, independientemente de que vayan o no dirigidos a ’el.
RETURN:
Retornar (sin chequear m’as reglas) a la canena que nos di’o el control.

Vaciar una cadena Para eliminar las reglas de una cadena, escribir:

root# iptables --flush chain_name

Borrar una cadena vac’ia Podemos borrar una cadena vac’ia con:

root# iptables --delete-chain chain_name

A nadir una nueva regla a una cadena En el siguiente ejemplo se filtra todo aquel paquete que vaya dirigido a la direcci’on 127.0.0.1:

root# ping -c 1 127.0.0.1  
PING 127.0.0.1 (127.0.0.1): 56 data bytes  
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms  
 
--- 127.0.0.1 ping statistics ---  
1 packets transmitted, 1 packets received, 0% packet loss  
round-trip min/avg/max = 0.2/0.2/0.2 ms  
 
root# iptables --append INPUT --source 127.0.0.1 --protocol icmp --jump DROP  
# ping -c 1 127.0.0.1  
PING 127.0.0.1 (127.0.0.1): 56 data bytes  
 
--- 127.0.0.1 ping statistics ---  
1 packets transmitted, 0 packets received, 100% packet loss  
 
root# iptables --verbose --list INPUT  
Chain INPUT (policy ACCEPT 169 packets, 21274 bytes)  
pkts bytes target     prot opt in     out     source                destination  
1    84    DROP       icmp --  any    any     localhost.localdomain anywhere

Borrar una regla de una cadena Borraremos la regla que acabamos de crear con:

root# iptables --delete INPUT 1

O tambi’en con:

root# iptables --delete INPUT --source 127.0.0.1 --protocol icmp --jump DROP

N’otese que los argumentos son id’enticos a los que utilizamos para crear la regla.

A nadiendo reglas m’as complejas Algunos de los par’ametros con los que podemos jugar son (v’ease [2] y [1] para m’as informaci’on):

Las direcciones IP de origen y destino:
Por ejemplo, podemos especificar s’olo los paquetes que van dirigidos a la red local puedan salir del host:
root# iptables --append OUTPUT --destination ! 192.168.213.0/24 --jump DROP

El protocolo utilizado:
Ejemplo, s’olo el tr’afico Web de entrada est’a permitido:
# N’otese el flag --syn que ‘‘matches’’ s’olo los paquetes TCP  
# de establecimiento de conexi’on  
root# iptables --append INPUT --protocol tcp --syn --dport ! http --jump REJECT

El puerto utilizado:
S’olo aquellos paquetes que vayan al puerto 22 (SSH) ser’an aceptados:
root# iptables --append INPUT --protocol tcp --syn --dport ! 22 --jump ACCEPT

El interface de red usado:
Esto es ’util cuando estamos creando un router o un NAT. Ejemplo, aceptar todo lo que venga de eth0:
root# iptables --append INPUT --in-interface eth0 --jump ACCEPT

Salvando y restaurando las cadenas Existen dos comandos para hacer esto: iptables-save y iptables-restore. Ambas leen y escriben la entrada y salida est’andares. Ejemplos:

root# iptables-save > iptables.txt  
 
root# iptables-restore < iptables.txt

Configure iptables para aceptar s’olo el tr’afico Web.

Bibliography

[1]   Oskar Andreasson. Iptables tutorial. http://www.frozentux.net/documents/iptables-tutorial.

[2]   Rusty Russell. Linux 2.4 Packet Filtering HOWTO. http://www.netfilter.org/documentation/HOWTO/packet-filtering-HOWTO.html.