10.2. Configurando Contabilidad IP

Debido a que la contabilidad IP se relaciona estrechamente con el cortafuegos de IP, la misma herramienta fue designada para configurarla, de modo que ipfwadm, ipchains o iptables sean utilizados para configurar la contabilidad IP. La sintaxis de órdenes es muy similar a la de las reglas del cortafuegos, así que no nos centraremos en eso, pero discutiremos qué puede descubrir sobre la naturaleza de su tráfico de red utilizando esta característica.

La sintaxis general para contabilidad IP con ipfwadm es:
    # ipfwadm -A [sentido] [orden] [parámetros]

El argumento sentido es nuevo. Esto se codifica simplemente como entrada (in), salida (out), o ambos (both). Estas trayectorías son desde la perspectiva de la propia máquina GNU/Linux. entrada (in) se refiere a datos que entran a la máquina desde una conexión de red y salida (out) se refiere a datos que están transmitiéndose por este nodo en una conexión de red. El sentido ambos (both) es la suma de ambas trayectorias, entrante y saliente.

La sintaxis general para la orden ipchains e iptables es:
    # ipchains -A cadena especificación-de-regla
    # iptables -A cadena especificación-de-regla

Las órdenes ipchains e iptables permiten especificar el sentido de una manera más consistente con las reglas de cortafuegos. El cortafuegos de cadenas IP[1] no le permite configurar una regla que agrege ambos sentidos, pero permite configurar reglas en la cadena forward que la antigua implementación no hacía. Veremos la diferencia que produce, en algunos ejemplos un poco mas adelante.

Las órdenes son bastante iguales a las reglas de cortafuegos, excepto que las políticas de reglas no se aplican aquí. Podemos agregar, insertar, eliminar y listar las reglas de contabilidad. En el caso de ipchains e iptables, todas las reglas válidas son reglas de contabilidad, y cualquier orden que no especifica la opción -j sólo realiza recuento.

Las reglas de especificación de parámetros para contabilidad IP son las mismas que aquellas usadas para cortafuegos IP. Éstas son las que nosotros usamos para definir precisamente qué tráfico de la red deseamos contabilizar y sumar.

10.2.1. Contabilidad por Dirección

Trabajemos con un ejemplo para ilustrar como usaríamos la contabilidad IP.

Imagine que tenemos un encaminador basado en Linux que sirve a dos departamentos en la Cervecería Virtual. El encaminador tiene dos dispositivos Ethernet, eth0 y eth1, cada uno de los cuales sirve a un departamento; y un dispositivo PPP, ppp0, que nos conecta vía un enlace serie de alta velocidad al campus principal de la Universidad Groucho Marx.

También imaginemos que para propósitos de faturación queremos conocer el total de tráfico generado por cada uno de los departamentos a lo largo del enlace serie, y para propósitos de administración queremos conocer el total de tráfico generado entre los dos departamentos.

La siguiente tabla muestra las interfaces y direcciones que usaremos en nuestro ejemplo:

Para responder a la pregunta, “¿ Cuántos datos genera cada departamento en el enlace PPP ?”, podríamos usar una regla parecida a:
    # ipfwadm -A both -a -W ppp0 -S 172.16.3.0/24 -b
    # ipfwadm -A both -a -W ppp0 -S 172.16.4.0/24 -b
o:
    # ipchains -A input -i ppp0 -d 172.16.3.0/24
    # ipchains -A output -i ppp0 -s 172.16.3.0/24
    # ipchains -A input -i ppp0 -d 172.16.4.0/24
    # ipchains -A output -i ppp0 -s 172.16.4.0/24
y con iptables:
    # iptables -A FORWARD -i ppp0 -d 172.16.3.0/24
    # iptables -A FORWARD -o ppp0 -s 172.16.3.0/24
    # iptables -A FORWARD -i ppp0 -d 172.16.4.0/24
    # iptables -A FORWARD -o ppp0 -s 172.16.4.0/24

La primera mitad de cada una de estas reglas dice, “Cuente todos los datos viajando en cualquier dirección por la interfaz llamada ppp0 con una dirección origen o destino (recuerde la función de la bandera -b en ipfwadm e iptables) de 172.16.3.0/24.” La segunda mitad de cada conjunto de reglas es la misma, pero para la segunda red Ethernet en nuestro sitio.

Para responder a la segunda pregunta , “¿ Cuántos datos viajan entre los dos departamentos ?”, necesitamos una regla como esta:
    # ipfwadm -A both -a -S 172.16.3.0/24 -D 172.16.4.0/24 -b
