Product SiteDocumentation Site

Capítulo 9. Servicios Unix

9.1. Arranque del sistema
9.1.1. El sistema de inicio systemd
9.1.2. El sistema de inicio System V
9.2. Inicio de sesión remoto
9.2.1. Inicio seguro de sesión remota: SSH
9.2.2. Utilización de escritorios gráficos remotos
9.3. Administración de permisos
9.4. Interfaces de administración
9.4.1. Administración en una interfaz web: webmin
9.4.2. Configuración de paquetes: debconf
9.5. syslog Eventos de sistema
9.5.1. Principio y mecanismo
9.5.2. El archivo de configuración
9.6. El superservidor inetd
9.7. Programación de tareas con cron y atd
9.7.1. Formato de un archivo crontab
9.7.2. Utilización del programa at
9.8. Programación de tareas asincrónicas: anacron
9.9. Cuotas
9.10. Respaldo
9.10.1. Respaldos con rsync
9.10.2. Restauración de equipos sin repaldos
9.11. Conexión en caliente: hotplug
9.11.1. Introducción
9.11.2. El problema de nombres
9.11.3. Cómo funciona udev
9.11.4. Un ejemplo concreto
9.12. Gestión de energía: interfaz avanzada de configuración y energía (ACPI: «Advanced Configuration and Power Interface)
Este capítulo cubre un número básico de servicios que son comunes a varios sistemas Unix. Todos los administradores deberían estar familiarizados con ellos.

9.1. Arranque del sistema

Cuando inicia el equipo, los muchos mensajes que aparecen en la pantalla muestran varias inicializaciones y configuraciones automáticas que se están ejecutando. Algunas veces deseará alterar ligeramente cómo funciona esta etapa, lo que significa que necesitará entenderlas bien. Éste es el propósito de esta sección.
Primero el BIOS toma el control del equipo, detecta los discos, carga el registro maestro de arranque («MBR») y ejecuta el gestor de arranque. Éste toma el control, busca el núcleo en el disco, lo carga y lo ejecuta. Luego se inicializa el núcleo y empieza la búsqueda y montaje de la partición que contiene el sistema de archivos raíz y finalmente ejecuta el primer programa — init. Frecuentemente esta «partición raíz» y su init están, de hecho, ubicados en un archivo virtual del sistema que sólo existe en RAM (de aquí el nombre «initramfs», anteriormente llamado «initrd» por «disco RAM de inicialización»: «initialization RAM disk»). El gestor de arranque carga este sistema de archivos en memoria, muchas veces desde un archivo en el disco duro o desde la red. Contiene sólo lo mínimo requerido por el núcleo para cargar el «verdadero» sistema de archivos raíz: estos pueden ser módulos de controladores para el disco duro u otros dispositivos sin los cuales el sistema no puede iniciar o, más frecuentemente, scripts de inicialización y módulos para ensamblar arreglos RAID, abrir particiones cifradas, activar volúmenes LVM, etc. Una vez que se monta la partición raíz, el initramfs entrega el control al verdadero init y la máquina regresa al proceso de inicio estándar.
Secuencia de inicio de un equipo ejecutando Linux con systemd

Figura 9.1. Secuencia de inicio de un equipo ejecutando Linux con systemd

9.1.1. El sistema de inicio systemd

