Próxima página Página anterior Contenido

4. IP firewalling chains.

Esta sección describe lo que usted realmente necesita saber para construir un filtro de paquetes que satisface sus necesidades.

4.1 Cómo los paquetes atraviesan los filtros.

El Kernel comienza con tres listas de reglas, estas listas son llamadas cadenas (chains) de cortafuegos o simplemente cadenas. Las tres cadenas son llamadas entrada (input), salida (output) y envio (forward). Cuando un paquete entra (digamos, a través de la tarjeta Ethernet) el kernel usa la cadena input para decidir su destino. Si sobrevive este paso, entonces el kernel decide dónde enviar el paquete (esto se llama enrutamiento --routing--). Si el destino es otra máquina, consulta la cadena forward. Finalmente, justo antes de que el paquete salga, el kernel consulta la cadena output.

Una cadena es una lista (de chequeo -- checklist) de reglas. Cada regla dice 'si el encabezado del paquete se ve como esto, entonces esto es lo que deseo hacer con el paquete'. Si la regla no empareja con el paquete, entonces se consulta la próxima regla en la cadena. Finalmente, si no hay ninguna regla más por consultar, entonces el kernel mira la política de la cadena para decidir qué hacer. En un sistema de seguridad-consciente, esta política normalmente le dice al kernel que rechace o deniegue el paquete.

Para los entusiastas del arte ASCII, esto muestra el camino completo que sigue un paquete que entra en una máquina.

        ----------------------------------------------------------------
        |            ACCEPT/                              lo interface |
        v           REDIRECT                  _______                  |
--> C --> S --> ______ --> D --> ~~~~~~~~ -->|forward|----> _______ --> 
    h     a    |input |    e    {Routing }   |Chain  |     |output |ACCEPT
    e     n    |Chain |    m    {Decision}   |_______| --->|Chain  |
    c     i    |______|    a     ~~~~~~~~        |     | ->|_______|
    k     t       |        s       |             |     | |     |    
    s     y       |        q       |             v     | |     |    
    u     |       v        e       v            DENY/  | |     v    
    m     |     DENY/      r   Local Process   REJECT  | |   DENY/
    |     v    REJECT      a       |                   | |  REJECT
    |   DENY               d       --------------------- | 
    v                      e -----------------------------
   DENY                              
Aqui está una descripción muy por encima de cada fase:

Checksum:

En esta fase se comprueba que el paquete no se ha adulterado de alguna manera. Si así pasa, se deniega.

Sanidad:

Realmente hay uno de estos verificadores de sanidad antes de cada cadena del cortafuegos, pero la cadena de entrada (input) es más importante. Algunos paquetes malformados podrían confundir el código de verificación de la regla, y éstos son denegados aquí (un mensaje queda en el syslog si esto pasa).

Cadena de entrada (Input chain):

Ésta es la primera cadena que el cortafuegos probará contra el paquete. Si el resultado de la cadena es no denegar o no rechazar, el paquete sigue adelante.

Desenmascaramiento (Demasquerade) :

Si el paquete es una respuesta a un paquete previamente enmascarado, es desenmascarado, y pasa directamente a la cadena de salida (output chain). Si no usa Ip Masquerading, puede borrar este diagrama mental.

Decisión de Enrutamiento (routing):

El campo del destino es examinado por el código de enrutamiento, para decidir si este paquete debe ser enviado a un proceso local (veáse proceso Local más abajo) o remitido a una máquina remota (veáse Cadena de envio -- forward -- más abajo).

Proceso local:

Un proceso que corre en la máquina puede recibir paquetes después de la fase de decisión de enrutamiento, y puede enviar paquetes (que pasan por la cadena de salida --output chain-- después a la cadena de entrada --input chain-- por medio de la interface 'lo' si están destinados para un proceso local, caso contrario solo atraviesan la cadena de salida). Este cruce entre cadenas por inter-proceso no se muestra totalmente en el diagrama, es demasiado gráfico..

Local:

Si el paquete no fue creado por un proceso local, entonces se verifica la cadena de envio (forward chain), por otra parte el paquete va directamente a la cadena de salida.

Cadena de envio (forward chain):

Esta cadena es atravezada por cualquier paquete que esté intentando pasar a través de esta máquina a otra.

Cadena de salida (output chain):

Esta cadena es atravezada justo antes de ser enviados.

Usando ipchains

Primero, verifique que usted tiene la versión de ipchains a la que este documento se refiere:
$ ipchains --version
ipchains 1.3.5, 26-June-1998
el ipchains tiene una página del manual bastante detallada (man ipchains), y si necesita más detalles particulares, puede comprobar la interface de programación (man 4 ipfw), o el archivo net/ipv4/ip_fw.c en el fuente del kernel 2.1.x que es (obviamente) autoritario.

Hay varias cosas diferentes que puede hacer con ipchains. Primero las operaciones para manejar cadenas enteras. Empieza con la construccion de tres cadenas input, output y forward, las cuales no puede borrar.

  1. Crear una nueva cadena (-N).
  2. Borrar una cadena vacía (-X).
  3. Cambiar la política para una cadena construida. (-P).
  4. Listar las reglas de una cadena (-L).
  5. Vaciar las reglas fuera de una cadena (-F).
  6. Poner a cero el contador de paquete y de byte en todas las reglas en una cadena (-Z).
Hay varias formas de manipular reglas dentro de una cadena:
  1. Añadir una nueva regla a una cadena (-UN).
  2. Insertar una nueva regla en alguna posición en una cadena (-yo).
  3. Reemplazar una regla en alguna posición en una cadena (-R).
  4. Anular una regla en alguna posición en una cadena (-D).
  5. Anular la primera regla que empareja en una cadena (-D).
