Sirviendo información sobre Linux desde 1998

TCPD y Firewalls usando IPFWADM

Autor: Javi Polo, LinuxFocus
Primera publicación: 1998-07-01
Copyright pertenece al autor

 

Resumen: En este articulo revisamos a groso modo la configuración de los servicios ofrecidos por inetd y como usar la herramienta IPFWADM para aumentar la seguridad de nuestro sistema.


Bueno, para empezar, hay que tener clarito qué es el inetd, es básicamente un demonio que controla los servicios que puede ofrecer una máquina conectada a Internet, pero también puede que no controle todos por defecto, así que, echadle un vistazo al fichero /etc/inetd.conf y mirad los servicios que da vuestra máquina desde el demonio inetd (los que estén descomentados, esto es, sin la parrilla "

Por ejemplo, la línea:

   ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -a

  • Lo primero de todo es el nombre del servicio (en este caso "ftp", que luego se buscará en el /etc/services a que puerto corresponde.
  • El segundo campo es el tipo de socket que se abre, y puede ser de varios tipos: stream (como en el ejemplo), dgram, raw, rdm y seqpacket
  • El tercer campo es el protocolo a utilizar, que tiene que estar definido en /etc/protocols (en este caso es el protocolo TCP)
  • El cuarto campo es para indicar wait/nowait, este campo debe ser siempre nowait excepto para los sockets de tipo datagrama (dgram). Si el servidor de datagramas es multi-hilo se indica nowait, ya que el servidor al recibir una llamada, lanza el proceso en un hilo de ejecución --al ser multi-hilo :)-- y libera el socket para que inetd pueda seguir recibiendo mensajes en el socket. Si el servidor es de tipo datagrama mono-hilo entonces se indica wait, ya que el servidor atiende siempre en el mismo socket y no puede lanzarlos en procesos aparte. Además, se puede añadir un apartado más a este campo, por ejemplo: nowait.50 (es decir, un número separado del wait/nowait por un punto). Este número representa el número máximo de demonios que puede lanzar (o de peticiones aceptadas, según se mire) en 1 minuto. Por defecto es 40.
  • El quinto campo indica el nombre del usuario con el que se debe ejecutar el demonio, en este caso se ejecutará como super-usuario (root).
  • El sexto y los sucesivos, son el programa a lanzar seguido de los parámetros que se le pasan al programa. Aquí se le indica que lance el demonio tcpd, y como argumentos el demonio in.ftpd con los parámetros -l -a. Ahora llega la parte más interesante de este primer trozo del artículo, que es la que engloba al TCPD.

Bueno, el tcpd es un demonio que filtra las peticiones, y hace una u otra cosa dependiendo del demonio a lanzar y de la IP que pide el servicio. Esto lo hace mediante el /etc/hosts.allow y /etc/hosts.deny

En principio, se usa /etc/hosts.deny para indicar a quien y a que no se permite el acceso, y el /etc/hosts.allow para decir quien y a que puede acceder.

El formato de ambos ficheros es:

DEMONIO: IP[: OPCION1 [: OPCION2 ]]

donde DEMONIO puede ser el demonio a lanzar, como en el ejemplo puesto, el in.ftpd, o también puede ser ALL, refiriéndose a todos los demonios.

IP puede ser tanto una IP o una URL, como un rango de IPs (o de URLs), como cualquiera de los comodines que explico despues.

Para indicar un rango de IPs, por ejemplo, se hace poniendo: `123.32.' Esto englobaría todas las IPs 123.32.XXX.XXX Y lo mismo para las URLs: `.ml.org' englobaría todos los subdominios de ml.org

También se puede determinar un rango de IPs de la tradicional forma IP/MASCARA De forma que por ejemplo, para indicar el rango 127.0.0.0 a 127.0.255.255 se indicaría así: 127.0.0.0/255.255.0.0 Los comodines son:

  • ALL que indica que coincide con cualquier dirección entrante
  • LOCAL que coincide con cualquier nombre que no tenga un "."
  • UNKNOWN que coincide con aquellas máquinas de las que no se conoce o su nombre o su IP
  • KNOWN que coincide con las máquinas de las que se conoce tanto su nombre como su IP
  • PARANOID que coincide con aquellas máquinas en las cual su nombre no coincida con su IP

las opciones pueden ser:

  • allow hace que a lo indicado en esa entrada se debe aceptar conexión, independientemente de si está en el fichero hosts.allow o en hosts.deny. Debe ser la última opción de la línea.
  • deny es como la anterior, pero denegando la conexión.
  • spawn ejecuta un comando shell (por si se quiere ejecutar algo cada vez que se establece una conexión que coincida con la línea), yo por ejemplo hago que cuando recibo cualquier conexión de fuera, me suene un sonido para saber que alguien intenta conectar a mi máquina
  • twist es como el comando spawn, pero cortando la conexión tras ejecutar el comando. También debe ser la última opción de la línea.

Para estos dos últimos comandos, se pueden usar las expansiones que permite el tcpd. Estas son:

  • %a dirección de la máquina cliente
  • %c Información del cliente (puede ser usuario@máquina, o lo que sea, dependiendo del cliente)
  • %d nombre del demonio
  • %h nombre o IP de la máquina cliente, según esté disponible
  • %n nombre de la máquina cliente
  • %p PID del demonio
  • %s información del servidor (demonio@máquina o solo demonio, depende)
  • %u Nombre del usuario cliente
  • %% Es un simple carácter %

Con estas expansiones y esos dos comandos se pueden hacer muchas cosas, por ejemplo, me se de uno que cada vez que intentaban entrarle por telnet, le mandaba automáticamente un "teardrop" al afortunado intruso :)