Actualmente systemd proporciona el «init real» y esta sección documenta este sistema de inicio.
Systemd ejecuta varios procesos que se encargan de configurar el sistema: teclado, controladores, sistemas de archivos, redes, servicios. Hace esto a la vez que mantiene una visión global del sistema como un todo y de los requerimientos de los componentes. Cada componente se describe en un fichero unidad o "unit file" (a veces más de uno). La sintaxis de los mismos se deriva de la de los muy extendidos archivos ".ini". Es decir que utiliza pares clave = valor agrupados entre cabeceras de [sección]. Los archivos unit se guardan en /lib/systemd/system/ y /etc/systemd/system/. Aunque hay varios tipos, aquí nos vamos a concentrar en los servicios ("services") y metas ("targets").
Un archivo de servicio ("service file") de systemd describe un proceso gestionado por systemd. Contiene más o menos la misma información que los antiguos scripts de inicio, pero expresada en de forma declarativa (y mucho más concisa). Systemd se ocupa de la mayoría de las tareas repetitivas (arrancar y parar el proceso, comprobar su estado, registrar los errores, soltar privilegios, etc) y el archivo de servico únicamente tiene que proporcionar los parámetros especificos de cada servicio. Por ejemplo aquí se muestra el fichero de servicio para SSH:
[Unit]
Description=OpenBSD Secure Shell server
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target
Alias=sshd.service
Como se puede comprobar no hay apenas código, únicamente declaraciones. Systemd se ocupa de mostrar los informes de progreso, de controlar los procesos e incluso de reiniciarlos cuando sea necesario.
Un fichero de meta ("target file") describe un estado del sistema en el cual se sabe que está operativo un conjunto de servicios. Se puede hacer una analogía los antiguos niveles de ejecución ("runlevels"). Una de las metas es local-fs.target; cuando se alcanza, el resto del sistema puede asumir que todos los sistemas de archivos locales están montados y son accesibles. Otros ejemplos de metas pueden ser network-online.target o sound.target. Las dependencias de una meta se pueden establecer directamente en su archivo de configuración o "target file" (en la línea Requires=) o bien utilizando un enlace simbólico a un archivo de servicio ("service file") en el directorio /lib/systemd/system/targetname.target.wants/. Por ejemplo /etc/systemd/system/printer.target.wants/ contiene un enlace a /lib/systemd/system/cups.service; systemd se asegurará de que CUPS esté en ejecución para poder alcanzar la meta printer.target.
Puesto que los archivos de unidad son declarativos en lugar de scripts o programas, no se pueden ejecutar directamente; tienen que ser interpretados por systemd. Existen varias utilidades que permiten al administrador interactuar con systemd y controlar el estado del sistema y de cada componente.
La primera de estas utilidades es systemctl. Cuando se ejecuta sin argumentos lista todos los archivos de unidad conocidos por systemd (excepto los que han sido deshabilitados), así como su estado. systemctl status muestra una visión mejor de los servicios y sus procesos relacionados. Si se proporciona el nombre de un servico (como p.ej. systemctl status ntp.service) muestra aún más detealles, así como las últimas líneas del registro relacionadas con el servicio (más información más adelante).
Para arrancar un servicio manualmente basta ejecutar systemctl start nombredelservicio.service. Como se puede suponer, para parar un servicio se hace con systemctl stop nombredelservicio.service; otros subcomandos disponibles son reload y restart.
Para establecer si un servicio está activo (es decir, si se debe arrancar automáticamente al inicio o no) utilce el comando systemctl enable nombredelservicio.service (o disable). is-enabled permite saber si está activo o no.
Una característica interesante de systemd es que incluye un componente de registro llamado journald. Viene como complemento a los sistemas de registro tradicionales como syslogd, pero añade características interesantes como un enlace formal entre un servicio y los mensajes que genera, así como la posibilidad de capturar los mensajes de error generados por su secuencia de inicialización. Los mensajes se pueden mostrar con la ayuda del comando journalctl. Sin argumentos símplemente vuelca todos los mensajes que han ocurrido desde el arranque del sistema, aunque no se suele utilizar de esa forma. Normalmente se utiliza con un identificador de servicio:
# journalctl -u ssh.service
-- Logs begin at Tue 2015-03-31 10:08:49 CEST, end at Tue 2015-03-31 17:06:02 CEST. --
Mar 31 10:08:55 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.
Mar 31 10:08:55 mirtuel sshd[430]: Server listening on :: port 22.
Mar 31 10:09:00 mirtuel sshd[430]: Received SIGHUP; restarting.
Mar 31 10:09:00 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.
Mar 31 10:09:00 mirtuel sshd[430]: Server listening on :: port 22.
Mar 31 10:09:32 mirtuel sshd[1151]: Accepted password for roland from 192.168.1.129 port 53394 ssh2
Mar 31 10:09:32 mirtuel sshd[1151]: pam_unix(sshd:session): session opened for user roland by (uid=0)
Otra opción útil es -f, que hace que journalctl siga mostrando los nuevos mensajes a medida que se van emitiendo (semejante a lo que ocurre con tail -f file).
Si un servicio parece que no está funcionando como debiera, el primer paso para resolver el problema es comprobar si el servicio está ejecutándose realmente mediante systemctl status. Si no es así y los mensajes que se muestran no son suficientes para diagnosticar el problema se pueden comprobar los registros que ha recogido journald relacionados con es servicio. Por ejemplo, suponiendo que el servidor SSH no funciona:
# systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
   Active: failed (Result: start-limit) since Tue 2015-03-31 17:30:36 CEST; 1s ago
  Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
  Process: 1188 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=255)
 Main PID: 1188 (code=exited, status=255)

Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.
Mar 31 17:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
# journalctl -u ssh.service
-- Logs begin at Tue 2015-03-31 17:29:27 CEST, end at Tue 2015-03-31 17:30:36 CEST. --
Mar 31 17:29:27 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.
Mar 31 17:29:27 mirtuel sshd[424]: Server listening on :: port 22.
Mar 31 17:29:29 mirtuel sshd[424]: Received SIGHUP; restarting.
Mar 31 17:29:29 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.
Mar 31 17:29:29 mirtuel sshd[424]: Server listening on :: port 22.
Mar 31 17:30:10 mirtuel sshd[1147]: Accepted password for roland from 192.168.1.129 port 38742 ssh2
Mar 31 17:30:10 mirtuel sshd[1147]: pam_unix(sshd:session): session opened for user roland by (uid=0)
Mar 31 17:30:35 mirtuel sshd[1180]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:35 mirtuel sshd[1182]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:35 mirtuel sshd[1184]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel sshd[1186]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel sshd[1188]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.
Mar 31 17:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
# vi /etc/ssh/sshd_config
# systemctl start ssh.service
# systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
   Active: active (running) since Tue 2015-03-31 17:31:09 CEST; 2s ago
  Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 1222 (sshd)
   CGroup: /system.slice/ssh.service
           └─1222 /usr/sbin/sshd -D