Hay unas pocas operaciones para enmascarar, que se encuentran en ipchains por la necesidad de un buen sitio para ponerlas:
  1. Listar las conexiones enmascaradas actualmente (-M -L).
  2. Asignar valores de timeout de enmascaramiento (-M -S). ¡(Veáse No puedo asignar timeouts al enmascaramiento! ).
La función final (y quizás la más útil) es la que permite verificar lo que le pasaría a un paquete dado si este atraviesa por una cadena dada.

Operaciones en una sola regla.

Esto es lo práctico de ipchains; manipulación de reglas. En la mayoría de casos, usted probablemente usará los comandos de adicionar (-UN) y borrar (-D). Los otros (-I para insertar y -R para remplazar) son simples extensiones de estos conceptos.

Cada regla especifica un juego de condiciones que el paquete debe cumplir, y qué hacer si se las encuentra (un objetivo -- target-- ). Por ejemplo, usted podría querer denegar todos los paquetes de ICMP que vienen de la dirección IP 127.0.0.1. Así que, nuestras condiciones son: que el protocolo debe ser ICMP y que la dirección orígen debe ser 127.0.0.1. Nuestro objetivo es denegar `DENY '.

127.0.0.1 es la interface de retorno --loopback-- que tendrá aun cuando no tenga ninguna conexión real de red. Usted puede usar el programa `ping ' para generar tales paquetes (envía un ICMP de tipo 8 (echo request) al que todos los host coperativos deben obligatoriamente responder con un paquete ICMP de tipo 0 (echo reply)). Esto es útil para probar:.

# 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