o:
    # ipchains -A forward -s 172.16.3.0/24 -d 172.16.4.0/24 -b
o:
    # iptables -A FORWARD -s 172.16.3.0/24 -d 172.16.4.0/24
    # iptables -A FORWARD -s 172.16.4.0/24 -d 172.16.3.0/24
Estas reglas contarán todos los datagramas con una dirección origen perteneciente a una de las redes de departamento y una dirección destino perteneciente a la otra.

10.2.2. Contabilidad por el Puerto de Servicio

Bien, supongamos que también queremos una mejor idea de qué tipo de tráfico exactamente está transportándose por nuestro enlace PPP. Por ejemplo, nosotros podríamos querer saber cuánto del enlace están consumiendo los servicios FTP, SMTP, y Web.

Un guión de reglas para permitirnos coleccionar esta información podría parecerse a:
    #!/bin/sh
    # Coleccionar estadísticas de volumen FTP, SMTP y WWW para los datos
    # transportados en nuestro enlace PPP utilizando ipfwadm
    #
    ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 ftp ftp-data
    ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 smtp
    ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 www
o:
    #!/bin/sh
    # Coleccionar estadísticas de volumen FTP, SMTP y WWW para los datos
    # transportados en nuestro enlace PPP utilizando ipchains
    #
    ipchains -A input -i ppp0 -p tcp -s 0/0 ftp-data:ftp
    ipchains -A output -i ppp0 -p tcp -d 0/0 ftp-data:ftp
    ipchains -A input -i ppp0 -p tcp -s 0/0 smtp
    ipchains -A output -i ppp0 -p tcp -d 0/0 smtp
    ipchains -A input -i ppp0 -p tcp -s 0/0 www
    ipchains -A output -i ppp0 -p tcp -d 0/0 www
o:
    #!/bin/sh
    # Coleccionar estadísticas de volumen FTP, SMTP y WWW para los datos
    # transportados en nuestro enlace PPP utilizando iptables
    #
    iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport ftp-data:ftp
    iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport ftp-data:ftp
    iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport smtp
    iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport smtp
    iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport www
    iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport www

Hay un par de rasgos interesantes a esta configuración. Primeramente, hemos especificado el protocolo. Cuando especificamos puertos en nuestras reglas, también debemos especificar un protocolo porque TCP y UDP proveen conjuntos separados de puertos. Ya que todos estos servicios están basados en TCP, lo hemos especificado como el protocolo. Segundo, tenemos especificado dos servicios ftp y ftp-data en un comando. ipfwadm permite establecer puertos simples, rango de puertos o una lista arbitraria de puertos. La orden ipchains permite cualesquiera, puertos simples o rango de puertos, que es lo que hemos usado aquí. La sintaxis “ftp-data:ftp” significa “puertos ftp-data (20) hasta ftp (21),” y es como nosotros codificamos rangos de puertos en ambos: ipchains e iptables. Cuando usted tiene una lista de puertos en una regla de contabilidad, eso significa que cualquier dato recibido para alguno de los puertos en la lista, provocará que el dato sea sumado a los totales de esa entrada. Recordando que el servicio FTP utiliza dos puertos, el de órdenes y el de transferencia de datos, los hemos añadido a la vez para sumar el tráfico de FTP. Finalmente, especificamos la dirección origen como “0/0”, que es la notación especial que coincide con todas las direcciones y es requerida por ambas órdenes ipfwadm e ipchains para especificar los puertos.

Podemos extendernos un poco en el segundo punto para darnos una vista diferente de los datos en nuestro enlace. Ahora imaginemos que nosotros clasificamos tráfico FTP, SMTP, y del Web como tráfico esencial, y todo el otro tráfico como no esencial. Si nosotros estuviéramos interesados en ver la proporción del tráfico esencial al tráfico no esencial, podríamos hacer algo como:
    # ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 ftp ftp-data smtp www
    # ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 1:19 22:24 26:79 81:32767

Si ya ha examinado su fichero /etc/services, observará que la segunda regla cubre todos los puertos excepto (ftp, ftp-data, smtp, y www).