# 
Después de comprobar el estado del servicio (fallido) comprobamos los registros; indican un error en el archivo de configuración. Después de editar el archivo de configuración y corregir el error reiniciamos el servicio y comprobamos que efectivamente está funcionando.

9.1.2. El sistema de inicio System V

El sistema de incio System V (al cual llamaremos init por brevedad) ejecuta varios procesos siguiendo instrucciones del archivo /etc/inittab. El primer programa que ejecuta (que se corresponde con el paso sysinit) es /etc/init.d/rcS, un script que ejecuta todos los programas del directorio /etc/rcS.d/.
Entre estos encontrará sucesivamente programas a cargo de:
  • configurar el teclado de la consola;
  • cargar controladores: el núcleo carga por sí mismo la mayoría de los módulos a medida que el hardware es detectado; los controladores extras se cargan automáticamente cuando los módulos correspondientes son listados en /etc/modules;
  • verificar la integridad de los sistemas de archivos;
  • montar particiones locales;
  • configurar la red;
  • montar sistemas de archivos de red (NFS).
Despues de esta etapa, init toma el control e inicia los programas activados en el nivel de ejecución («runlevel») predeterminado (generalmente el nivel 2). Ejecuta /etc/init.d/rc 2, un script que inicia todos los servicios enumerados en /etc/rc2.d/ y aquellos cuyos nombres comiencen con la letra «S». Los números de dos cifras que le sigue fueron utilizados históricamente para definir el orden en el que se iniciarán los servicios, pero actualmente el sistema de inicio predeterminado utiliza insserv, que programa todo automáticamente basándose en las dependencias de los scripts. Cada script de inicio, por lo tanto, declara las condiciones a cumplir para iniciar o detener el servicio (por ejemplo, si debe iniciar antes o después de otro servicio); init luego los ejecuta en un orden que satisfaga estas condiciones. El enumerado estático de los scripts ya no se tiene en cuenta (pero sus nombres siempre deben comenzar con «S» seguidos de dos números y el nombre real del script utilizado para dependencias). Generalmente, se inician primero los servicios de base (como los registros con rsyslogd o la asociación de puertos con portmap) seguidos de los servicios estándar y la interfaz gráfica (gdm).
Este sistema de inicio basado en dependencias hace posible renumerar automáticamente los scripts, lo que sería tediososo de hacer manualmente y limita el riesgo de error humano ya que se realiza la programación según los parámetros indicados. Otro beneficio es que se pueden iniciar los servicios en paralelo cuando son independientes entre ellos, lo cual puede acelerar el proceso de inicio.
init distingue varios niveles de ejecución («runlevel») y puede cambiar de uno a otro ejecutando telinit nuevo-nivel. Inmediatamente, init ejecuta nuevamente /etc/init.d/rc con el nuevo nivel de ejecución. Luego, este script ejecutará los servicios faltantes y detendrá aquellos que ya no se desean. Para hacerlo, se refiere al contenido del archivo /etc/rcX.d (donde X representa el nuevo nivel de ejecución). Los scripts cuyos nombres comienzan con «S» (por «start», iniciar) son los servicios a iniciar; aquellos cuyos nombres comienzan con «K» (por «kill», matar) son los servicios a detener. El script no inicia ningún servicio que ya haya estado activo en el nivel de ejecución anterior.
De forma predeterminada, el inicio System V en Debian utiliza cuatro niveles de ejecución diferentes:
  • Nivel 0: sólo se lo utiliza temporalmente mientras se apaga el equipo. Como tal, sólo contiene scripts «K».
  • Nivel 1: también conocido como modo de usuario único, corresponde al sistema en modo degradado; sólo incluye servicios básicos y está destinado a operaciones de mantenimiento donde no se desea la interacción con usuarios normales.
  • Nivel 2: es el nivel para operaciones normales, lo que incluye servicios de red, una interfaz gráfica, sesiones de usuario, etc.
  • Nivel 6: similar a nivel 0, excepto a que es utilizada durante la fase de cierre que precede a un reinicio.
