Capítulo 8.2 - Servicios Personalizados
Objetivos de Aprendizaje
Al final de este capítulo, usted será capaz de:
- Crear un archivo unit de systemd
- Configurar un servicio personalizado
- Comprender las secciones de un unit file
- Gestionar las dependencias
- Crear servicios para scripts
Estructura de un Unit File
Ubicación
# Sistema
/etc/systemd/system/
# Usuario
~/.config/systemd/user/
Prioridad:
/etc/systemd/system/(sistema) >/usr/lib/systemd/system/(paquetes)
Formato Básico
[Unit]
Description=Descripción del servicio
After=network.target
[Service]
Type=simple
ExecStart=/ruta/al/comando
Restart=always
[Install]
WantedBy=multi-user.target
Secciones Principales
[Unit]
[Unit]
Description=Mi Servicio Personalizado
Documentation=man:mon-service(1)
After=network.target sshd.service
Before=some-service.service
Requires=network.target
Wants=sshd.service
Conflicts=old-service.service
Directivas:
- Description: Descripción del servicio
- After: Inicia después de estas unidades
- Before: Inicia antes de estas unidades
- Requires: Dependencia fuerte (falla si la dependencia falla)
- Wants: Dependencia débil (continúa si la dependencia falla)
- Conflicts: No puede ejecutarse al mismo tiempo
[Service]
[Service]
Type=simple
ExecStart=/usr/local/bin/mon-script.sh
ExecStartPre=/bin/echo "Inicio"
ExecStartPost=/bin/echo "Iniciado"
ExecStop=/bin/echo "Detenido"
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10
User=monuser
Group=mongroup
WorkingDirectory=/var/lib/monservice
Environment="VAR1=valor1"
EnvironmentFile=/etc/monservice/env
StandardOutput=journal
StandardError=journal
Tipos:
- simple: Comando principal (por defecto)
- forking: Fork en segundo plano
- oneshot: Ejecución única
- notify: Notifica a systemd cuando está listo
Restart:
- no: No reinicia
- always: Siempre reiniciar
- on-failure: Reiniciar si falla
- on-success: Reiniciar si tiene éxito
[Install]
[Install]
WantedBy=multi-user.target
Alias=monservice.service
Targets comunes:
- multi-user.target: Modo multiusuario
- graphical.target: Modo gráfico
- default.target: Target por defecto
Ejemplos Prácticos
Servicio Simple
# /etc/systemd/system/mon-service.service
[Unit]
Description=Mi Servicio Simple
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mon-script.sh
Restart=always
RestartSec=10
User=www-data
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Activar:
sudo systemctl daemon-reload
sudo systemctl enable mon-service
sudo systemctl start mon-service
Servicio con Script
#!/bin/bash
# /usr/local/bin/mon-script.sh
# Script de servicio
# Función de limpieza
cleanup() {
echo "Deteniendo el servicio"
# Limpieza...
exit 0
}
# Trap signals
trap cleanup SIGTERM SIGINT
# Bucle principal
while true; do
# Trabajo...
echo "Servicio activo: $(date)"
sleep 60
done
Unit file:
[Unit]
Description=Servicio con Script
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mon-script.sh
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Servicio Forking
[Unit]
Description=Servicio Forking
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/daemon --daemonize
PIDFile=/var/run/daemon.pid
Restart=always
[Install]
WantedBy=multi-user.target
Servicio Oneshot
[Unit]
Description=Script Oneshot
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/init-script.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Variables de Entorno
En el Unit File
[Service]
Environment="VAR1=valor1"
Environment="VAR2=valor2"
EnvironmentFile=/etc/monservice/env
Archivo de Entorno
# /etc/monservice/env
VAR1=valor1
VAR2=valor2
VAR3="valor con espacios"
Gestión de Logs
Journal systemd
# Ver logs del servicio
sudo journalctl -u mon-service
# Seguir logs
sudo journalctl -u mon-service -f
# Logs recientes
sudo journalctl -u mon-service -n 50
# Desde fecha
sudo journalctl -u mon-service --since "2024-01-01"
Redirección
[Service]
# Al journal (por defecto)
StandardOutput=journal
StandardError=journal
# A archivo
StandardOutput=file:/var/log/monservice.log
StandardError=file:/var/log/monservice-error.log
# Ignorar
StandardOutput=null
StandardError=null
Buenas Prácticas
Estructura
[Unit]
# Descripción clara
# Dependencias apropiadas
[Service]
# Tipo correcto
# User/Group no-root si es posible
# Restart apropiado
# Logging configurado
[Install]
# Target apropiado
Seguridad
[Service]
# No usar root si es posible
User=serviceuser
Group=servicegroup
# Limitar capacidades
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
# Chroot si es posible
RootDirectory=/var/lib/monservice
Resumen
En este capítulo, usted ha aprendido:
Unit files: Estructura [Unit], [Service], [Install]
Tipos: simple, forking, oneshot, notify
Dependencias: After, Before, Requires, Wants
Restart: always, on-failure, never
Entorno: Environment, EnvironmentFile
Logs: journalctl, redirección a archivos
Práctica: Crear servicios para scripts y aplicaciones
Próximos Pasos
Capítulo 8.3: Cron Avanzado y systemd Timers
Módulo 9: Seguridad del Sistema
Capítulo creado el: Diciembre 2024