¿Cómo hacemos esto con las órdenes ipchains o iptables, puesto que ellas permiten sólo un argumento en la especificación de puerto ?. Podemos aprovecharnos en contabilidad, de las cadenas definidas por usuario tan fácil como en las reglas del cortafuegos. Considere el siguiente acercamiento:

    # ipchains -N a-essent
    # ipchains -N a-noness
    # ipchains -A a-essent -j ACCEPT
    # ipchains -A a-noness -j ACCEPT
    # ipchains -A forward -i ppp0 -p tcp -s 0/0 ftp-data:ftp -j a-essent
    # ipchains -A forward -i ppp0 -p tcp -s 0/0 smtp -j a-essent
    # ipchains -A forward -i ppp0 -p tcp -s 0/0 www -j a-essent
    # ipchains -A forward -j a-noness
Aquí creamos dos cadenas definidas por usuario, una llamada a-essent, donde capturamos datos de contabilidad para servicios esenciales y otra llamada a-noness, donde capturamos datos de contabilidad para servicios no esenciales. Entonces agregamos a nuestra cadena forward las reglas que coinciden con nuestros servicios esenciales y saltan a la cadena a-essent, donde tenemos justamente una regla que acepta todos los datagramas y los cuenta. La última regla en nuestra cadena forward es una regla que salta a nuestra cadena a-noness, donde otra vez tenemos solamente una regla que acepta todos los datagramas y los cuenta. La regla que salta a la cadena a-noness no será alcanzada por ninguno de nuestros servicios esenciales, puesto que ellos se habrán aceptado en su propia cadena. Nuestras cuentas para servicios esenciales y no esenciales estarán por consiguiente disponibles en las reglas dentro de esas cadenas. Éste es simplemente un acercamiento que podría tomar; hay otros. Nuestra implementación iptables del mismo acercamiento se parecería a:
    # iptables -N a-essent
    # iptables -N a-noness
    # iptables -A a-essent -j ACCEPT
    # iptables -A a-noness -j ACCEPT
    # iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport ftp-data:ftp -j a-essent
    # iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport smtp -j a-essent
    # iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport www -j a-essent
    # iptables -A FORWARD -j a-noness

Esto parece bastante simple. Desafortunadamente, hay un pequeño pero inevitable problema al intentar efectuar contabilidad por el tipo de servicio. Recordará que discutimos el rol que desempeña la MTU en redes TCP/IP en un capítulo anterior. La MTU define el datagrama más largo que se transmitirá en un dispositivo de red. Cuando un datagrama se recibe por un encaminador que es más grande que el MTU de la interfaz que necesita al retransmitirlo, el encaminador realiza un truco llamado fragmentación. El encaminador fragmenta el datagrama largo en piezas pequeñas no más largos que la MTU de la interfaz y entonces transmite éstas piezas. El encaminador construye nuevas cabeceras para poner delante de cada una de estas piezas, y éstas son las que la máquina remota usa para reconstruir el dato original. Desafortunadamente, durante el proceso de fragmentación el puerto se pierde para todos menos para el primer fragmento. Esto significa que la contabilidad IP no puede contar adecuadamente datagramas fragmentados. Puede contar fiablemente sólo el primer fragmento o datagramas no fragmentados. Hay un pequeño truco permitido por ipfwadm que asegura que mientras nosotros no podamos saber exactamente desde qué puerto el segundo y siguientes fragmentos vienen, podemos todavía contarlos. Una temprana versión del software de contabilidad Linux asignó a los fragmentos un número de puerto falso, 0xFFFF, que podríamos contar. Para asegurarnos que capturamos el segundo y posteriores fragmentos, podemos usar una regla como ésta:
    # ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 0xFFFF

La implementación de cadenas IP tiene una solución ligeramente más sofisticada, pero el resultado es muy similar. Usando la orden ipchains usaríamos en cambio:
    # ipchains -A forward -i ppp0 -p tcp -f
y con iptables usaríamos:
    # iptables -A FORWARD -i ppp0 -m tcp -p tcp -f

Éstos no nos dirán el puerto original para estos datos, pero por lo menos podemos ver cuanto de nuestros datos son fragmentos, y seremos capaces de contabilizar el volumen de tráfico que ellos consumen.

En núcleos 2.2 podemos seleccionar una opción del núcleo en tiempo de compilación, que niega este problema completo si su máquina GNU/Linux está actuando como el único punto de acceso para una red. Si habilita la opción IP: Desfragmentar siempre cuando compila su núcleo, todos los datagramas recibidos serán reensamblados por el encaminador Linux antes de encaminar y retransmitir. Esta operación es realizada antes que el software de contabilidad y cortafuegos miren el datagrama, y así no tendrá trato con ningún fragmento. En núcleos 2.4 usted puede compilar y cargar el módulo netfilter forward-fragment.

10.2.3. Contabilidad de Datagramas ICMP