Existe otros niveles, especialmente del 3 al 5. De forma predeterminara están configurados para operar de la misma forma que el nivel 2, pero el administrador puede modificarlos (agregando o eliminando scripts en los directorios /etc/rcX.d correspondientes) para adaptarlos a necesidades particulares.
Secuencia de inicio de un equipo ejecutando Linux con inicio System V

Figura 9.2. Secuencia de inicio de un equipo ejecutando Linux con inicio System V

Todos los scripts en los varios directorios /etc/rcX.d son sólo enlaces simbólicos — creados durante la instalación del paquete por el programa update-rc.d — que apuntan a los scripts reales que están almacenados en /etc/init.d/. El administrador puede ajustar los servicios disponibles en cada nivel de ejecución ejecutando update-rc.d nuevamente con los parámetros correctos. La página de manual update-rc.d(1) describe la sintaxis en detalle. Sepa que eliminar todos los enlaces simbólicos (con el parámetro remove) no es un buen método de desactivar un servicio. En su lugar, simplemente debería configurar para que el mismo no se ejecute en el nivel de ejecución deseado (preservando las llamadas para detenerlo en caso que el servicio esté ejecutando en el nivel de ejecución anterior). Debido a que update-rc.d tiene una interfaz bastante compleja, puede preferir utilizar rcconf (en el paquete rcconf) que provee una interfaz mucho más amigable.
Finalmente, init inicia los programas de control para varias consolas virtuales (getty). Muestra un prompt esperando por un nombre de usuario y luego ejecuta login usuario para iniciar una sesión.