# ipchains -A input -s 127.0.0.1 -p icmp -j DENY
# 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
#
Puede ver aquí que el primer ping fue exitoso (el ` -c 1 ' indica a ping que envie sólo un paquete).

Luego adicionamos (-UN) una cadena `input ', una regla que especifica que para los paquetes que provienen de 127.0.0.1 (-s 127.0.0.1') con protocolo ICMP (-p ICMP) debemos pasar a DENEGAR (` -j DENY').

Luego probamos nuestra regla, usando el segundo ping. Habrá una pausa antes de que el programa deje de esperar por una respuesta que nunca vendrá.

Podemos borrar la regla de cualquiera de dos formas. Primero, puesto que sabemos que es la única regla en la cadena input, podemos usar un borrado numerado, así:

 # ipchains -D input 1
 #
Para borrar la regla número 1 en la cadena input.

La segunda forma es a través del comando -A, pero reemplazando el -A con -D. Esto es útil cuando tiene una cadena compleja de reglas y no quiere tener que contarlos para concluir que es la regla 37 de la que desea librarse. En este caso, usamos:

 # ipchains -D input -s 127.0.0.1 -p icmp -j DENY
 #
La sintaxis de -D debe tener exactamente las mismas opciones como en el comando -A (o -I o -R). Si hay multiples reglas idénticas en la misma cadena, sólo la primero se borrará.

Especificaciones de filtrado.

Hemos visto el uso de ` -p ' para especificar protocolo, y ` -s ' para especificar dirección del orígen, pero hay otras opciones que podemos uar para especificar las características del paquete. Lo que sigue es un compendio exhaustivo.

Especificando direcciones IP orígen y destino.

Direcciones IP de Orígen (-s) y destino (-d) pueden especificarse de cuatro maneras. La manera más común es usar el nombre completo, como `localhost ' o `www.linuxhq.com '. La segunda manera es especificar la dirección IP tal como `127.0.0.1 '.

La tercera y cuarta formas permiten especificar un grupo de direcciones IP, como `199.95.207.0/24 ' o `199.95.207.0/255.255.255.0 '. Estas dos especifican cualquier IP del rango desde 192.95.207.0 hasta 192.95.207.255; los digitos después del ` / ' dicen qué partes de la dirección de IP son significantes. ` /32 ' o ` /255.255.255.255 ' es el valor por defecto (todas las direcciones de IP). Para especificar cualquier IP se puede usar ` /0 ' , así:

 # ipchains -A input -s 0/0 -j DENY
 #
Esto rara vez se usa, puesto que el efecto es el mismo que no especificar la opción ` -s '.

Especificando Inversión (contrarios).

Muchas marcas, incluso las marcas ` -s ' y ` -d ' pueden tener sus argumentos precedidos por `! ' (`pronunciado NOT') para referir a direcciones que no son iguales a las dadas. Por ejemplo ` -s ! localhost' se refiere a cualquier paquete que no proviene del localhost.

Especificando Protocolo.

El protocolo puede especificarse con la marca ` -p '. El protocolo puede ser un número (si usted conoce los valores numéricos de protocolos para IP) o un nombre para los casos especiales de `TCP ', `UDP ' o `ICMP '. No importa mínusculas o mayúsculas, `tcp ' hace lo mismo que `TCP '.

El nombre de protocolo puede estar precedido por '!', para invertirlo, tal como ' -p ! TCP' .

Especificando puertos UDP y TCP.

Para el caso especial donde un protocolo de TCP o UDP se especifica, puede haber un argumento extra que indica el puerto TCP o UDP, o un rango de puertos (Veáse Manejando Fragmentos mas abajo). Un rango es representado usando el caracter ":", como "6000:6010" que cubre 11 números de puerto, desde 6000 hasta 6010. Si se omite el limite inferior, se asigna por defecto 0. Si se omite el límite superior, se asigna por defecto 65535. Así pues, para especificar conexiones de TCP en los puertos por debajo del 1024, la sintáxis sería ' -p TCP -s 0.0.0.0/0 :1024 ' . Los números de puerto pueden ser especificados usando nombre, ej. 'www'.

Note que el puerto especificado puede estar precedido por '!' para indicar lo contrario. Así pues, para especificar todos los paquetes TCP excepto los WWW, lo indicará así:

-p TCP -d 0.0.0.0/0 ! www
Es importante comprender que la especificación
-p TCP -d ! 192.168.1.1 www
es muy diferente de
-p TCP -d 192.168.1.1 ! www
La primera especifica cualquier paquete de TCP al puerto de WWW en cualquier máquina excepto 192.168.1.1. El segundo especifica alguna conexión de TCP a cualquier puerto en 192.168.1.1 excepto el puerto de WWW.

Finalmente, este caso significa que no a los de puerto WWW y no a los de dirección 192.168.1.1:

-p TCP -d ! 192.168.1.1 ! www


Especificando ICMP tipo & código.

ICMP también permite un argumento opcional, puesto que ICMP no tiene puertos, (ICMP tiene un tipo y un código) los cuales tienen un significado diferente.

Puede especificarlos como nombres ICMP (use ipchains -h icmp para listar los nombres) después de la opción ` -s ', o como un tipo y código númerico ICMP, donde el tipo sigue a la opción '-s' y el código sigue a la opción '-d'.

Los nombres de ICMP son bastante largos: sólo necesita usar las letras suficientes para hacer que un nombre sea distinto de otro.

Aquí está una pequeña tabla de algunos de los más comúnes paquetes ICMP:

Número  Nombre                   Requerido por

0       echo-reply               ping
3       destination-unreachable  Any TCP/UDP traffic.
5       redirect                 routing if not running routing daemon
8       echo-request             ping
11      time-exceeded            traceroute
Note que por el momento los nombres de ICMP no pueden ser precedidos por `! '.

NO NO NO bloquee todos los mensajes ICMP tipo 3 (Vea Paquetes ICMP más abajo).

Especificando una interface.

La opción ` -i ' especifica el nombre de una interface para comparar. Una interface es el dispositivo físico por el cual un paquete llega o sale. Puede usar el comando ifconfig para listar las interfaces activas. (ie. que estén funcionando en el momento).

La interface para los paquetes entrantes (ie. paquetes que atraviesan la cadena input) es considearada la interface por donde ellos entran. Lógicamente, la intercace para los paquetes salientes (paquetes que atraviesan la cadena output) es la interface por donde ellos saldrán. La interface para que los paquetes atraviesen la cadena forward es también la interface por donde ellos saldrán; una decisión bastante arbitraria a mi modo de ver.

Es absolutamente legal especificar una interface que actualmente no existe; la regla no emparejará nada hasta la interface sea activada. Esto es sumamente útil para enlaces telefónicos ppp (normalmente interface ppp0) y similares.

Como un caso especial, un nombre de interface que termine con un `+ ' emparejará todas las interfaces (si ellas existen actualmente o no) qué empieza con esa cadena. Por ejemplo, para especificar una regla que se refiere a todas las interfaces PPP entonces se usaría -i ppp+.

El nombre de la interface puede ir precedido por `! ' para indicar un paquete que no empareja con la interface(s) especificada.

Especificando paquetes SYN TCP solamente.

A veces es útil permitir conexiones de TCP en un sentido, pero no en el otro. Por ejemplo, podría permitir conexiones hacia un servidor de WWW externo, pero no las que provienen desde él.

El acercamiento ingenuo sería bloquear paquetes de TCP que vienen del servidor. Desafortunadamente, para que trabajen las conexiones de TCP requieren paquetes que van en ambos sentidos.

La solución es bloquear sólo los paquetes de petición de conexión. A estos paquetes se les llama paquetes SYN (ok, técnicamente son aquellos paquetes con la marca SYN activada (SYN flag) y las marcas FIN y ACK limpias, pero nosotros los llamaremos paquetes SYN). Impidiendo sólo estos paquetes, podemos detener los intentos de conexión .

La marca ` -y ' se usa para esto: es sólo válida para reglas que especifican TCP como su protocolo. Por ejemplo, especificar intentos de conexión TCP desde 192.168.1.1:

-p TCP -s 192.168.1.1 -y
Una vez más, esta marca puede ser invertida precediéndola con un `! ' que significa todos los paquetes restantes a los que inician conexión.

Manejando Fragmentos.

A veces un paquete es demasiado grande para alcanzar en un sola transmisión todo de una vez. Cuando esto pasa, el paquete es dividido en fragmentos , y se envía como múltiples paquetes. En el otro extremo se reensamblan los fragmentos para reconstruir el paquete entero.

El problema con fragmentos es que algunas de las especificaciones que se mencionaron anteriormente (en particular, puerto orígen, puerto destino, tipo ICMP, código ICMP, o marca TCP SYN) requieren que el kernel mire al inicio del paquete, los cuales son contenidos unicamente en el primer fragmento.

Si su máquina es la única conexión a una red externa, entonces puede indicar al kernel que ensamble los fragmentos que lo atraviesan, seteando a 'Y' la opción IP: always defragment. Esto envita el problema limpiamente..

Por otra parte, es importante entender cómo los fragmentos son tratados por las reglas de filtración. Alguna regla que nos pregunte por información que no se tiene, no emparejará. Esto significa que el primer fragmento se trata como cualquier otro paquete. El segundo y siguientes fragmentos no lo serán. Así pues, una regla (especificando un puerto de orígen www) nunca emparejará con un fragmento (más que con el primer fragmento) Segundo y los fragmentos extensos no serán. Así la regla - TCP -s 192.168.1.1 www (especificando un puerto de la fuente de `www ') nunca emparejará un fragmento (otra cosa que el primer fragmento). La regla opuesta tampoco -p TCP 192.168.1.1 ! www

Sin embargo, usted puede especificar una regla específicamente para el segundo y demás, usando la marca ` -f '. Obviamente, es ilegal especificar un puerto TCP o UDP, tipo ICMP, código ICMP o marca TCP SYN tal regla del fragmento.

También es legal especificar que una regla no se aplica para el segundo y demás fragmentos, precediendo ` -f ' con `! '.

Normalmente se tiene en cuenta como seguro para permitir al segundo y demás fragmentos pasar, puesto que el filtrado afectará al primer fragmento, de ese modo previene reensamblar en el host destino, sin embargo, se han detectado bugs que hacen que la máquina falle simplemente por enviar fragmentos.

Note que los encabezados de red: paquetes malformados (paquetes TCP, UDP e ICMP demasiado cortos para que el codigo del cortafuegos lea los puertos o los tipos o códigos ICMP) también son tratados como fragmentos. Sólo los fragmentos TCP que empiezan en la posición 8 son desechados explicitamente por el código de cortafuegos (un mensaje debe aparecer en el syslog si esto ocurre).

Como un ejemplo, la siguiente regla desecha cualquier fragmento que va a 192.168.1.1:


# ipchains -A output -f -D 192.168.1.1 -j DENY

#

Efectos laterales del filtrado.

OK, hasta ahora sabemos todas las formas como podemos emparejar un paquete usando una regla. Si un paquete empareja con una regla, pasa lo siguiente.
  1. El contador de byte para esa regla es aumentado por el tamaño del paquete (encabezado y todo lo demás).
  2. El contador de paquetes para esa regla se incrementa.
  3. Si la regla lo requiere, el paquete es anotado.
  4. Si la regla lo requiere, el campo Type Of Service es cambiado.
  5. Si la regla lo requiere, el paquete es marcado (no en las series 2.0 del kernel).
  6. El objetivo de la regla es examinado para determinar que se hace después con el paquete..
Para variar, los he puesto en orden de importancia.

Especificando un objetivo.

Un objetivo --target-- indica al kernel que hacer con un paquete que empareja con una regla. El ipchains usa '-j' (saltar a) para especificar el objetivo.

El caso más simple es cuando no se ha especificado el objetivo. Este tipo de regla (a menudo llamada regla de "accounting") es útil simplemente para contar un cierto tipo de paquetes. Empareje o no con la regla, el kernel examina la próxima regla en la cadena. Por ejemplo, para contar el número de paquetes provenientes de 192.168.1.1, podemos hacer esto:

# ipchains -A input -s 192.168.1.1
#
(Usando `ipchains -L -v ' podemos ver el contador de bytes y de paquetes asociados con cada regla).

Hay seis objetivos especiales. Los tres primeros, son bastante simples. ACEPTAR (ACCEPT) RECHAZAR (REJECT) y DENEGAR (DENY). ACCEPT permite que el paquete lo atraviese. DENY desecha el paquete como si nunca hubiera sido recibido. REJECT desecha el paquete, pero (si no es un paquete ICMP) genera una respuesta de ICMP al orígen que dice que el destino fue inalcanzable.

El próximo objetivo, MASQ le dice al kernel que enmascare el paquete. Para que esto funcione, su kernel debe ser compilado con Ip Masquerading habilitado. Para mas detalles, ver el IP-Masquerading-HOWTO y el Apéndice Diferencia entre ipchains e ipfwadm Este objetivo solo es válido para los paquetes que atraviesan la cadena forward.

El otro objetivo especial es REDIRECT que le dice al kernel que envie el paquete a un puerto local en lugar de un sitio cualquiera donde fuera dirigido. Puede ser especificado solo para reglas que contienen protocolos TCP y UDP. Opcionalmente, un puerto (nombre o número) puede especificarse después de '-j REDIRECT' lo cual hace que el paquete sea redirigido a un puerto particular incluso si fue direccionado a otro puerto. Este objetivo es válido solo para paquetes que atraviesan la cadena input.

El último objetivo especial es RETURN el cual es similar a descender de la cadena inmediatamente. (Ver Asignando Política más abajo).

Cualquier otro objetivo indica una cadena definida por el usuario (como se describe en Operaciones en una cadena entera más abajo). El paquete empezará atravezando las reglas en esa cadena. Si esa cadena no decide el destino del paquete, entonces una vez que la travesia por esa cadena ha terminado, la travesia se reasume en la próxima regla en la cadena actual.

Considere dos cadenas: input (la cadena construida --built-in--) y Test (una cadena definida por el usuario --user-defined--).

         `input'                         `Test'
        ----------------------------    ----------------------------
        | Rule1: -p ICMP -j REJECT |    | Rule1: -s 192.168.1.1    |
        |--------------------------|    |--------------------------|
        | Rule2: -p TCP -j Test    |    | Rule2: -d 192.168.1.1    |
        |--------------------------|    ----------------------------
        | Rule3: -p UDP -j DENY    |
        ----------------------------

Considere un paquete de TCP que viene desde 192.168.1.1, que va hacia 1.2.3.4. Entra en la cadena input, y se prueba contra la Regla 1: no concuerda. Regla 2: concuerda, y el objetivo es Test, tal que la siguiente regla es la primera de Test. La regla 1 en test concuerda, pero no especifica un objetivo, tal que la próxima regla es examinada, Regla 2. Esta no concuerda, tal que hemos alcanzado el final de la cadena. Regresamos a la cadena input, ahora a la Regla 3, la cual no coincide.

Así que la ruta del paquete es:

                                v    __________________________
         `input'                |   /    `Test'                v
        ------------------------|--/    -----------------------|----
        | Rule1                 | /|    | Rule1                |   |
        |-----------------------|/-|    |----------------------|---|
        | Rule2                 /  |    | Rule2                |   |
        |--------------------------|    -----------------------v----
        | Rule3                 /--+___________________________/
        ------------------------|---
                                v
Vea la sección Cómo Organizar sus reglas de cortafuegos para saber la forma cómo usar eficazmente las cadenas definidas por el usuario.

Anotando paquetes.

Este es un efecto lateral que puede tener el emparejar una regla; puede tener la anotación del paquete emparejado usando la marca '-l'. Usualmente no querrá esto para los paquetes rutinarios, pero es una característica muy útil si desea observar eventos fuera de lo común.

El kernel anota esta información de esta forma:

Packet log: input DENY eth0 PROTO=17 192.168.2.1:53 192.168.1.1:1025
  L=34 S=0x00 I=18 F=0x0000 T=254

Este mensaje de anotación es diseñado para ser conciso, y contener información técnica útil para los gurus de las redes, pero puede ser útil para el resto de nosotros. Se interpreta así:

  1. `input' es la cadena que contiene la regla la cual se ha emparejado con el paquete, causando el mensaje de anotación.
  2. `DENY' es lo que la regla le dice al paquete. Si es '-' entonces la regla no afecta absolutamente al paquete (en reglas de accounting).
  3. `eth0' es el nombre de la interface. Puesto que fue la cadena input, significa que el paquete llegó por 'eth0'.
  4. `PROTO=17' significa que el paquete fue del protocolo 17. Una lista de los números de protocolos se encuentra en '/etc/protocols'. Los más comúnes son 1 (ICMP), 6 (TCP) y 17 (UDP).
  5. `192.168.2.1' significa que la dirección IP de orígen del paquete fue 192.168.2.1.
  6. `:53' significa que el puerto de orígen fue el 53. Mirando en '/etc/services' observa que este es el puerto 'domain' (ej. Es probablemente el puerto de respuesta del DNS). Para UDP y TCP, este número es el puerto de orígen. Para ICMP, es el tipo ICMP. Para otros, será 65535.
  7. `192.168.1.1' es la dirección IP de destino
  8. `:1025' significa que el puerto destino fue el 1025. Para UDP y TCP, este número es el puerto destino. Par ICMP, es el código ICMP. Para otros, será 65535.
  9. `L=34' significa que el paquete tenia una longitud total de 34 bytes.
  10. `S=0x00' significa que el campo Type Of Service (dividir por 4 para obtener el Tipo de Servicio tal como lo usa ipchains).
  11. `I=18' es el ID de IP.
  12. `F=0x0000' es el desplazamiento del fragmento de 16 bits más banderas. Un valor que comience con '0x4' o '0x5' significa que el bit de fragmento no está activo. '0x2' o '0x3' significa que el bit 'More Fragments' (Más fragmentos) está activo; se esperan más fragmentos después de este. El resto de números es el desplazamiento de este fragmento, dividido por 8.
  13. `T=254' es el tiempo de vida (Time To Live) del paquete. Es deducido desde este valor para todo salto, y comunmente empieza en 15 o 255.

En sistemas Linux estándard, esta salida del kernel es capturada por klogd (el demonio de anotación del kernel) el cual lo entrega a syslogd (el demonio de anotación del sistema). El archivo '/etc/syslog.conf' controla el comportamiento de syslogd, porque especifica un destino para cada 'establecimiento -- facility' (en nuestro caso, el establecimiento es "kernel") y 'nivel -- level ' (para ipchains, el nivel usado es "info").

Por ejemplo, mi (Debian) /etc/syslog.conf contiene dos lineas que concuerdan con "kern.info":

kern.*                          -/var/log/kern.log
*.=info;*.=notice;*.=warn;\
        auth,authpriv.none;\
        cron,daemon.none;\
        mail,news.none          -/var/log/messages

Esto significa que los mensajes son duplicados en '/var/log/kern.log' y '/var/log/messages'. Para más detalles, ver 'man syslog.conf'.

Manipulando el Tipo de servicio (Type Of Service)

Hay cuatro bits en el encabezado IP, llamados bits del Tipo de Servicio (TOS). Afectan a la forma como son tratados los paquetes. Los cuatro bits son "Retraso mínimo", "Máximo Throughput", "Fiabilidad Máxima" y "Costo Mínimo". Solo es permitido setear uno de estos bits. Rob van Nieuwkerk, autor del código TOS-mangling, dice:

Especialmente el "Retraso Mínimo" es importante para mí. Lo cambio a "interactivo" en mi router (Linux). Estoy tras un enlace de modem de 33k6. Linux prioriza paquetes en 3 colas. De esta forma obtengo un rendimiento interactivo aceptable mientras mientras se hace descargas pesadas al mismo tiempo. (Incluso podría ser mejor si no hubiese semejante cola en el driver serial, excepto que la latencia se mantiene por debajo de 1.5 segundos).
.
El uso más común es poner las conexiones telnet a "Retraso Mínimo" y los datos FTP a "Máximo Throughput." Esto se haría como sigue:

ipchains -A output -p tcp -d 0.0.0.0/0 telnet -t 0x01 0x10
ipchains -A output -p tcp -d 0.0.0.0/0 ftp -t 0x01 0x10
ipchains -A output -p tcp -s 0.0.0.0/0 ftp-data -t 0x01 0x08
La marca ` -t ' toma dos parámetros extras, ambos en hexadecimal. Éstos permiten un juego completo de los bits de TOS: la primera máscara es con AND con el TOS actual de los paquetes, y luego la segunda máscara es XOR. Si esto lo confunde, simplemente use la siguiente tabla:

	Nombre del TOS          Valor         Usos típicos

      Minimum Delay           0x01 0x10     ftp, telnet
      Maximum Throughput      0x01 0x08     ftp-data
      Maximum Reliability     0x01 0x04     snmp
      Minimum Cost            0x01 0x02     nntp

Marcando un paquete.

No se usa actualmente, pero creo que permitirá poderosas y complejas interacciones con la nueva Quality Of Service de Alexey Kuznetsov, que reemplaza al Traffic Shaper de los kernels v2.1. Por eso es ignorado totalmente en las series 2.0 de kernel.

Operaciones en una cadena entera.

Un rasgo muy útil de ipchains es la habilidad de agrupar reglas relacionadas en las cadenas. Puede llamar a las cadenas como usted quiera, mientras no se llamen como las cadenas contruidas (input output forward) o los objetivos (MASQ REDIRECT ACCEPT DENY REJECT RETURN). Sugiero eviar las mayúsculas completamente, puesto que se pueden usar para futuras ampliaciones. El nombre de la cadena puede estar por encima de los 8 caracteres.

Creando una nueva cadena.

Creemos una nueva cadena. La llamaré. test
# ipchains -N test
#
Es ese simple. Ahora usted puede poner reglas como se detalló anteriormente.

Borrando una cadena.

Borrar una cadena también es simple.
# ipchains -X test
#
¿Por qué ` -X '? Bien, todas las letras buenas fueron tomadas.

Hay un par de restricciones al borrar cadenas: ellas deben estar vacías (vea Vaciando una Cadena más abajo) y ellas no deben ser el objetivo de cualquier otra regla. No puede borrar ninguna de las tres cadenas construidas (input output forward).

Vaciando una cadena.

Hay una manera simple de vaciar todas las reglas de una cadena, usando la orden ` -F '.
 # ipchains -F forward
 #
Si usted no especifica una cadena, entonces todas las cadenas se vaciarán.

Listando una cadena.

Usted puede listar todas las reglas en una cadena usando la orden ` -L '.
# ipchains -L input
Chain input (refcnt = 1): (policy ACCEPT)
target prot opt source destination ports
ACCEPT icmp ----- anywhere anywhere any
# ipchains -L test
Chain test (refcnt = 0):
target prot opt source destination ports
DENY icmp ----- localnet/24 anywhere any
El `refcnt ' listado en Test, es el número de reglas que tiene Test como objetivo. Este debe ser cero (y la cadena está vacía) antes de que la cadena pueda borrarse.

Si el nombre de la cadena se omite, todas las cadenas se listan, incluso las vacías.

Hay tres opciones que pueden acompañar a `-L '. La opción ` -n ' (numérico) es muy útil para prevenir que ipchains intente mirar las direcciones IP, lo cual (si usa DNS como la mayoría de personas) causará grandes retrasos si su DNS no está configurado apropiadamente, o ha filtrado las demandas al DNS. Esto también hace que los puertos sean mostrados como números en lugar de nombres.

La opción ` -v ' muestra todos los detalles de las reglas, tal como los contadores de bytes y de paquetes, las mascaras de TOS, la interface, y la marca del paquete. Caso contrario, estos valores se omiten. Por ejemplo:

# ipchains -v -L input
Chain input (refcnt = 1): (policy ACCEPT)
pkts bytes target prot opt tosa tosx ifname mark source destination ports
 10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any
Note que el contador de bytes y de paquetes se muestran usando los sufijos `K ', `M ' o `G ' para 1000, 1,000,000 y 1,000,000,000 respectivamente. Usando la marca ` -x ' (expandir números) se imprime los números completos, no importa lo grandes que ellos sean.

Restablecimiento (poniendo a cero) los contadores.

Es útil poder restablecer los contadores. Esto puede hacerse con la opción ` -Z ' (zero counters). Por ejemplo:
# ipchains -v -L input
Chain input (refcnt = 1): (policy ACCEPT)
pkts bytes target prot opt tosa tosx ifname mark source destination ports
 10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any
# ipchains -Z input

# ipchains -v -L input
Chain input (refcnt = 1): (policy ACCEPT)
pkts bytes target prot opt tosa tosx ifname mark source destination ports
 0 0 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any
El problema con esto es que a veces usted necesite conocer el valor del contador inmediatamente antes de que ellos se restablezcan. En el ejemplo anterior, algunos paquetes podrían pasar a través de las ordenes ` -L ' y ` -Z ' . Por esta razón, usted puede usar ` -L ' y ` -Z ' juntos, para restablecer a los contadores mientras los lee. Desgraciadamente, si usted hace esto, no puede operar en una sola cadena: tiene que listar y poner a cero todas las cadenas en seguida.
# ipchains -L -v -Z
Chain input (policy ACCEPT):
pkts bytes target prot opt tosa tosx ifname mark source destination ports
 10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any

Chain forward (refcnt = 1): (policy ACCEPT)
Chain output (refcnt = 1): (policy ACCEPT)
Chain test (refcnt = 0):
 0 0 DENY icmp ----- 0xFF 0x00 ppp0 localnet/24 anywhere any

# ipchains -L -v
Chain input (policy ACCEPT):
pkts bytes target prot opt tosa tosx ifname mark source destination ports
 10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any

Chain forward (refcnt = 1): (policy ACCEPT)
Chain output (refcnt = 1): (policy ACCEPT)
Chain test (refcnt = 0):
 0 0 DENY icmp ----- 0xFF 0x00 ppp0 localnet/24 anywherep; any

Estableciendo la Política.

Anteriormente no se dijo lo que pasa cuando un paquete alcanza el final de una cadena construida, en Especificando un Objetivo. En este caso, la política de la cadena determina el destino del paquete. Sólo las cadenas construidas (input output forward) tiene políticas, porque si un paquete llega al final de una cadena definida por el usuario, pasaría a la cadena anterior.

La política puede ser cualquiera de los primeros cuatro objetivos especiales: ACCEPT, DENY REJECT MASQ. MASQ es sólo válido para la cadena `forward '.

También es importante anotar que el objetivo RETURN en una regla de cadenas construidas es útil para especificar el objetivo de la política de la regla cuando un paquete empareja con una regla.

Operaciones en Enmascaramiento.

Hay varios parámetros que usted puede intentar para Ip Masquerading. Ellos se adhieren a ipchains porque no vale la pena hacerlo en una herramienta por separado.

El comando IP Masquerading es ` -M ', y puede combinarse con ` -L ' para listar las conexiones actualmente enmascaradas, o ` -S ' para poner los parámetros de enmascaramiento.

El orden ` -L ' puede ir con ` -n ' (muestre números en lugar de los hostnames y nombres del puerto) o ` -v ' (muestre la secuencia de números para conexión enmascarada).

La orden ` -S ' debe ser seguido por tres valores de timeout, cada uno en segundos: para sesiones TCP, para sesiones TCP después del paquete FIN, y para los paquetes UDP. Si no desea cambiar los valores, simplemente de un valor de '0'.

Los valores predefinidos se listan en ` /usr/include/net/ip_masq.h ', actualmente 15 minutos, 2 minutos y 5 minutos respectivamente.

El valor que se cambia más comúnmente es el primero, para FTP (vea Pesadillas de FTP más abajo).

Note los problemas al poner valores de timeout en No puedo poner timeouts para enmascaramiento.

Verificando un paquete.

A veces usted quiere ver lo que pasa cuando un cierto paquete entra en su máquina, como hacer debug de las cadenas del cortafuegos. ipchains tiene la orden ` -C ' para hacerlo, usando exactamente las mismas rutinas que el kernel usa para diagnosticar paquetes reales..

Usted especifica qué cadena probará el paquete siguiendo el argumento ` -C ' su nombre. Considerando que el kernel siempre empieza atravezando las cadenas input, output y forward, le permite atravezar cualquier cadena para estos propósitos.

Los detalles del `packet ' se especifica usando la misma sintaxis que especifica reglas del cortafuego. En particular, un protocolo (` -p '), dirección del orígen (` -s '), dirección del destino (` -d ') e interface (` -i '). Si el protocolo es TCP o UDP, entonces debe especificarse un solo orígen y un solo puerto del destino, y deben especificarse un tipo y un código de ICMP para el protocolo de ICMP (a menos que la marca ` -f ' se especifique para indicar una regla del fragmento, caso en que estas opciones son ilegales).

Si el protocolo es TCP (y la marca ` -f ' no se especifica), la marca ` -y ' puede especificarse, para indicar que el paquete de la prueba debe tener activo el bit de SYN.

Aquí hay un ejemplo de testeo de un paquete TCP SYN desde 192.168.1.1 puerto 60000 al puerto www de 192.168.1.2, entrando la cadena 'input' (Esta es una clásica iniciación de conexión WWW):

# ipchains -C input -p tcp -y -s 192.168.1.1 60000 -d 192.168.1.2 www
packet accepted

Multiples reglas de una vez y ver lo que pasa.

A veces una simple línea de comando puede ocasionar que múltiples reglas sean afectadas. Esto se hace de dos formas: Primro, si especifica un hostname el cual se resuelve (usando DNS) a múltiples direcciones IP, ipchains actuará como si hubiese tecleado múltiples comandos con cada combinación de direcciones.

Así pues, si el hostname `www.foo.com ' se resuelve a tres direcciones IP, y el hostname 'www.bar.com' se resuelve a dos direcciones IP, entonces el comando `ipchains -A input -j reject -s www.bar.com -d www.foo.com' adicionaría seis reglas a la cadena input.

La otra forma de que ipchains realice acciones múltiples es usar la marca bidireccional (` -b '). Esta marca hace que ipchains se comporte como si usted hubiera tecleado dos veces, en la segunda los argumentos ` -s ' y ` -d ' se invierten. Así, para evitar remisiones (forwarding) hasta o desde 192.168.1.1, podría hacer a lo siguiente:

# ipchains -b -A forward -j reject -s 192.168.1.1
#
Personalmente, no me gusta mucho la opción ` -b '; si desea conveniencia, vea Usando ipchains-save más abajo.

La opción -b puede usarse con las ordenes de inserción (` -I '), borrado (` -D ') (excepto en las variantes que toman un número de la regla), adición (` -A ') y Chequeo (` -C ').

Otra marca útil es ` -v ' (verbose) qué muestra exactamente lo que ipchains está haciendo con los comandos. Es útil cuando esta trabajando con órdenes que pueden afectar a múltiples reglas. Por ejemplo:.

# ipchains -v -b -C input -p tcp -f -s 192.168.1.1 -d 192.168.1.2 -i lo
 tcp opt ---f- tos 0xFF 0x00 via lo 192.168.1.1 -\062 192.168.1.2 * -\062 *
packet accepted
 tcp opt ---f- tos 0xFF 0x00 via lo 192.168.1.2 -\062 192.168.1.1 * -\062 *
packet accepted

4.2 Ejemplos útiles

Tengo una conexión vía telefónica (-i ppp0). Tomo noticias (-p TCP -s news.virtual.net.au nntp) y correo (-p TCP -s
mail.virtual.net.au pop-3) cada vez que me conecto. Uso el método ftp de Debian para actualizar mi máquina regularmente (-p TCP -y -s ftp.debian.org.au ftp-data). Navego en la web a través del proxy de mi ISP mientras tanto (-p TCP -d
proxy.virtual.net.au 8080) , pero odio los anuncios de doubleclick.net en el archivo Dilbert (-p TCP -y -d
199.95.207.0/24 & -p TCP -y -d 199.95.208.0/24).

No me molesta que las personas intenten hacer ftp a mi máquina mientras estoy online (-p TCP -d $LOCALIP ftp) pero no quiero que nadie pretenda obtener una dirección de mi red interna (-s 192.168.1.0/24). Esto es llamado comunmente IP Spoofing, y hay una mejor manera de protegerse a si mismo, desde el kernel 2.1.x y superiores. Ver Cómo seteo la protección de Ip spoofing? .

Esta configuración es bastante simple, ya que no hay ninguna otra máquina en mi red interna.

No quiero que ningún proceso local (ie. Netscape, lince etc.) se conecte con doubleclick.net:

# ipchains -A output -d 199.95.207.0/24 -j REJECT
# ipchains -A output -d 199.95.208.0/24 -j REJECT
Ahora quiero poner prioridades en varios paquetes salientes (no se gana mucho haciendolo en los paquetes entrantes). Puesto que tengo un número justo de estas reglas, tiene sentido ponerlos todos en una sola cadena, llamada. ppp-out
# ipchains -N ppp-out
# ipchains -A output -i ppp0 -j ppp-out
Retraso mínimo para tráfico de web & telnet.
# ipchains -A ppp-out -p TCP -d proxy.virtual.net.au 8080 -t 0x00 0x10
# ipchains -A ppp-out -p TCP -d 0.0.0.0 telnet -t 0x00 0x10
Prioridad baja para los datos del ftp, nntp, pop-3,:
# ipchains -A ppp-out -p TCP -d 0.0.0.0/0 ftp-data -t 0x00 0x02
# ipchains -A ppp-out -p TCP -d 0.0.0.0/0 nntp -t 0x00 0x02
# ipchains -A ppp-out -p TCP -d 0.0.0.0/0 pop-3 -t 0x00 0x02
Hay unas restricciones en paquetes que entran por la interface ppp0: creemos una cadena llamada `ppp-in ':
# ipchains -N ppp-in
# ipchains -A input -i ppp0 -j ppp-in
Ahora, ningún paquete que entra por ppp0 debe estar exigiendo una dirección de orígen 192.168.1. *, así que lo anotamos y los denegamos:
# ipchains -A ppp-in -s 192.168.1.0/24 -l -j DENY
#
Permito conexiones DNS (remito todas las demandas a 203.29.16.1, así que espero respuesta DNS TCP sólo desde ellos), ftp, y retorno ftp-data solamente (las cuales solo deben ir a un puerto superior a 1023, y no a los puertos X11 alrededor de 6000)
# ipchains -A ppp-in -p TCP -s 203.29.16.1 -d $LOCALIP dns -j ACCEPT
# ipchains -A ppp-in -p TCP -s 0.0.0.0/0 ftp-data -d $LOCALIP 1024:5999 -j ACCEPT
# ipchains -A ppp-in -p TCP -s 0.0.0.0/0 ftp-data -d $LOCALIP 6010: -j ACCEPT
# ipchains -A ppp-in -p TCP -d $LOCALIP ftp -j ACCEPT
Finalmente, los paquetes local-a-local están OK:
# ipchains -A input -i lo -j ACCEPT
Ahora, mi política predefinida en la cadena input es DENY, de tal forma que todo lo demás sea desechado.
# ipchains -P input DENY
NOTA: No configuraría mis cadenas en este orden, mientras que los paquetes cruzan en el momento que estoy configurando. Lo más seguro es poner la política de DENY primero, luego insertar las reglas. Por supuesto, que si sus reglas exigen ver al DNS, podría tener problemas.

Usando.ipchains-save

Configurar las cadenas de un cortafuegos como usted lo desea, y luego intentar recordar las ordenes que usted utilizó para hacerlo la próxima vez es doloroso.

Así pues, ipchains-save es un script que lee su actual configuración de cadenas y la graba en un archivo. Por el momento, le dejo la inquietud de lo que podría hacer ipchains-restore

ipchains-save pueda grabar una sola cadena, o todas las cadenas (si ningún nombre de la cadena se especifica). La única opción actualmente permitida es ` -v ' qué imprime las reglas (a stderr) cuando ellas se graban. La política de la cadena también se graba para las cadenas input, output y forward.

$ ipchains-save \062 my_firewall
Saving `input'.
Saving `output'.
Saving `forward'.
Saving `ppp-in'.
Saving `ppp-out'.
$

Usando.ipchains-restore

ipchains-restore restaura cadenas grabadas con ipchains-save Puede tomar dos opciones: ` -v ' qué muestra cada regla mientras se agrega, y ` -f ' qué forza el vaciado de las cadenas definidas por el usuario, si existen.

Si una cadena definida por el usuario se encuentra en la entrada, ipchains-restore verifica si esa cadena ya existe. Si es así, entonces le preguntará si las cadenas deben vaciarse (vaciado de todas las cadenas) o si la restauración de esta cadena debe saltarse. Si usted especifica '-f' en la linea de comandos, usted no será consultado; la cadena se vaciará.

Usted debe ser root para ejecutar este script, ya que usa ipchains para intentar restaurar las reglas.

Por ejemplo:

# ipchains-restore \060 my_firewall
Restoring `input'.
Restoring `output'.
Restoring `forward'.
Restoring `ppp-in'.
Chain `ppp-in' already exists. Skip or flush? [S/f]? s
Skipping `ppp-in'.
Restoring `ppp-out'.
Chain `ppp-out' already exists. Skip or flush? [S/f]? f
Flushing `ppp-out'.

Próxima página Página anterior Contenido