9.10. Comprobación de una configuración del cortafuegos

Después de haber diseñado una configuración de cortafuegos adecuada, es importante comprobar que efectivamente se obtiene lo que se deseaba. Una forma de hacerlo consiste en utilizar un 'host' de prueba fuera de nuestra red para que intente atravesar su cortafuegos: esto puede llegar a resultar farragoso y lento, y se estaría limitado a la comprobación únicamente de aquellas direcciones que realmente puedan usarse.

Un método más rápido y sencillo está disponible con la implementación del cortafuegos de GNU/Linux. Permite generar pruebas y ejecutarlas contra el cortafuegos como si se estuviera haciendo la prueba con datagramas reales. Todas las variedades de software del cortafuegos del núcleo de GNU/Linux, ipfwadm, ipchains, e iptables, dan soporte a este tipo de comprobaciones. La implementación involucra el uso de la orden de comprobación relevante.

El procedimiento general de comprobación es como sigue:

  1. Diseñe y configure su cortafuegos utilizando ipfwadm, ipchains, o iptables.

  2. Diseñe una serie de comprobaciones que determinen si su cortafuegos está realmente funcionando como deseaba. Puede utilizar cualquier dirección de origen o destino para realizar estas comprobaciones, por lo que escoja algunas combinaciones de direcciones que deberían ser aceptadas y otras que deberían ser rechazadas. Si se va a permitir o prohibir a un cierto rango de direcciones, es una buena idea comprobar las direcciones situadas justo en los límites del rango—una dirección justo dentro del rango y otra justo fuera del rango. Esto le ayudará a asegurarse de que configuró correctamente los rangos, pues a veces resulta muy fácil especificar de forma incorrecta las máscaras de su configuración. Si se filtra por número de protocolo y puerto, sus comprobaciones también deberían comprobar todas las combinaciones importantes de estos parámetros. Por ejemplo, si se desea aceptar TCP sólo en ciertas circunstancias, compruebe que se rechazan los datagramas de tipo UDP.

  3. Desarrolle reglas de ipfwadm, ipchains, o iptables para implementar cada comprobación. Probablemente merezca la pena escribir todas estas reglas en un guión de tal forma que pueda hacer y rehacer la comprobación fácilmente a la vez que va corrigiendo los errores o cambiando el diseño. Las comprobaciones utilizan casi la misma sintaxis que las especificaciones de reglas, pero los argumentos tiene significados ligeramente diferentes. Por ejemplo, el argumento de dirección de origen de una especificación de una regla especifica la dirección de origen que deberían tener los datagramas coincidentes con esta regla. En cambio, el argumento de dirección de origen en la sintaxis de comprobación específica la dirección de origen del datagrama de prueba que se generará. En el caso de ipfwadm, debe utilizarse la opción –c para especificar que la orden es una comprobación, mientras que en el caso de ipchains e iptables, se debe utilizar la opción –C. En todos los casos siempre se deben especificar la dirección de origen, la dirección de destino, el protocolo y la interfaz que se utilizará como prueba. El resto de argumentos, como los números de puertos y los valores de los bits de TOS, son opcionales.

  4. Ejecute cada orden de comprobación y anote el resultado. El resultado de cata comprobación consistirá en una única palabra que indicará el blanco final del datagrama después de haber cruzado la configuración del cortafuegos; es decir, dónde terminará el proceso. Para el caso de ipchains e iptables, pueden comprobarse las cadenas de usuario además de las predefinidas.

  5. Compare la salida de cada comprobación contra el resultado deseado. Si encuentra alguna discrepancia, necesitará analizar su conjunto de reglas para determinar dónde cometió el error. Si escribió sus órdenes de pruebas en un fichero de guión, entonces podrá reejecutar la comprobación de forma fácil después de haber corregido cualquier error de la configuración del cortafuegos. Se considera buena práctica borrar por completo sus conjuntos de reglas y reconstruirlas desde cero, en vez de estar realizando cambios dinámicamente. Esto le ayudará a asegurarse de que la configuración activa que está comprobando refleja el conjunto de órdenes de su guión de configuración.

Veamos lo que podría ser la transcripción de una comprobación manual de nuestro ejemplo simple con ipchains. Recuerde que la red local del ejemplo era 172.16.1.0 con una máscara de red de 255.255.255.0, y que se permitían las conexiones de TCP hacia servidores web de fuera de la red. La cadena de reenvío 'forward' no permitía pasar nada más. Empiece con una transmisión que sabemos debería funcionar, una conexión desde el 'host' local a un servidor web de fuera:
    # ipchains -C forward -p tcp -s 172.16.1.0 1025 -d 44.136.8.2 80 -i eth0
    accepted[1]

Fíjese en los argumentos que se han proporcionado y en la forma en que se utilizan para describir el datagrama. La salida de la orden indica que se aceptó el datagrama para su reenvío, que es lo que se esperaba.

Ahora hagamos otra prueba, esta vez con una dirección de origen que no pertenece a nuestra red, y, que por tanto, debería ser rechazada.
    # ipchains -C forward -p tcp -s 172.16.2.0 1025 -d 44.136.8.2 80 -i eth0
    denied[2]

Realice algunas comprobaciones más, con el mismo nivel de detalle que la primera comprobación pero con diferentes protocolos. También deberían ser rechazados:
    # ipchains -C forward -p udp -s 172.16.1.0 1025 -d 44.136.8.2 80 -i eth0
    denied
    # ipchains -C forward -p icmp -s 172.16.1.0 1025 -d 44.136.8.2 80 -i eth0
    denied

Pruebe con otro puerto de destino, de nuevo esperando que sea rechazado:
    # ipchains -C forward -p tcp -s 172.16.1.0 1025 -d 44.136.8.2 23 -i eth0
    denied

Tendrá que recorrer un largo camino para estar tranquilo pues tendrá que diseñar una serie de comprobaciones muy exhaustiva. Aunque a veces esto resulta tan complicado como el diseño de la propia configuración del cortafuegos, también es la mejor forma de saber si su diseño proporciona la seguridad que esperaba.

Notas

[1]

N. del T.: "aceptado"

[2]

N. del T.: "rechazado"