NOTA: Un teardrop es un DoS (Denial of Service, un ataque para colgar la máquina o provocar que se reinicie) que se basa en aprovecharse en el fallo de la defragmentación de los paquetes TCP que tienen (ahora ya tenían, puesto que muchos se han parcheado ya) gran parte de Sistemas Operativos. La información se manda a través de Internet por el protocolo TCP/IP (que se usa también en otro tipo de redes, aparte de Internet, como por ejemplo intranets), el protocolo TCP se encarga de trocear la información en paquetes que luego el protocolo IP se encarga de hacer llegar a su destino, y una vez allí, el protocolo TCP comprueba que estén todos los paquetes y los junta para recomponer la información original. Dicho ataque (y muchos basados en él) lo que hace es aprovecharse de que en muchos Sistemas Operativos no se comprobaba si el tamaño del paquete antes de juntarlos era muy pequeño, y al ser así la máquina se hacía un lío a la hora de juntarlo. Esto no estoy completamente seguro de que sea así, evidentemente, acepto todo tipo de aportaciones y críticas, tanto positivas como negativas. Finalizada esta "pequeña" aclaración, sigamos ...

Ejemplos:

# cat /etc/hosts.allow

ALL: 127.0.0.1 #deja entrar a localhost para todo

in.ftpd: ALL: spawn (wavplay /usr/share/sounds/intruso.wav & )
# deja entrar a cualquiera por ftp, pero lanzando un
# sonido wav (para que yo me entere)

in.telnetd: ALL: twist ( teardrop %h %h )
# manda un teardrop a quien intente
# entrar por telnet


# cat /etc/hosts.deny


ALL: `.bsa.org' # no deja entrar a nadie del dominio bsa.org

in.fingerd: ALL # el servicio de finger cerrado para todos :)

#fin

Bueno, esto es todo lo que tengo que decir sobre el tcpd, ya os dije que mis conocimientos no eran muchos. Probad, experimentad y leeros las páginas de manual (tcpd, host_access(5) ). Seguro que así aprendéis mucho más de lo que yo os pueda enseñar. Pasemos ahora al uso de la herramienta IPFWADM

Lo primero de todo es tener el soporte de IP Firewalling en el kernel (Networking -> Network firewalls + IP: firewalling). Luego, tras recompilar el kernel y reiniciar el equipo, pasemos a explicar la utilidad de esta herramienta.

Esta herramienta permite entre otras cosas (serán en las únicas que me centraré) gestionar la entrada y salida de paquetes de los protocolos TCP, UDP e ICMP. En resumen, nosotros le indicamos qué paquetes debe permitir entrar, pudiendo especificar si vienen de una IP o grupo de IPs concretos, a un puerto concreto, con un protocolo concreto, y todas las mezclas de opciones que se puedan hacer, y lo mismo con los paquetes que van hacia fuera.

ipfwadm tiene varios parámetros principales:

  • -A especifica las reglas de accounting.
  • -I especifica las reglas para los paquetes entrantes.
  • -O especifica las reglas para los paquetes salientes.
  • -F especifica las reglas de reenvío de paquetes.
  • -M es para la administración del IP masquerading.

En este artículo solo hablaré de los parámetros -I y -O. Para ambos se sigue la misma sintaxis. Subparámetros de estos parámetros principales son:

  • -a añade una o más reglas al final de la lista.
  • -i añade una o más reglas al principio de la lista.
  • -d borra una o más reglas de la lista.
  • -l muestra las reglas de la lista.
  • -f borra las reglas de la lista.
  • -p para indicar si los paquetes se han de aceptar (a), denegar (d) o rechazar (r).
  • -c comprueba que tipo de regla se seguía con un paquete.
  • -h ayuda.

Los parámetros "importantes" son:

  • -P especifica el protocolo con el cual se ha de aplicar la regla, este puede ser TCP, UDP, ICMP o all (para indicar cualquier protocolo)
  • -S especifica la dirección origen del paquete. El formato es:
   DIRECCION[/MASCARA] [PUERTO]

Por ejemplo, una dirección válida sería:

   123.32.34.0/255.255.255.250 25

para indicar el rango de IPs desde 123.32.34.0 a 123.32.34.5

-D especifica la dirección destino. Tiene el mismo formato que -S

Básicamente estos son los parámetros fundamentales, así, para permitir que las tramas lleguen a mi máquina, todas de mi misma máquina, añado la regla:

   ipfwadm -I -i a -S 127.0.0.1

y para descartar los paquetes que vengan desde 123.34.22.XXX le indico:

   ipfwadm -I -a d -S 123.34.22.0/255.255.255.0

y luego si quiero denegar TODO acceso al puerto de netbios, menos para la IP 111.222.123.221, lo haría así:

   ipfwadm -I -a a -P tcp -S 111.222.123.221 139
ipfwadm -I -a d -P tcp -D 0.0.0.0/0 139

Bueno, creo que eso es todo mi artículo, un poco pobre, pero mis conocimientos no llegan a más O:)