| name | sysadmin-systemd |
| description | Administration complète de systemd : unités (service, timer, socket, path, mount), targets, dépendances, journald, hardening de services, drop-ins et débogage. |
| version | 1.0.0 |
| author | EVA |
| license | Privée EVA St-Étienne |
| platforms | ["linux"] |
| metadata | {"EVA":{"tags":["systemd","services","timers","journald","init","units","sockets","targets","cgroups","boot"],"related_skills":["os-linux-admin","sysadmin-logging","sysadmin-monitoring"]}} |
Administration Systemd Complète
Vue d'ensemble
systemd est le système d'init et le gestionnaire de services du noyau Linux moderne, adopté par toutes les distributions majeures. Il gère le démarrage, l'arrêt, la supervision, l'isolation et la journalisation des processus système.
Concepts Fondamentaux :
- Unit : ressource gérée par systemd (service, timer, socket, path, mount, target)
- Target : groupe d'unités → remplace les runlevels SysV
- Journald : service de journalisation binaire centralisée
- CGroup : isolation des processus par groupe de contrôle
Quand l'utiliser
- Créer un service personnalisé pour une application ou un script
- Planifier des tâches récurrentes avec des timers (alternative moderne à cron)
- Activer un service au démarrage d'un événement (socket, path, device)
- Diagnostiquer un démarrage lent, un service qui refuse de s'arrêter
- Durcir un service avec les options de sandboxing (PrivateTmp, ProtectHome, etc.)
Types d'Unités
| Type | Extension | Rôle |
|---|
| Service | .service | Processus démon (le plus courant) |
| Timer | .timer | Planification temporelle (remplace cron) |
| Socket | .socket | Activation sur connexion (listen) |
| Path | .path | Activation sur changement fichier |
| Mount | .mount | Point de montage systemd |
| Automount | .automount | Montage à la demande |
| Target | .target | Groupe d'unités (multi-user.target = runlevel 3) |
Commandes Quotidiennes
Gestion des Services
sudo systemctl start nginx.service
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx
sudo systemctl enable nginx
sudo systemctl disable nginx
sudo systemctl enable --now nginx
systemctl status nginx
systemctl is-active nginx
systemctl is-enabled nginx
systemctl is-failed nginx
systemctl list-units --type=service --state=running
systemctl list-units --type=timer --all
Gestion des Timers
systemctl list-timers --all
sudo systemctl start backup-daily.timer
sudo systemctl disable --now backup-daily.timer
Journald (Consultation des Logs)
journalctl -u nginx.service
journalctl -u nginx -f
journalctl -u nginx --since today
journalctl -u nginx -p err
journalctl -b
journalctl _PID=1234
journalctl -k
sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=500M
Structure d'une Unité Service
[Unit]
Description=Mon service personnalisé
Documentation=https://docs.example.com
After=network.target postgresql.service
Requires=postgresql.service # démarre avec, échoue si manquant
Wants=postgresql.service # démarre avec, tolérant
[Service]
Type=simple # défaut, le processus principal
ExecStart=/usr/local/bin/monservice --config /etc/monservice/config.yaml
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
Restart=on-failure
RestartSec=5
User=monservice
Group=monservice
WorkingDirectory=/opt/monservice
EnvironmentFile=-/etc/monservice/env # le - ignore si fichier absent
StandardOutput=journal
StandardError=journal
# Durcissement (sandboxing)
PrivateTmp=true
ProtectHome=true
ProtectSystem=full
NoNewPrivileges=true
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ReadWritePaths=/var/lib/monservice
[Install]
WantedBy=multi-user.target
Types de Services
| Type | Comportement |
|---|
simple | Processus principal = ExecStart, ne fork pas |
forking | Processus principal fork, le parent exit (démons classiques) |
oneshot | S'exécute une fois, attend la fin (pour timers) |
notify | Le processus envoie sd_notify(READY=1) via libsystemd |
dbus | S'enregistre sur le bus D-Bus, systemd attend le nom |
idle | Démarre après que tous les jobs soient soumis |
Exemple Complet : Service + Timer
1. Script à exécuter
#!/bin/bash
set -euo pipefail
/usr/bin/pg_dump mydb | gzip > /var/backups/mydb-$(date +\%Y\%m\%d).sql.gz
2. Service (oneshot car le script se termine)
[Unit]
Description=Sauvegarde quotidienne de la base
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-db.sh
User=postgres
Group=postgres
3. Timer (planification)
[Unit]
Description=Minuterie sauvegarde base
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
RandomizedDelaySec=60
[Install]
WantedBy=timers.target
4. Activation
sudo systemctl daemon-reload
sudo systemctl enable --now backup-db.timer
systemctl list-timers backup-db.timer
Drop-in (Override) — Ne JAMAIS modifier les unités système
Pour surcharger une option d'une unité existante :
sudo systemctl edit nginx.service
sudo mkdir -p /etc/systemd/system/nginx.service.d/
sudo tee /etc/systemd/system/nginx.service.d/override.conf << 'EOF'
[Service]
Restart=always
RestartSec=10
LimitNOFILE=65536
EOF
sudo systemctl daemon-reload
sudo systemctl restart nginx
Les drop-ins sont prioritaires sur l'unité d'origine et survivent aux mises à jour du paquet.
Durcissement (Hardening) de Service
systemd offre des options de sandboxing pour limiter la surface d'attaque :
[Service]
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/app
PrivateNetwork=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
NoNewPrivileges=true
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
SystemCallFilter=@system-service
SystemCallArchitectures=native
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
MemoryMax=512M
TasksMax=100
Vérifier le niveau de durcissement :
systemd-analyze security nginx.service
Activation par Socket et Path
Socket Activation (ex: service qui écoute sur une socket UNIX)
[Socket]
ListenStream=/var/run/myapp.sock
SocketUser=myapp
SocketGroup=myapp
SocketMode=0660
[Install]
WantedBy=sockets.target
[Service]
ExecStart=/usr/bin/myapp
Le service est démarré automatiquement quand une connexion arrive sur la socket.
Path Activation (ex: traitement dès qu'un fichier apparaît)
[Path]
PathModified=/var/spool/incoming/
Unit=processor.service
[Install]
WantedBy=multi-user.target
Débogage (Troubleshooting)
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain
systemd-analyze verify /etc/systemd/system/monservice.service
systemctl list-dependencies nginx.service
sudo systemctl daemon-reload
sudo systemctl mask nginx.service
sudo systemctl unmask nginx.service
sudo systemctl kill -s SIGKILL nginx.service
Pièges Courants
-
Oublier systemctl daemon-reload après avoir modifié une unité.
-
Type=simple avec un script qui fork : Si votre script lance un processus fils et exit, systemd pense que le service s'est arrêté. Utiliser Type=forking ou Type=notify.
-
Timer OnCalendar mal formaté : Vérifier avec systemd-analyze calendar "*-*-* 02:00:00". Les expressions cron ne sont pas compatibles — utiliser OnCalendar=.
-
StandardOutput=journal : Les logs passent par journald, pas par un fichier. Si un logiciel écrit dans /var/log/ ET dans stdout, les logs sont dupliqués.
-
Limites par défaut : LimitNOFILE=1024 pour les services. Les bases de données et serveurs web nécessitent LimitNOFILE=65536.
Liste de vérification (Checklist)