Creación y gestión de demonios en Linux usando SystemD
Resumen
La gestión de demonios en Linux es una habilidad fundamental para cualquier administrador de sistemas. Estos procesos en segundo plano permiten que nuestro sistema operativo funcione de manera eficiente, ejecutando tareas críticas sin intervención directa del usuario. Dominar la creación y administración de demonios te dará un control más profundo sobre tu sistema Linux, permitiéndote automatizar tareas y crear servicios personalizados que se ejecuten según tus necesidades específicas.
¿Qué son los demonios en Linux y para qué sirven?
Los demonios son un mecanismo que tiene Linux para darle un comportamiento de servicio a los procesos. Esto significa que podemos configurarlos para que se inicien automáticamente al arrancar el sistema, bajo condiciones específicas y con comportamientos predeterminados.
Estos servicios se crean a través de archivos de configuración llamados "Unit Files", que definen cómo y cuándo debe ejecutarse un demonio. Un caso de uso común es cuando necesitamos que un script (por ejemplo, en Python) se ejecute constantemente realizando una función específica sin intervención manual.
El primer y más importante demonio en Linux es SystemD, que funciona como el gestor principal de todos los demás demonios del sistema. SystemD es responsable de iniciar componentes críticos como:
Drivers de red
Entorno gráfico
Servicios esenciales del sistema operativo
Para interactuar con SystemD, utilizamos SystemCTL (System Control), que proporciona una interfaz para gestionar los demonios y servicios del sistema.
¿Cómo crear y configurar un demonio personalizado?
Para demostrar el proceso de creación de un demonio, vamos a implementar un simple script de Python que funcione como un logger básico, registrando la fecha actual cada segundo en un archivo.
Preparando el script
Primero, necesitamos crear nuestro script de Python:
import time
from datetime import datetime
whileTrue:file=open('/date_logs/timestamp.txt','a')file.write(f"Timestamp: {datetime.now()}\n")file.close() time.sleep(1)
Este script simplemente:
Abre un archivo en modo append (añadir)
Escribe la fecha y hora actual
Cierra el archivo
Espera un segundo antes de repetir el proceso
Configurando el entorno
Para que nuestro script funcione correctamente, debemos:
Verificar que Python esté instalado:
python3 -V
Crear el directorio donde se guardarán los logs:
mkdir /date_logs
Crear un directorio para nuestros scripts:
mkdir /root/scripts
Guardar nuestro script en la ubicación adecuada:
vim /root/scripts/logger.py
Creando el Unit File
El Unit File es la configuración que SystemD utilizará para gestionar nuestro demonio. Debemos crearlo en la ubicación correcta:
Este archivo de configuración tiene tres secciones principales:
[Unit]: Contiene metadatos y dependencias
Description: Una descripción simple del servicio
After: Indica que este servicio debe iniciarse después del target especificado
[Service]: Define el comportamiento del servicio
Type: Especifica el tipo de proceso (simple, forking, oneshot, etc.)
Restart: Determina cuándo reiniciar el servicio (always, on-failure, etc.)
ExecStart: El comando que se ejecutará para iniciar el servicio
[Install]: Configura cómo se instala el servicio
WantedBy: Especifica en qué target debe incluirse este servicio
Activando y gestionando el demonio
Una vez creado el Unit File, debemos recargar SystemD para que reconozca los cambios:
systemctl reload
Para habilitar el servicio para que se inicie automáticamente al arrancar el sistema:
systemctl enable loggerPython.service
Para iniciar manualmente el servicio:
systemctl start loggerPython.service
Para verificar el estado del servicio:
systemctl status loggerPython.service
Para detener el servicio:
systemctl stop loggerPython.service
Para deshabilitar el inicio automático:
systemctl disable loggerPython.service
¿Cómo funcionan los targets y niveles de ejecución?
En SystemD, los targets son similares a los niveles de ejecución (runlevels) en sistemas SysV init tradicionales. El target multi-user.target que utilizamos en nuestro ejemplo se activa después de que todos los servicios esenciales (red, drivers, etc.) se han iniciado, permitiendo el acceso a una consola de texto.
Los targets definen puntos específicos en el proceso de arranque y determinan qué servicios deben estar activos en cada etapa. Esto permite una gestión más granular y flexible de los servicios del sistema.
Dominar la creación y gestión de demonios en Linux te permitirá automatizar tareas, crear servicios personalizados y tener un mayor control sobre tu sistema. ¿Has creado algún demonio personalizado para alguna tarea específica? Comparte tu experiencia en los comentarios y explora otras posibilidades para aprovechar esta potente característica de Linux.
Es un proceso de Linux que da un comportamiento de servicio a un programa: es decir, que se ejecuta en segundo plano sin la interacción de un usuario.
systemd : crea los demonios
systemctl: gestiona los demonios
Para crear un demonio primero debes:
Crear el script o unit file que usará de base tu demonio, esto puedes hacerlo con Python u otro lenguaje de scripting.
Es importante crear el folder donde se alojará el unit file a nivel de root, de esta manera estará disponible para todos los usuarios.
Crear la carpeta en donde alojaremos la información generada por nuestro unit file.
ir a /etc/systemd/system y crear el script que beberá del primero para poder correr el demonio.
reiniciamos los demonios con:
systemctl daemons-reload
Habilitamos con:
systemctl enable loggerpython.service
Activamos con:
systemctl start loggerpython.service
Gracias por el aporte.
Muchas gracias por tu resumen en estos pasos, gran aporte!!!
mi aporte en ruby guardandolo en un archivo llamado poem
classFile def self.my_open(filename, mode) file = self.new(filename, mode)return file unless block_given? begin
yield file
rescue Exception=> e
p e.message ensure
file.close end
end
end
File.my_open("poem.txt","w")do|f| f.puts"Hello world"whiletruesleep(1) f.putsTime.now end
end
Intento con bash
#!/bin/bash#
# datetime logger
#
# Usage:# -First make it executable by running chmod +x ./logger.sh# -Then run it with./logger.sh#
# If run from the right location(/scripts) and with the right privileges(root) it shouldn't produce errors but you can always redirect the stderr to a file or to /dev/nullif you need to.# that would be ./logger.sh2> error.log or ./logger.sh2>/dev/nullwhiletrue;do echo "Timestamp: $(date '+%Y-%m-%d %H:%M:%S')">>/datelogs/timestamp.txt sleep 1done
Interesante: ¿Por qué "Daemon" (con a) y no "Demon" (sin a)? Porque en la mitología griega un "daimon" era un espíritu que guiaba y servía como intermediario entre los dioses y los humanos. No era malo, era una guía, una ayuda. En los 60s, los desarrolladores de los sistemas Unix querían tener esa misma "ayuda" o "intermediario" entre el sistema y sus operaciones, por eso adoptaron la palabra "daemon", para evitar hacer una referencia negativa con la palabra "demon"... aunque en realidad, se pronuncia igual: "dee - muhn". ¿Será que en español deberíamos decir "daimon" en vez de "demonio" para evitar la referencia negativa?
Esto ya lo había hecho en la universidad :0 pero no sabía que se llamaban "unit files" solo les conocia como scripts de arranque
si dice que el directorio no existe pongan solo dos puntos a la ruta, recuerden que python aveces o dependiendo su configuracion siempre hace referencia desde el punto donde esta y no desde el /home
IMPLEMENTACIÓN DE UN ARCHIVO DE UNIDAD DE SERVICIO (DAEMON)
.
La implementación de un archivo de unidad de servicio en systemd implica seguir una sintaxis específica y definir varias opciones de configuración. Aquí hay un ejemplo básico de cómo sería la implementación de un archivo de unidad de servicio:
.
Abre un editor de texto y crea un nuevo archivo con una extensión .service. Por ejemplo, puedes usar el comando sudo nano /etc/systemd/system/mi_servicio.service para crear y abrir el archivo con el editor de texto nano (asegúrate de tener privilegios de superusuario para realizar esta operación).
.
En el archivo, define las siguientes secciones y opciones de configuración:
[Unit]Description=Descripción de mi servicio
After=network.target # Dependencias, si es necesario
[Service]ExecStart=/ruta/al/comando-de-inicio # Comando para iniciar el servicio
ExecStop=/ruta/al/comando-de-detencion # Comando para detener el servicio, si es necesario
Restart=always # Opciones de reinicio, si es necesario
User=nombre_de_usuario # Usuario bajo el cual se ejecuta el servicio
Group=nombre_de_grupo # Grupo asociado al servicio
WorkingDirectory=/ruta/al/directorio/de/trabajo # Directorio de trabajo del servicio, si es necesario
[Install]WantedBy=multi-user.target # Objetivo en el que se habilitará el servicio
Reemplaza /ruta/al/comando-de-inicio con la ruta absoluta del comando que se utilizará para iniciar el servicio. Puede ser un script, un binario o cualquier otro comando necesario para iniciar tu servicio.
.
Opcionalmente, reemplaza /ruta/al/comando-de-detencion con la ruta absoluta del comando que se utilizará para detener el servicio, si es necesario. Si no se especifica, systemd intentará detener el servicio enviando una señal SIGTERM al proceso principal.
.
Opcionalmente, ajusta las otras opciones de configuración según las necesidades de tu servicio.
.
Guarda y cierra el archivo.
.
Ejecuta el comando sudo systemctl daemon-reload para que systemd reconozca el nuevo archivo de unidad de servicio.
.
Para iniciar el servicio, usa el comando sudo systemctl start mi_servicio (reemplaza mi_servicio con el nombre del archivo de unidad de servicio sin la extensión .service).
.
Para detener el servicio, usa el comando sudo systemctl stop mi_servicio.
Para habilitar que el servicio se inicie automáticamente en el arranque del sistema, usa el comando sudo systemctl enable mi_servicio.
.
Con estos pasos, has implementado un archivo de unidad de servicio básico en systemd. Recuerda que puedes ajustar y personalizar las opciones de configuración según las necesidades específicas de tu servicio.
.
Fuente:ChatGPT.
En Linux, un “unit file” es un archivo de configuración utilizado por systemd, el sistema init y administrador de servicios. Estos archivos definen cómo systemd debe manejar un recurso del sistema12.
Características de los unit files:
Definen servicios: Los unit files más comunes son los que terminan en .service, que definen cómo iniciar, detener y administrar servicios.
Ubicación: Se encuentran en /etc/systemd/system/ o /lib/systemd/system/ y pueden ser creados y editados por el usuario o proporcionados por paquetes instalados.
Formato: Son archivos de texto que utilizan una sintaxis específica para definir la configuración del servicio o recurso.
Tipos de unidades: Además de servicios, pueden definir otros tipos de recursos como dispositivos, puntos de montaje, trabajos cron, sockets y más.
Ejemplo de un unit file para un servicio:
[Unit]
Description=Mi Servicio Personalizado
After=network.target
[Service]
ExecStart=/usr/bin/mi_servicio
User=mi_usuario
Restart=on-failure
[Install]
WantedBy=multi-user.target
Este es un ejemplo básico de cómo se ve un unit file para un servicio. Define cuándo se debe iniciar el servicio (After), qué comando ejecutar (ExecStart), bajo qué usuario (User), y qué hacer si falla (Restart). También especifica que el servicio debe iniciarse con el nivel de ejecución multi-user.target2.
Los unit files son fundamentales para el funcionamiento de systemd, ya que le permiten gestionar los servicios y otros recursos del sistema de manera eficiente y modular.
El manejo de systemctl es muy utilizado cuando creas tu servidor apache para utilizarlo con PHP, debes realizar esos pasos y es muy interesante. Les recomiendo instalar PHP en Linux y vean cada paso para validar esos procesos
Vemos estado con:
<systemctl status loggerpython.service>
Habilitamos con:
<systemctl enable loggerpython.service>
Activamos con:
< systemctl start loggerpython.service>
Detenemos con
< systemctl stop loggerpython.service>
Desahabilitamos con
< systemctl disable loggerpython.service>
Estoy impresionado con lo que pueden hacer los demonios y como son creados a ser ejecutados sin ningun problema. Aprendi mucho de crearlos y manejarlos. Esta fue una gra clase que no olvidare. A seguir
Los demonios terminan siendo los servicios en WIndows?
Los comando de systemd y systemctl se usan mucho, yo lo hice cuando hice un laboratorio para desplegar una aplicacion web hecha con asp.net y .net 10.
el primer enlace de lecturas recomendadas ya no funciona
En pocas palabras los demonios son la alternativa en Linux a lo que en Windows conocemos como services
donde se descargan los recursos?
Los recursos estan debajo de los videos, en el apartado de recursos
Código transformado a TypeScript y con comentarios agregados
import*as fsfrom'fs';import*as pathfrom'path';import{ promisify }from'util';const sleep =promisify(setTimeout);asyncfunctionwriteTimestamp():Promise<void>{const filePath ='/datelogs/timestamp.txt';while(true){// Open the file in append modeconst fileHandle =await fs.promises.open(filePath,'a');try{// Get the current timestampconst timestamp =newDate().toISOString();// Append the timestamp to the fileawait fileHandle.appendFile(`\nTimestamp: ${timestamp}`);}finally{// Close the file handleawait fileHandle.close();}// Wait for 1 secondawaitsleep(1000);}}writeTimestamp().catch(console.error);
Muy interesante lo que un script malicioso puede hacer.