El protocolo ICMP no usa número de puerto de servicio y es por eso un poco más dificultoso coleccionar detalles. ICMP usa un número de tipos diferentes de datagramas. Muchos de éstos son inofensivos y normales, mientras otros sólo deben observarse bajo circunstancias especiales. A veces las personas con mucho tiempo en sus manos intentan maliciosamente deteriorar el acceso de un usuario a la red, generando grandes cantidades de mensajes ICMP. Esto es comúnmente denominado saturamiento ping[2]. Aun cuando la contabilidad IP no puede hacer nada para prevenir este problema ( ¡ Aunque el cortafuegos IP puede ayudar ! ) podemos al menos colocar reglas de contabilidad en un lugar que nos muestre si alguien lo ha estado intentando.

ICMP no usa los puertos como lo hacen TCP y UDP. En cambio ICMP tiene mensajes tipo ICMP. Podemos construir reglas de contabilidad para cada tipo de mensaje ICMP. Para hacer esto, colocamos el mensaje ICMP y el número del tipo en lugar del puerto en la orden de contabilidad ipfwadm. Listamos los tipos de mensaje ICMP en “Sección 9.6.3.5” refíerase a él si usted necesita recordar cuáles son.

Una regla de contabilidad IP para coleccionar información sobre el volumen de datos ping que está enviándose a usted o que usted está generando podría verse como:
    # ipfwadm -A both -a -P icmp -S 0/0 8
    # ipfwadm -A both -a -P icmp -S 0/0 0
    # ipfwadm -A both -a -P icmp -S 0/0 0xff
o, con ipchains:
    # ipchains -A forward -p icmp -s 0/0 8
    # ipchains -A forward -p icmp -s 0/0 0
    # ipchains -A forward -p icmp -s 0/0 -f
o, con iptables:
    # iptables -A FORWARD -m icmp -p icmp --sports echo-request
    # iptables -A FORWARD -m icmp -p icmp --sports echo-reply
    # iptables -A FORWARD -m icmp -p icmp -f
La primera regla colecciona información sobre datagramas “Petición de eco ICMP” (petición ping) [3], y la segunda regla colecciona información sobre datagramas “Respuesta de eco ICMP” (respuesta ping). La tercera regla colecciona información sobre fragmentos de datagrama ICMP. Este es un truco similar al descrito para fragmentos de datagramas TCP y UDP.

Si usted especifica la dirección origen y/o destino en sus reglas, puede seguir la pista de dónde están viniendo los ping, tales como si ellos se originan dentro o fuera de su red. Una vez que ha determinado de dónde están viniendo los datagramas pillos, usted puede decidir si quiere poner reglas de cortafuegos en un sitio para evitarlos o tomar alguna otra acción, como avisar al dueño de la red agraviante para avisarles del problema, o quizás incluso, acción legal si el problema es un acto malévolo.

10.2.4. Contabilidad por Protocolo

Imaginemos ahora que estamos interesados en conocer cuánto tráfico en nuestro enlaces es TCP, UDP, e ICMP. Usaríamos reglas como las siguientes:
    # ipfwadm -A both -a -W ppp0 -P tcp -D 0/0
    # ipfwadm -A both -a -W ppp0 -P udp -D 0/0
    # ipfwadm -A both -a -W ppp0 -P icmp -D 0/0
o:
    # ipchains -A forward -i ppp0 -p tcp -d 0/0
    # ipchains -A forward -i ppp0 -p udp -d 0/0
    # ipchains -A forward -i ppp0 -p icmp -d 0/0
o:
    # iptables -A FORWARD -i ppp0 -m tcp -p tcp
    # iptables -A FORWARD -o ppp0 -m tcp -p tcp
    # iptables -A FORWARD -i ppp0 -m udp -p udp
    # iptables -A FORWARD -o ppp0 -m udp -p udp
    # iptables -A FORWARD -i ppp0 -m icmp -p icmp
    # iptables -A FORWARD -o ppp0 -m icmp -p icmp
Con estas reglas situadas, todo el tráfico fluyendo por la interfaz ppp0 será analizado para determinar si es TCP, UDP, o tráfico de IMCP y los contadores apropiados serán actualizados para cada uno. El ejemplo con iptables divide el flujo entrante del flujo saliente como lo exige su sintaxis.

Notas

[1]

Traducción de IP Chains Firewall. N. del T.

[2]

Traducción de ping flooding N. del T.

[3]

Traducción de ICMP Echo Request. N. del T.