12.1. El Super Servidor inetd

Los programas que proporcionan servicios de aplicación a través de la red se llaman demonios[1]. Un demonio es un programa que abre un puerto, comúnmente un puerto de algún servicio bien conocido, y espera conexiones entrantes en él. Si ocurre una, el demonio crea un proceso hijo que acepta la conexión, mientras que el proceso padre continúa escuchando más peticiones. Este mecanismo funciona bien, pero tiene unas pocas desventajas; al menos una instancia de cada posible servicio que se quiera proporcionar, debe estar activa en memoria a todas horas. Además, la rutina software que hacen la escucha y la gestión del puerto tiene que ser replicada en cada uno de los demonios de red.

Para superar estas ineficiencias, muchas instalaciones Unix ejecutan un demonio de red especial, el cual debe ser considerado como un “super servidor.” Este demonio crea sockets en nombre de cada uno de los servicios y escucha en todos ellos simultáneamente. Cuando una conexión entrante es recibida en cualquiera de esos sockets, el super servidor acepta la conexión y replica el servicio especificado para ese puerto, pasando el socket a gestionarse a través del proceso hijo. El servidor entonces, vuelve a la escucha.

startup El super servidor más común se llama inetd, el Demonio de Internet[2]. Se inicia en tiempo de arranque del sistema y toma la lista de servicios que ha de gestionar de un fichero de inicialización llamado /etc/inetd.conf. Además de estos servidores, hay un número de servicios triviales realizados por inetd llamados servicios internos. Se incluyen chargen, el cuál simplemente genera una cadena de caracteres, y daytime, el cuál devuelve la idea del sistema de la hora del día.

Una entrada en este fichero consiste en una sola línea compuesta de los siguientes campos:
    servicio tipo protocolo espera usuario servidor línea_de_órdenes

Cada uno de los campos se describe en la siguiente lista:

servicio

Da el nombre del servicio. El nombre del servicio tiene que ser traducido a un número de puerto buscándolo en el fichero /etc/services. Este fichero se describirá más tarde en este capítulo, en la sección “ Sección 12.3.”

tipo

Especifica la clase de socket, o un socket de flujo “stream” (para protocolos orientados a la conexión) o un socket de datagrama “dgram” (para protocolos orientados a datagramas). Los servicios basados en TCP deberían entonces utilizar siempre sockets de flujo, stream, mientras que servicios basados en UDP deberían utilizar sockets de datagramas, dgram.

protocolo

Nombra el protocolo de transporte usado por el servicio. Debe ser un nombre válido de protocolo que se encuentre en el fichero protocols, expuesto más adelante.

espera

Esta opción se aplica sólo a sockets dgram. Puede ser wait[3] o nowait[4]. Si se especifica wait, inetd ejecuta sólo un servidor para el puerto especificado. El otro modo, continúa escuchando inmediatamente en el puerto después de ejecutar el servicio.

Esto es usado para servidores “de hilo único”[5] que leen todos los datagramas entrantes hasta que no llegan más, y después terminan. Muchos servidores RPC son de este tipo y tienen que ser especificados como wait. El tipo opuesto, “multi-hilo”, [6] permite la ejecución concurrente de un número ilimitado de instancias. Estos servidores deben especificarse como nowait.

Los sockets de flujo, “stream”, deben usar siempre nowait.

usuario

Esto es el identificador de registro del usuario[7] que será propietario del procesos mientras se esté ejecutando. Éste será muchas veces el usuario root, pero algunos servicios pueden usar cuentas distintas. Es una buena idea aplicar el principio del mínimo privilegio aquí, lo que significa que usted no debe ejecutar órdenes bajo cuentas privilegiadas si el programa no requiere esto para su correcto funcionamiento. Por ejemplo, el servidor de noticias NNTP ejecutado como news, mientras sirve noticias puede ser un riesgo de seguridad (como tftp o finger) que son muchas veces ejecutados como nobody.

servidor

Proporciona el camino completo del programa servidor a ser ejecutado. Los servicios internos se marcan con la palabra clave internal.

línea_de_órdenes

Esta es la línea de órdenes que se va a pasar al servidor. Comienza con el nombre del servidor a ejecutar y puede incluir cualquier argumento que se le necesiten pasar. Si está usando encapsulación TCP [8], especificará el camino completo al servidor aquí. Si no, entonces especificará el nombre del servidor como quiera que aparezca en un listado de procesos. Hablaremos acerca de encapsulación TCP brevemente.

Este campo está vacío para los servicios internos.

Un ejemplo del fichero inetd.conf se expone en Ejemplo 12-1. El servicio finger está comentado así que no está disponible. Esto se hace a menudo por razones de seguridad, porque puede ser usado por atacantes para obtener nombres y otros detalles de los usuarios de su sistema.

Ejemplo 12-1. Un ejemplo del fichero /etc/inetd.conf

    # 
    # inetd services
    ftp      stream tcp nowait root  /usr/sbin/ftpd    in.ftpd -l
    telnet   stream tcp nowait root  /usr/sbin/telnetd in.telnetd -b/etc/issue
    #finger  stream tcp nowait bin   /usr/sbin/fingerd in.fingerd
    #tftp    dgram  udp wait  nobody /usr/sbin/tftpd   in.tftpd
    #tftp    dgram  udp wait  nobody /usr/sbin/tftpd   in.tftpd /boot/diskless
    #login   stream tcp nowait root  /usr/sbin/rlogind in.rlogind
    #shell   stream tcp nowait root  /usr/sbin/rshd    in.rshd
    #exec    stream tcp nowait root  /usr/sbin/rexecd  in.rexecd
    #
    #       inetd internal services
    #
    daytime  stream tcp nowait root internal
    daytime  dgram  udp nowait root internal
    time     stream tcp nowait root internal
    time     dgram  udp nowait root internal
    echo     stream tcp nowait root internal
    echo     dgram  udp nowait root internal
    discard  stream tcp nowait root internal
    discard  dgram  udp nowait root internal
    chargen  stream tcp nowait root internal
    chargen  dgram  udp nowait root internal

El demonio tftp se muestra comentado también. tftp implementa el Trivial File Transfer Protocol (TFTP), el cual permite transferir cualquier fichero con permisos de lectura globales desde su sistema sin verificación de contraseña. Esto es especialmente perjudicial para el fichero /etc/passwd, e incluso más cuando no usan claves “shadow”.

TFTP se usa normalmente por clientes sin disco duro y por Terminales X para descargar su código desde un servidor de arranque. Si necesita ejecutar tftpd por esta razón, asegúrese de limitar su alcance a aquellos directorios desde los cuáles los clientes obtendrán los ficheros; deberá añadir esos nombres de directorio a la línea de órdenes de tftpd. Esto se muestra en la segunda línea de tftp en el ejemplo.

Notas

[1]

daemons

[2]

Internet Daemon en inglés, N. del T.

[3]

espera

[4]

no espera

[5]

single-threaded

[6]

multi-threaded

[7]

login ID

[8]

TCP wrapper