![]()
Por:
Luis Miguel Diaz Vizcaino
A continuación se explica de forma mas a menos resumida como configurar un script de IPChains, que permite filtrar trafico de forma muy sencilla bajo cualquier sistema operativo basado en Linux. Este filtrado es clásico, permitiendo el análisis de direcciones de origen o destino y puertos, además de comprobaciones de protocolo de nivel 4 y bits de estado (SYN/FIN o el bit de fragmentación).
A.1-Nociones Básicas
Básicamente, las reglas se aplican a los paquetes que entran (input) en un interfaz, que salen (output) de un interfaz o que pasan (forward) de un interfaz a otro. De esta forma, un paquete que vaya a ser enrutado por el equipo, entrara por un interfaz, pasara de uno a otro y finalmente saldrá por otro, pudiendo ser objetivo de los 3 tipos de reglas que haya definidas, mientras que un paquete que se dirija a la misma maquina solo podrá ser objetivo de reglas bajo el tipo input.
Una vez sabemos las categorías (chains) generales bajo las que se pueden adscribir las reglas de filtrado, pasamos a ver que se puede hacer con un paquete que concuerde con una regla (target).
Principalmente, las opciones (targets) son ACCEPT, DENY o REJECT. La primera permite que el paquete pase el filtro (ya sea de entrada, salida o forward), mientras que la segunda y tercera descartan el paquete. Existe una sutil diferencia entre DENY y REJECT, que consiste en que con DENY el paquete se tira sin mas acciones mientras que con REJECT se genera un mensaje ICMP indicando que la conexión se ha rechazado. Esta ultima opción solo es útil en determinadas circunstancias, por lo que como regla general se utilizara DENY, evitando de esta forma el exceso de información a un posible ataque externo. REJECT solo es útil para servicios que, por ejemplo, utilizan algún tipo de identificación previa que no es imprescindible. Con REJECT se deniega el intento de identificación y el servicio continua normalmente, mientras que si usamos DENY el servidor intentaría la identificación varias veces y finalmente concluiría que la maquina se ha caído, y cerraría la conexión (inutilizando el servicio).
Existen otras tres opciones que también se usan poco: MASQ, REDIRECT y RETURN. MASQ (valido únicamente en forward) permite el uso de una red enmascarada siempre y cuando el Kernel tenga activado CONFIG_IP_MASQUERADE. Con esta opción, el paquete se modifica de forma que parece haberse originado en el interfaz por el que quería salir, ocultando el verdadero origen. Esta opción es muy común en redes que solo tienen una dirección IP verdadera y tienen muchas maquinas conectadas, identificadas por direcciones IP no enrutables. también se usa para salvaguardar las direcciones internas, de forma que no se pueda acceder desde el exterior de forma directa a estas direcciones, y que sean desconocidas para el mundo exterior, aunque esto provoca, en principio, que no se pueda ejecutar ningún servidor en el interior (existen herramientas que permiten resolver el problema).
REDIRECT solo se usa en la opción input, y necesita tener activada la opción CONFIG_IP_TRANSPARENT_PROXY en el Kernel. Los paquetes que concuerden con una regla REDIRECT se redirigen a un socket local aunque su destino fuese remoto. Esta opción no es común, pero es imprescindible para usar un servidor transparente de Web Cache, que permite usar un servidor de esta características sin necesidad de reconfigurar cada Browser individualmente. Se redirigen todas las peticiones Web al servidor de cache local, salvo aquellas que provienen del propio servidor (peticiones a paginas Web que no están en cache), que se dejan salir al exterior.
Finalmente, RETURN se usa para hacer que una regla coincida con la política definida por defecto para esa categoría (input, output, forward). De esta forma, si se cambia la política por defecto, se cambia también la acción a tomar en esa regla. Su uso es muy limitado, y se recomienda fijar opciones mas estrictas, como ACCEPT, DENY y REJECT, principalmente por legibilidad. Esta opción solo tiene utilidad con las categorías definidas por el usuario (user-defined chains), que es una manera de organizar las reglas de forma modular. Este nuevo Chain puede usarse como objetivo (target) de alguna regla, de forma que se salta al Chain definido y se comprueban sus reglas. RETURN permite volver al Chain principal y continuar comprobando reglas, justo a partir de la regla que provoco el salto de Chain. El uso de Chains definidos por el usuario puede ser útil en scripts muy grandes y complejos, pero si se comenta adecuadamente el script, y se define un flujo de datos adecuado, es mas que suficiente con los Chains predefinidos (input, output y forward).
Otra de las cosas que hay que tener en cuenta es el orden de las reglas. Las reglas se comprueban en orden, desde la primera a la ultima, y cuando coincide con alguna se aplica la opción correspondiente y se detiene el proceso (si no coincide con ninguna regla se aplica la política por defecto de esa categoría). Por esta razón, se deben ordenar las reglas de las mas especificas a las mas genéricas, o de lo contrario nunca se evaluarían las reglas especificas.
Finalmente, se recomienda configurar el Firewall desde la consola y no a través de la red, además se debe desconectar el Firewall de la red para ponerlo en marcha, porque mientras se realiza esta operación es extremadamente vulnerable a un ataque.
A.2-Estructura Básica de las Reglas
Las reglas se escriben en un archivo, una detrás de la otra de forma que ese orden determina el orden en que se evaluaran para filtrar un paquete. La estructura típica de una regla IPChains es:
ipchains
<Action Flag> <Chain> [Optional Flags] [Target]
·Action Flag: opción que indica la acción a realizar con el Chain. Puede ser añadirle una regla (-A), borrar todas las reglas (-F) y otras.
·Chain: Especifica si la regla se añade al chain de input, output, forward o alguno definido por el usuario.
·Optional Flags: Opciones extras, que sirven para identificar la dirección de origen, destino, puertos y protocolo a los que se refiere la regla.
·Target: Destino final del paquete que coincida con la regla. Puede ser DENY, ACCEPT, REJECT, ...
Para ICMP, donde no tiene sentido hablar de puertos, el flag de ‘destination port’ se refiere al tipo del mensaje ICMP especifico al que se aplica la regla.
Por ejemplo, las siguientes reglas pueden ser parte de cualquier Firewall:
ipchains –F input
#Elimina
todas las reglas del Chain input
ipchains –P input DENY
#Fija
la política de input en denegar. Todos los paquetes que entren en
#el
Firewall por cualquier interfaz se rechazan a menos que una regla
#especifica
diga lo contrario
ipchains –A input –p tcp
–destination-port 23 –j ACCEPT
#Añade
(-A) una regla al chain input, que se aplica al protocolo (-p) TCP
#que
tenga como puerto de destino el puerto 23. Estos paquetes se
#deben
aceptar (-j ACCEPT)
También se puede especificar la dirección de origen o destino con el Flag –s (origen) y –d (destino). Esta opción se puede combinar con las mascaras de red para identificar redes enteras, o mediante el operador de negación (!) para identificar a una maquina especifica. Por ejemplo:
ipchains –P input ACCEPT #Se aceptan todas las conexiones
entrantes
ipchains –A input
–p tcp –s ! 100.100.100.100 –destination-port 23 –j DENY
#Los
paquetes entrantes con protocolo TCP y destino el puerto 23 que no
#vengan
de 100.100.100.100 se deniegan. Si el paquete viene de
#100.100.100.100
(con destino el puerto 23 y protocolo TCP) no cumple esta
#regla
y se le aplicaría la política por defecto (Aceptar). Con estas dos líneas
#solo
se aceptarían los Telnet (puerto 23) de la maquina 100.100.100.100
Otro de los Flags mas importantes es el que permite identificar un interfaz especifico (-i). Así se pueden discriminar los paquetes que entran (input) o salen (output) por un interfaz o por otro. Así, si queremos aceptar los Telnet desde la subred interna (por ejemplo eth0) pero no los que vengan por el interfaz de internet (ppp0), haríamos lo siguiente:
ipchains –A input
–i eth0 –p tcp –destination-port 23 –j ACCEPT
ipchains –A input
–i ppp0 –p tcp –destination-port 23 –j DENY
Estas reglas no tienen en cuenta la política por defecto, por lo que probablemente alguna de las dos sobre (aquella que coincida con la política por defecto). además, estas reglas pueden hacerse mas especificas, identificando destinos u origenes validos (eliminando al Firewall como objetivo valido del Telnet aunque venga por el interfaz interno, por ejemplo).
Finalmente, el ultimo Flag realmente importante es aquel que permite identificar un paquete TCP como iniciante de una conexión o como respuesta (-y identifica un paquete que inicia una conexión). Esto nos permitirá crear reglas para habilitar servicios de forma sencilla, ya que bastara con habilitar un servicio en sentido saliente (LocalàInternet) y permitir las respuestas:
ipchains –P input
DENY
ipchains –P output
ACCEPT
ipchains –A input
–i eth0 –p tcp –destination-port 23 –j ACCEPT
#Aceptamos
los paquetes internos que intentan iniciar o usar un Telnet
ipchains –A input
–i ppp0 –p tcp –source-port 23 ! -y -j
ACCEPT
#también
permitimos los paquetes que llegan de internet desde un servidor de
#Telnet
y que parecen ser respuesta a una conexión iniciada previamente (! -y).
Estas reglas son muy genéricas, y se recomienda encarecidamente que se especifiquen al máximo, de forma que es muy recomendable indicar también las direcciones de origen y destino, cuando sea posible (por ejemplo, indicando la subred interna mediante las mascaras cuando sea posible), y los rangos de los puertos, indicando como origen del Telnet el rango temporal con ‘—source-port 1024:65535’ (y como puerto destino de los paquetes de vuelta). Todo lo que permita acotar las reglas al máximo supondrá un beneficio que redunda en la seguridad, puesto que evita los imprevistos y ayuda a mantener todo bajo control.
Por ultimo, para conseguir enmascarar la red tras la dirección IP del Firewall, basta con añadir una regla en el forward Chain, de forma que se enmascaren los paquetes internos que vayan hacia fuera, puesto que el Kernel se preocupa de deshacer el masquerading de los paquetes de vuelta, y hacer la redirección apropiada. Si asumimos que la red interna va desde la dirección 192.168.1.1 hasta la 192.168.1.255 (todas ellas no enrutables), la regla seria:
ipchains –A forward –s
192.168.1.0/24 –d ! 192.168.1.0/24 –j MASQ
#Los paquetes que pasen de un interfaz al
otro, que se originan internamente y
#que se dirigen hacia fuera son
enmascarados tras el Firewall.
A.3-Reglas mas Comunes
A continuación ofrecemos una colección de reglas típicas en la mayoría de Firewall, junto con una breve justificación de las mismas, de forma que se pueda implementar un Firewall básico sin mas que “copiar” y ajustar las reglas aquí descritas. El interfaz interno se denotara como eth0, y el externo como ppp0, de forma que cada administrador deberá cambiar estos nombres adecuadamente.
A.3.1-Políticas
Como política mas sencilla, se recomienda aceptar todos los paquetes salientes (output) y enrutados (forward), mientras que se deniegan todos los entrantes (input). De esta forma se controla el trafico con un solo Chain, ya que cualquier paquete en output o forward o bien ha sido generado por el Firewall (que se supone es la maquina mas segura de la red) o bien ha pasado por la criba del input Caín, y por tanto se debe aceptar, a menos que se especifique lo contrario. Esto se consigue con:
ipchains –F input
ipchains –F output
ipchains –F
forward
#Borramos
los chains
ipchains –P input DENY
ipchains –P output
ACCEPT
ipchains –P
forward ACCEPT
Aunque no es raro hacer DENY de todo, y luego crear una colección mas extensa de reglas, aceptando explícitamente cada paquete en entrada, transito y salida.
Por otro lado, es necesario habilitar el uso del interfaz de loopback, o de lo contrario, la maquina no funcionara correctamente:
ipchains –A input –i lo –j ACCEPT
Otra practica habitual suele ser permitir todos los paquetes que vengan del interfaz interno, y habilitar las respuestas de los servicios permitidos mas adelante:
ipchains –A input –i eth0 –j ACCEPT
#permite que las peticiones de los clientes se realicen, sean cuales
#sean...Pero al no permitir de momento ninguna respuesta, sigue
#sin haber ningún servicio activo
Al igual que antes, esta opción se puede omitir, pero redunda en una mayor extensión de las reglas del Firewall.
A.3.2-Protección contra paquetes Falsos
Los paquetes falsos son un claro ejemplo de intento de ataque o prueba que pueden ser fácilmente detenidos con un Firewall de estas características. Estos paquetes consisten en direcciones no enrutables, o en direcciones imposibles, como paquetes del exterior que tienen como origen una maquina del interior y similares. La siguiente colección de reglas es imprescindible en cualquier Firewall, aun incluso si la política por defecto fuese suficiente para parar estos paquetes. Nunca esta de mas tener la certeza absoluta de que estos paquetes nunca van a pasar el Firewall. Algunos están marcados con la etiqueta ‘-b’, de forma que la regla es bidireccional, lo que quiere decir que la regla se aplica tanto para direcciones de origen como de destino (‘-b’ crea 2 reglas iguales en las que se intercambian ‘-s’ por ‘-d’ y viceversa):
ipchains –A input –i ppp0 –s 255.255.255.255/32 –b –j DENY
ipchains –A input –i ppp0 –s 127.0.0.0/8 –b –j DENY
#Paquetes no enrutables
ipchains –A input –i ppp0 –s 10.0.0.0/8 –b –j DENY
ipchains –A input –i ppp0 –s 172.16.0.0/12 –b –j DENY
ipchains –A input –i ppp0 –s 192.168.0.0/16 –b –j DENY
#Paquetes con direcciones enmascaradas
#Asumiendo unas direcciones internas de 100.100.100.0/24
ipchains –A input –i ppp0 –s 100.100.100.0/24 –j DENY
#Paquetes que vienen por fuera, cuyo origen es interno
A.3.3-Servicios
A continuación se detallan los servicios mas normales, y sus correspondientes reglas, además de una breve explicación, a modo de comentario de ipchains.
ipchains –A input –p icmp –destination-port 3 –j ACCEPT
#El tipo 3 se usa para la gestión de parámetros TCP, y es
#necesario para el funcionamiento de la red.
#Asumiendo que el
DNS externo es 1.2.3.4:
ipchains –A input –i ppp0 –p udp –s 1.2.3.4 53 –j ACCEPT
ipchains –A input –i ppp0 –p tcp –s 1.2.3.4 53 –j ACCEPT
#Aceptamos las respuestas del DNS, ya sean TCP o UDP
#Servidor interno de SMTP en 1.2.3.4:
ipchains –A input –i ppp0 –p tcp –d 1.2.3.4 25 –j ACCEPT
ipchains –A input –i ppp0 –p tcp –d 1.2.3.4 113 –j REJECT
#Permitimos que el exterior use el servidor de SMTP pero
#rechazamos los intentos de identificación sin bloquear el servicio
En caso de tener una red enmascarada, las instrucciones para la habilitación del servidor de SMTP son:
#Asumimos que 1.2.3.4 es la dirección externa del Firewall y que
#192.168.1.99 es la dirección interna del servidor de SMTP real
ipchains –A input –i ppp0 –p tcp –dport 25 –j ACCEPT
ipchains –A input –i ppp0 –p tcp –dport 25 –j REJECT
ipmasqadm portfw –a –P tcp –L 1.2.3.4 25 –R 192.168.1.99 25
A continuación, si respetamos las políticas definidas previamente, para activar la navegación Web de los clientes del Firewall, tendríamos que permitir las respuestas de los servidores de Web de Internet, y eso se hace con:
ipchains –A input –i ppp0 –p tcp –sport 80 –dport 1024:65535 ! –y –j ACCEPT
#Aceptamos los paquetes que vienen de un servidor de Web (puerto 80) y
#que son parte de una conversación previa (! -y). además especificamos que
#el destino solo puede ser un puerto temporal
Como vemos, estas reglas son muy especificas, a pesar de que se ha intentado poner un ejemplo lo mas general posible, por lo que se recomienda que, en función de las necesidades, se fijen unas políticas u otras y se creen las reglas adecuadas, siguiendo estas reglas como ejemplo de sintaxis. Por ejemplo, otra combinación de políticas muy usada, pero que requiere mas líneas de archivo, es Denegar todos los inputs y Rechazar los outputs y forwards (para generar mensajes) o incluso Rechazar solo las peticiones locales (para informar a los clientes de un servicio cerrado por el Firewall) y no las remotas. Cada uno tendrá sus preferencias, y requerirá unos niveles distintos de seguridad.
A.4-Poniendo el Firewall Operativo
Hay que realizar una serie de operaciones para poner el Firewall en estado operativo, en las que habrá que configurar y ajustar el sistema operativo a las necesidades de nuestro Firewall, que pasamos a detallar a continuación.
A.4.1-Activar el Enrutamiento
Por defecto, la mayoría de sistemas operativos traen la función de enrutado de paquetes desactivada, de forma que el Firewall no servirá para nada. En Linux, se puede alterar fácilmente este comportamiento, fijando el valor de ‘FORWARD_IPV4’ a TRUE en el archivo ‘/etc/sysconfig/network’ (que por defecto se pone a FALSE en la mayoría de distribuciones habituales).
Otra manera de alterar este comportamiento, es arrancando el Forwarding cada vez que se arranque el Firewall, a través de su propio Script de arranque, mediante la instrucción:
‘echo 1 >
/proc/sys/net/ip_forward’
Que además, permite la desactivación del routing con el script de apagado del Firewall, simplemente cambiando el 1 (TRUE) por un 0 (FALSE).
El primer método (editar el archivo), es mas cómodo, y además se realiza a través de un script bastante robusto, por lo que se recomienda su uso. además, y como precaución, es muy importante iniciar la función del Firewall inmediatamente antes de iniciar el rutado (o de lo contrario se “colaran” paquetes sin la supervisión del Firewall) y el primer método es el único que funciona adecuadamente con esta política, por razones que veremos un poco mas adelante.
A.4.2-Activar el Firewall
Es necesario arrancar los scripts del Firewall en el momento adecuado, o de lo contrario el sistema “encenderá” los interfaces de red y habrá un periodo de tiempo durante el que el sistema será vulnerable sin el Firewall. Por eso, es recomendable arrancar el Firewall ANTES de arrancar la red, de forma que cuando llegue el primer paquete, se encuentre con el Firewall en perfecto funcionamiento.
En principio, hay que averiguar en que init level arranca el sistema, mediante la instrucción ‘grep initdefault /etc/inittab’, que devuelve un numero indicando el runlevel de inicio (algo así como id:3:initdefault). Los niveles de arranque normales son el 3 y el 5. Este numero es importante, ya que nos indica el directorio donde debe descansar el script de arranque del Firewall.
Asumiendo que el nivel de inicio sea el 3, nos movemos al directorio ‘etc/rc.d/rc3.d’, que contiene archivos que se ejecutan al finalizar o arrancar el sistema (unos empiezan con K y los otros con S), ordenados por un numero de dos cifras, que representa el orden de ejecución. La red se arranca en el script llamado S10network, por lo que debemos crear un link llamado S09firewall que llame al script de arranque del Firewall, de forma que el Firewall se arranque justo antes que la red:
cd /etc/rc.d/rc3.d/
ln –s /etc/rc.d/init.d/firewall S09firewall
Como vemos, el script de arranque del Firewall descansa en /etc/rc.d/init.d/firewall y puede ser algo tan sencillo como:
#!/bin/sh
#
# Librería de funciones:
. /etc/rc.d/init.d/functions
# Configuración de Red:
. /etc/sysconfig/network
[ -f /etc/rc.d/rc.firewall ] || exit 0
case “ $1 “ in
start)
echo –n “ Arrancando Firewall: “
daemon /etc/rc.d/rc.firewall
touch /var/lock/subsys/firewall
;;
stop)
echo –n “ Cerrando Firewall: ”
ipchains –F input
ipchains –F output
ipchains –P input ACCEPT
ipchains –P output ACCEPT
echo
rm –f /var/lock/subsys/firewall
;;
restart)
$0 stop
$0 start
;;
status)
status firewall
;;
*)
echo “ Usage: firewall {start|stop|restart|status}”
exit 1
easc
exit 0
Este script asume que el código de IPChains del Firewall se encuentra en ‘etc/rc.d/rc.firewall’. Esto es solo un ejemplo muy sencillo, pero se pueden encontrar muchos otros en la red que se ajustan a necesidades diversas.
Por otro lado, si se escoge el camino lógico, y se arranca el Firewall antes que la red, no funcionara el método antes mencionado de arrancar el Forwarding poniendo una línea al script del Firewall que modifique el estado del ‘proc/sys/net/ip_forward’ ya que el S10network llama al archivo ‘etc/sysconfig/network’ y este machacaría el forwarding a menos que se halla modificado la variable FORWARD_IPV4 que aparece en este archivo. Esta es la otra razón por la que se recomendaba la edición del archivo network en detrimento del arranque manual del forwarding a través del script del Firewall.
A.4.3.-Port Forwarding
Ya hemos comentado anteriormente las ventajas que proporciona el Masquerading de la red tras el Firewall, entre otras cosas permite el acceso a Internet de muchas maquinas a través de una única dirección de red (y una única conexión), salvaguardando la integridad de las maquinas protegidas tras el Firewall, que es la única maquina accesible desde el exterior, y que además es (o debería) la maquina mas segura.
Esta opción también tiene inconvenientes, como también hemos comentado, ya que la imposibilidad de acceder a una maquina interna, impide (en principio) tener servidores en la red protegida. Existen varias soluciones, como tener un DMZ accesible desde el exterior o, para aplicaciones mas interesantes (como una base de datos que se quiere proteger, o una maquina que se quiere administrar de forma remota), se puede instalar un redirector de trafico.
Un redirector de trafico (o “Port Forwarding Tool”) es una aplicación que captura el trafico que se dirige a un determinado puerto y lo reenvía a la dirección adecuada. De esta forma, el Firewall aparecerá como un “super-servidor” que integra todos los servicios, pero en realidad lo único que hace es redirigir las peticiones a los servidores reales, que se encuentran en el interior de la red, a salvo de otras conexiones que no sean las permitidas en el Firewall.
En Linux, esta aplicación se llama “ipmasqadm”, y tiene una sintaxis similar a IPChains (principalmente cambian los flags), por lo que apenas se comentara nada mas de ella. Como ejemplo:
ipmasqadm portfw –f
#borra todas las reglas
ipmasqadm portfw –l –n
#listado de reglas (no debe haber ninguna). además, no hace
#comprobaciones de nombres en el DNS
#Asumiendo que el Firewall es 203.42.57.2 y el Servidor Web esta
#en 192.168.1.17
ipmasqadm portfw –a –P tcp –L 203.42.57.2 80 –R
192.168.1.17 80
#Redirige el trafico que va al inexistente servidor Web en el
#Firewall, a la dirección enmascarada que cobija al Web Server.
Existen, algunos problemas inherentes a esta solución, que pasamos a explicar. El primero es que no se permite tener mas que un servicio de cada tipo, porque no hay forma de diferenciar ambos servidores (ambos tienen la dirección del Firewall y el mismo puerto), a menos que el Firewall tenga varias direcciones IP externas, de forma que bastaría con escribir varias reglas.
Otro problema grave es que este sistema no funciona bien con aplicaciones como el FTP pasivo, en el que el servidor le devuelve un numero al cliente para que abra una conexión ahí, por lo que el forwarder no sabe a donde debe redireccionar, ni el que debe escuchar. Existen maneras de hacer forwarding adaptativo, pero están fuera del objetivo de este tutorial, por lo que si se necesita un servicio como este, lo mejor es colocarlo fuera, en el DMZ, de forma que se comprometa lo menos posible a la subred (como ya comentamos al hablar del FTP).
Por otro lado, existe un problema añadido con las direcciones IP Dinámicas, ya que es necesario especificar estáticamente la dirección IP en las reglas del ipmasqadm. Si se posee una conexión de este tipo, no hay mas remedio que rescribir las reglas de forwarding de forma dinámica, con un script que se arranque tras la adquisición de la dirección IP correspondiente, y usando una variable en vez de la dirección estática que usamos en el ejemplo. Nuevamente, este script es algo mas complejo, y queda fuera de este tutorial, pero si el lector esta interesado, no le será difícil encontrar múltiples scripts pre-diseñados en la red.
A.4.4-Routing
Normalmente no será necesario tocar la tabla de encaminamiento del ordenador, pero si será conveniente revisarla, para comprobar que todo esta en su sitio. Como mínimo debería tener una entrada para el interfaz de loopback, otra entrada para el interfaz interno de la red, posiblemente otra entrada para el externo y otra entrada para el Gateway por defecto (configuraciones de red mas complejas requerirán tablas mas extensas). El aspecto mas típico de una tabla de encaminamiento es:
Asumiendo que:
*El interfaz interno es 163.117.140.0/24
*El externo es 163.117.31.0/24
*El Gateway por defecto es 163.117.31.1
*eth0 del Firewall es 163.117.140.2
*eth1 del Firewall es 163.117.31.2
Destination Gateway Genmask Flags Mss Window irtt Iface
163.117.140.0
0.0.0.0 255.255.255.0 U
0 0 0 eth0
163.117.31.0 0.0.0.0
255.255.255.0 U 0 0 0 eth1
127.0.0.0
0.0.0.0 255.0.0.0
U 0 0 0 lo
0.0.0.0 163.117.31.1
0.0.0.0 UG
0 0 0 eth1
Como podemos observar, lo único que tiene hacer es mandar por el interfaz ethernet adecuado los paquetes cuyo destino esta en ese segmento de red, y los paquetes que no se dirijan a ninguno de esos interfaces es redirigido a la pasarela de salida en el interfaz externo (en este caso, también es una ethernet, denominada eth1). El interfaz de loopback se configura para que el sistema funcione correctamente (lo usa para mandarse mensajes a si mismo).
Existe una entrada del manual (‘man route’) que explica de forma sencilla como añadir o borrar entradas de esta tabla, pero si no se tiene un conocimiento adecuado de lo que se esta haciendo, es mejor no tocarla. En cualquier caso, no nos extenderemos mas en este apartado.
A.4.5-Mejoras añadidas
Existen algunas cosas mas que debemos hacer para mejorar el Firewall. Una de ellas consiste en desactivar el “Source Routing” y otra consiste en eliminar los compiladores del sistema. además, también es recomendable apagar la mayoría de servicios que no va a usar el Firewall.
La primera es siempre una buena idea. Bajo ningún concepto se deben aceptar los paquetes que aparezcan enrutados por el origen (como se comento en el apartado 2.2.1), pero es sencillo hacer que estos paquetes “mueran” en el Firewall, sin mas que añadir estas dos líneas al script del Firewall:
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
echo 0 > /proc/sys/net/ipv4/conf/default/accept_source_route
El primero establece una “política general”, mientras que la segunda pone un caso base para todos los interfaces que se definan tras este punto. Puede parecer redundante, pero el hecho es que no lo es, y se recomienda la inclusión de ambas líneas en el script de arranque del Firewall.
Otra buena idea es eliminar el compilador de C del Firewall. Es cierto que un buen hacker llevara su propio compilador o cualquier otra cosa que le sea necesaria, pero muchos otros no lo harán, por lo que todo lo que sea dificultar la tarea de los atacantes siempre será una avance en la seguridad y no una perdida de tiempo. también se deben eliminar todas aquellas herramientas que no se vayan a usar, y que puedan ser susceptibles de ser usadas por un hacker, como las herramientas de análisis de trafico, análisis del sistema, etc. además, si se necesitan en algún momento puntual, se pueden instalar, usar y nuevamente desinstalar, con poco esfuerzo.
En cuanto a los servicios que se deben apagar, hay que recordar que la mayoría de servicios se controlan a través del archivo ‘/etc/inetd.conf’ en el que aparecen todos los servicios activos, y muchos otros que aparecen en forma de comentario (los menos usados) para ser activados sin mas que borrar el “#” de l comentario (simplificándole la tarea al administrador). Muchos de estos servicios vienen marcados como “ftp” o “smtp” directamente, pero se puede encontrar un mapping de los nombres de los servicios y los puertos en el archivo ‘/etc/services’.
Por tanto, se deben desconectar todos los servicios que no sean imprescindibles (en realidad, ninguno lo es), pero se puede permitir, por ejemplo, que el ssh siga en funcionamiento, para así poder administrar el Firewall de forma remota (el sshd debe arrancarse al inicio). Para comprobar que servicios se quedan funcionando, se puede ejecutar:
kill –1 ‘cat /var/run/inetd.pid’
Que re-arranca el inetd nuevamente, con las modificaciones hechas, y luego con:
netstat –apn
Podemos ver una lista con los servicios que todavía siguen funcionando. De la salida de este comando, nos debemos fijar en las entradas TCP que están en LISTEN y en las entradas UDP, y en los puertos en los que corren dichos servicios. Gracias al archivo ‘/etc/services’ podemos identificar que servicios corren en esos puertos y apagar el daemon correspondiente. Algunos servicios no tendrán identificador de proceso asignado porque se manejaran directamente por el Kernel (como el NFS), por lo que seria muy complicado apagarlo, pero esto se soluciona fácilmente asegurándose de que estos paquetes no pasen el IPChains, y por tanto no lleguen nunca al Kernel.
De esta forma nos aseguramos que el Firewall escuche a la menor cantidad posible de paquetes, protegiendo al propio Firewall de ataques contra servicios vulnerables, que por otro lado no tienen utilidad y pueden (deben) ser desactivados del Firewall sin ningún tipo de problema.
A.5-Referencia Extendida de Flags
A continuación damos una referencia completa de los Flags disponibles de IPChains, aunque como ya comentamos antes, la mayoría no son en absoluto necesarios para la creación de un Firewall, y solo añaden complejidad. también pueden encontrarse en la pagina del manual (‘man ipchains’):
A: Añade una regla a un Chain
b: Regla bidireccional. Crea dos reglas, intercambiando el origen y el destino.
C: Chequea un paquete para ver si pasa un Chain. Se especifican los parámetros del paquete de forma normal (con los flags ‘-s’, ‘-p’...) y comprueba el destino de ese paquete. Este flag se utiliza en la línea de comandos, como comprobación, mas que en el script del Firewall.
D: Borra una regla. Se puede especificar un numero (con –L sale una lista, y se puede contar) o una regla propiamente dicha.
d: Especifica el destino de un paquete. Se puede indicar una dirección IP, una IP con una mascara (escrita como la IP y una ‘/’ seguida del numero decimal de la mascara), o incluso un puerto de destino (o un intervalo de puertos):
-d 1.2.3.4 à El destino es esa IP
-d 1.2.3.0/24 à El destino esta entre 1.2.3.0 y 1.2.3.255
-d 1.2.3.0/24 1024:65535 à además el puerto de destino esta en ese rango
Se puede añadir el operador negación para negar la dirección o para negar el rango de puertos (para negar ambos es necesario poner 2 negaciones). De esta forma la regla se aplica si el destino NO coincide con el especificado, o si el puerto NO esta en ese rango:
-d ! 1.2.3.0/24 1024:65535 à El destino NO es esa subred, y el puerto esta en ese rango
destination-port, -dport: Especifica el puerto de destino del paquete. Como antes, se puede especificar un rango. Para paquetes ICMP este parámetro identifica el tipo de mensaje (echo request, echo Reply...).
F: Borra todas las reglas de un Chain.
f: Especifica que la regla solo se aplica al segundo y posteriores paquetes de un datagrama que ha sido fragmentado. Se suele usar principalmente para bloquear los fragmentos, origen de muchos ataques.
h: Help. Breve descripción de la sintaxis IPChains.
I: Requiere un Chain, un numero y una regla. Inserta la regla en la posición especificada del chain. Puede ser confuso, por lo que se recomienda la inserción manual de la regla en su lugar correspondiente.
i: Especifica el interfaz al que se aplica la regla. Por ejemplo en input, indica “los paquetes que entran por el interfaz”, y en output, “los paquetes que salen por ese interfaz”. Se pueden usar comodines, de forma que ‘eth+’ identifica a todos los interfaces cuyo nombre empiece por eth (eth0, eth1, ...).
icmp-type: Otra forma de indicar el tipo de un mensaje icmp. Mejora la legibilidad con respecto a ‘-dport’, pero nada mas.
j: Especifica el destino del paquete que cumpla la regla. Puede ser ACCEPT, REJECT, DENY, MASQ, REDIRECT, RETURN o uno de los Chains definidos por el usuario.
L: Da un listado de las reglas definidas en un chain, o todas las reglas en caso de no especificar ninguno.
l: Almacena en un archivo de log todos aquellos paquetes que coincidan con la regla.
M: Combinado con –L sirve para ver en “directo” el estado del masquerading (que conexiones se redirigen y a donde...). útil para la monitorización de la red. Combinado con –S permite introducir manualmente entradas en la tabla de masquerading, aunque no se recomienda esta practica.
m: Marca el paquete que cumpla la regla con el valor que se especifique. Se suele usar en combinación con monitores de red.
N: Crea un Chain con el nombre especificado. Debe tener 8 letras como máximo.
n: Cuando se usa –L para sacar un listado, este flag indica que las direcciones deben sacarse en formato numérico, y por tanto que no se debe tratar de resolver ningún nombre.
o: Copia los paquetes que cumplan la regla en el ‘userspace device’. Esto requiere una reconfiguracion del Kernel, por lo que no se recomienda su uso a menos que se tengan extensos conocimientos en el funcionamiento interno del Kernel.
P: Especifica la política del chain especificado. Debe ser uno de los 6 targets predefinidos (ACCEPT, DENY...).
p: Permite discriminar por protocolo. Puede ser tcp, udp, icmp o cualquiera que aparezca en ‘/etc/protocols’. también se puede usar junto con el operador de negación (‘!’), para indicar cualquier protocolo excepto el que se especifica.
R: Reemplaza la regla (identificada por numero) del Chain especificado, por la que aparece en esta línea. Se puede usar con los Chains definidos por el usuario para crear scripts dinámicos, que cambian en función del trafico recibido.
S: Junto con –M sirve para fijar los parámetros de timeout en el masquerading. Por regla general, no se necesita, a menos que haya muchos clientes detrás del Firewall, y el ajuste de esos parámetros permita optimizar el funcionamiento del Firewall.
s: Especifica el origen del paquete. Formalmente idéntico a ‘-d’.
source-port, -sport: Puerto de origen del paquete.
t: Se usa para especificar mascaras que permitan alterar el campo TOS (Type of Service).
v: Verbose.
X: Borra el Chain definido por el usuario que se especifica. Para que el borrado tenga éxito, no debe haber referencias al Chain, y tampoco debe tener reglas.
x: Cuando se usa con ‘-L’, ofrece los valores de conteo exactos, en lugar de los valores redondeados, que aparecen normalmente.
y: Cuando se usa con el protocolo tcp, hace que la regla solo se aplique a paquetes con el SYN flag activado, y con ACK y FIN desactivados. Solo el primer paquete de una conversación TCP satisface esos requerimientos. Se suele usar con el operador de negación, para identificar los paquetes que sean parte de una conversación establecida previamente.
Z: Pone a 0 los contadores del chain especificado (todos si no se especifica ninguno).
A.6-Ejemplo de Script de IPChains
Lo que se presenta a continuación es un ejemplo de script de ipchains. En el se utilizan los flags mas normales, para conseguir un Firewall sencillo y efectivo, lo que no quiere decir que se puedan conseguir efectos mas complejos con scripts mucho mas complejos. Se pueden encontrar muchos scripts ya hechos en la red que pueden servir también como una herramienta para comprender completamente el funcionamiento de IPChains. En cualquier caso, sirva este script como primera aproximación:
#!/bin/bash
#Reglas del Firewall
#eth0->interfaz de area local
#ppp0->interfaz de conexion a Internet
#red privada->192.168.1.0/24 (enmascarada)
#DNS->1.2.3.1
y 1.2.3.2
#NTP->1.3.4.5
#inicializacion (puesta a cero)
ipchains -F input
ipchains -F output
ipchains -F forward
#politicas por defecto
ipchains -P input DENY
ipchains -P output ACCEPT
ipchains -P forward ACCEPT
#permitimos acceso local y loopback
ipchains -A input -i lo -j ACCEPT
ipchains -A input -i eth0 -j ACCEPT
#denegamos el acceso a paquetes que provienen de
direcciones #no enrutables
#(paquetes falsos)
ipchains -A input -i ppp0 -s 192.168.0.0/16 -j DENY
ipchains -A input -i ppp0 -s 172.16.0.0/12 -j DENY
ipchains -A input -i ppp0 -s 10.0.0.0/8 -j DENY
#permite el retorno de conexiones que previamente
hemos iniciado
ipchains -A input -i ppp0 -p tcp ! -y -j ACCEPT
#Abre el MAIL y el SSH
ipchains -A input -i ppp0 --dport 25 -j ACCEPT #Mail Server
ipchains -A input -i ppp0 --dport 22 -j ACCEPT #ssh server
#Rechazar las conexiones de autenticacion via SMTP
ipchains -A input -i ppp0 --dport 113 -j REJECT
#Reject para que el servidor de correo continue
sin autenticar (no #delay)
#Respuestas del DNS
ipchains -A input -i ppp0 -p udp -s 1.2.3.1 53 -j ACCEPT
ipchains -A input -i ppp0 -p udp -s 1.2.3.2 53 -j ACCEPT
ipchains -A input -i ppp0 -p tcp -s 1.2.3.1 53 -j ACCEPT
ipchains -A input -i ppp0 -p tcp -s 1.2.3.2 53 -j ACCEPT
#respuestas al NTP
ipchains -A input -i ppp0 -p udp -d 1.3.4.5 123 -j ACCEPT
#ICMP
ipchains -A input -i ppp0 -p icmp --dport 0 -j ACCEPT #Ping externo
#dialogos de red
ipchains -A input -i ppp0 -p icmp --dport 3 -j ACCEPT
ipchains -A input -i ppp0 -p icmp --dport 11 -j ACCEPT #traceroute
#no se permiten pings desde fuera (type 8)
#log de los paquetes rechazados
ipchains -A input -j DENY -l
#añadir al syslog.conf -> kern.=info /var/log/firewall
#touch /var/log/firewall
#/etc/rc.d/init.d/syslog restart
#Masquerading de paquetes salientes de la LAN
ipchains -A forward -j MASQ -s 192.168.1.0/24 -d ! 192.168.1.0/24
#INSTRUCCIONES:
#Guardar como /etc/rc.d/rc.firewall
#chmod 755 /etc/rc.d/rc.firewall
#poner el scrip de arranque (o el wrapper) en
/etc/rc.d/init.d/firewall
#grep initdefault /etc/inittab -> N=default level
#cd /etc/rc.d/rcN.d
#ln -s /etc/rc.d/init.d/firewall S09firewall
#poner en /etc/sysconfig/network
FORWARD_IPV4=true para #activar
#el forwarding (NO HACER A TRAVES DE
#/proc/sys/net/ipv4/ipforward, ya que
#el firewall se arranca antes que la red)
Universidad Carlos III de Madrid
Departamento de Ingenieria Telematica