12.2. La Facilidad de Control de Acceso tcpd

Debido a que abrir un computador al acceso de red implica muchos riesgos de seguridad, las aplicaciones están diseñadas para protegerse contra algunos tipos de ataques. Algunas características de seguridad, sin embargo, pueden tener fallos (más drásticamente demostrados por el gusano de Internet RTM, que explotaba un agujero en algunos programas, incluyendo versiones antiguas del demonio de correo Sendmail), o no distinguen entre hosts seguros cuyas peticiones de un servicio particular deberán ser aceptadas y hosts inseguros cuyas peticiones deberán ser rechazadas. Ya hemos visto brevemente los servicios finger y tftp. Los administradores de red deberían querer limitar el acceso de estos servicios a “hosts de confianza” únicamente, lo que es imposible con la configuración usual, por la que inetd ofrece este servicio o a todos los clientes o a ninguno.

Una herramienta útil para gestionar el acceso de hosts específicos es tcpd, a menudo llamado el demonio “encapsulador [1].”[2] Para los servicios TCP quiera monitorizar o proteger, se invoca en vez del programa servidor. tcpd verifica si el host remoto tiene permitido usar ese servicio, y sólo si esto tiene éxito ejecutará el programa servidor real. tcpd también deja registradas las peticiones en el demonio syslog . Nótese que no funciona para servicios basados en UDP.

Por ejemplo, para encapsular el demonio finger, debe cambiar la correspondiente línea en inetd.conf de esta forma:
    # demonio finger desencapsulado
    finger    stream tcp nowait bin    /usr/sbin/fingerd in.fingerd
a esta:
    # demonio finger encapsulado
    finger  stream  tcp     nowait  root    /usr/sbin/tcpd   in.fingerd

Sin añadir ningún control de acceso, al cliente le parecerá como la configuración usual de finger, excepto que todas las peticiones son registradas en la facilidad auth de syslog.

Dos ficheros llamados /etc/hosts.allow y /etc/hosts.deny implementan el control de acceso. Contienen entradas que permiten y deniegan acceso a ciertos servicios y hosts. Cuando tcpd gestiona una petición para un servicio como finger desde un host cliente llamado biff.foobar.com, se busca en hosts.allow y hosts.deny (en este orden) una entrada que coincida tanto con el servicio como con el host cliente. Si se encuentra la entrada correspondiente en hosts.allow, se autoriza el acceso y tcpd no consulta el fichero hosts.deny. Si no se encuentra una coincidencia en el fichero hosts.allow, pero se encuentra en el hosts.deny, la petición es rechazada cerrando la conexión. La petición es aceptada si no hay correspondencias en ninguno de los ficheros.

Las entradas en los ficheros de acceso tienen un aspecto como este:
    lista_de_servicios: lista_de_hosts [:órdenes_de_shell]

lista_de_servicios es una lista de nombres de servicio de /etc/services, o la palabra clave ALL. Para hacer coincidir a todos los servicios excepto finger y tftp, se usa ALL EXCEPT finger, tftp.

lista_de_hosts es una lista de nombres de hosts, direcciones IP, o las palabras clave ALL, LOCAL, UNKNOWN o PARANOID. ALL coincide con cualquier host, mientras que LOCAL coincide con nombres de host que no contienen un punto.[3] UNKNOWN coincide con cualquier host cuya búsqueda de nombre o dirección falle. PARANOID coincide con cualquier host cuyo nombre de host no se resuelva de vuelta a su dirección IP. [4] Un nombre que empice por un punto hace coincidir todos los hosts cuyo dominio es igual a este nombre. Por ejemplo, .foobar.com coincide biff.foobar.com, pero no nurks.fredsville.com. Un patrón que termine con un punto coincide con cualquier host cuya dirección IP comience con el patrón proporcionado, así que 172.16. coincide con 172.16.32.0, pero no con 172.15.9.1. Un patrón de la forma n.n.n.n/m.m.m.m es tratado como una dirección IP y la máscara de red, así que podemos especificar nuestro ejemplo anterior como 172.16.0.0/255.255.0.0 en su lugar. Finalmente, cualquier patrón que empiece por el carácter “/” permite especificar un fichero que se presume que contiene una lista de nombres de host o patrones de direcciones IP, con cualquiera de los cuáles se permite la coincidencia. Así que un patrón que se parezca a /var/access/trustedhosts causaría que el demonio tcpd lea este fichero, verificando si alguna de sus líneas coincide con el host que está conectándose.

Para denegar acceso a los servicios finger y tftp a todos menos al los hosts locales, ponga lo siguiente en /etc/hosts.deny y deje vacío /etc/hosts.allow:
    in.tftpd, in.fingerd: ALL EXCEPT LOCAL, .su.dominio

El campo opcional orden_de_shell puede contener una orden del intérprete de órdenes [5] para ser invocada cuando la entrada coincida. Esto es útil para establecer trampas que puedan exponer a los atacantes potenciales. El siguiente ejemplo crea un fichero de registros que lista al usuario y al host que se conecta, y si el host no es vlager.vbrew.com se concatenará la salida de un finger a ese host:
    in.ftpd: ALL EXCEPT LOCAL, .vbrew.com : \
          echo "request from %d@%h:" >> /var/log/finger.log; \
          if [ %h != "vlager.vbrew.com:" ]; then \ 
              finger -l @%h >> /var/log/finger.log \
          fi

Los argumentos %h y %d son expandidos por tcpd como el nombre del host del cliente y el nombre del servicio, respectivamente. Por favor dirígase a la página de manual hosts_access(5) para más detalles.

Notas

[1]

wrapper en inglés

[2]

escrito por Wietse Venema, wietse@wzv.win.tue.nl.

[3]

Habitualmente sólo los nombres de hosts locales obtenidos a través de búsquedas en /etc/hosts no contienen puntos.

[4]

Mientras este nombre sugiere una medida extrema, la palabra clave PARANOID es buena por omisión, y le protege contra hosts maliciosos que pretenden hacerse pasar por lo que no son. No todos los tcpd se proporcionan con la palabra clave PARANOID compilada; si el suyo no la tiene, necesitará recompilar tcpd para usarla.

[5]

shell