Aller au contenu
Administration Linux medium

systemctl : lister, démarrer et diagnostiquer les services Linux

34 min de lecture

systemctl est la commande centrale pour gérer les services sous Linux. Elle liste, démarre, arrête, recharge et diagnostique tout ce que systemd pilote sur un serveur moderne. Cette page couvre le cycle de vie d'un service, les deux façons de lister les services (celle qui manque à la plupart des lecteurs), la création d'une unité et le diagnostic de base d'un service qui refuse de tourner. Public visé : débutant qui découvre systemctl et administrateur qui veut arrêter de se faire piéger par un start trop optimiste.

Toutes les sorties reproduites ici proviennent d'un serveur Debian 13 avec systemd 257 et nginx installé. Les commandes sont identiques sur Ubuntu, Debian et RHEL ; seules quelques sorties d'enable diffèrent, et c'est signalé.

  • Lister les services avec list-units et list-unit-files, et comprendre pourquoi les deux listes ne se ressemblent pas
  • Piloter le cycle de vie : start, stop, restart, reload, status
  • Lire un statut ligne par ligne et interroger un service avec is-active, is-enabled, is-failed
  • Créer une unité de service personnalisée sans tomber dans le piège de Type=simple
  • Diagnostiquer un échec avec journalctl et le code 203/EXEC

Quatre-vingt-dix pour cent du travail sur les services tient dans cinq verbes. Chacun agit immédiatement, sur le système tel qu'il tourne en ce moment, et aucun ne survit à un redémarrage de la machine : l'activation au boot est une notion séparée. Toutes ces commandes modifient l'état du système, elles demandent donc les privilèges root via sudo, sauf status qui se contente de lire.

Fenêtre de terminal
sudo systemctl start nginx # démarrer maintenant
sudo systemctl stop nginx # arrêter maintenant
sudo systemctl restart nginx # arrêter puis redémarrer
sudo systemctl reload nginx # relire la configuration sans couper
systemctl status nginx # où en est-on ?

La bonne habitude consiste à enchaîner l'action et sa vérification dans la même ligne de commande. Le shell n'exécute la seconde partie que si la première a réussi, et is-active répond en un mot :

Fenêtre de terminal
systemctl start nginx && systemctl is-active nginx
active

Le suffixe .service est facultatif : systemctl start nginx et systemctl start nginx.service sont strictement équivalents. Il devient obligatoire dès qu'un timer ou un socket porte le même nom que le service, ce qui arrive souvent.

reload demande au service de relire sa configuration pendant qu'il continue de servir les requêtes en cours. restart tue le processus puis en lance un nouveau : les connexions en cours tombent. Sur un serveur web en production, la différence se voit dans les logs des clients.

Fenêtre de terminal
systemctl reload nginx && systemctl is-active nginx
active

systemctl status est la fiche d'identité d'un service : d'où vient son fichier de configuration, s'il tourne, depuis quand, avec quel PID, et les dernières lignes de son journal. C'est le premier réflexe devant un service suspect.

Fenêtre de terminal
systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-07-12 16:54:11 UTC; 31s ago
Invocation: 78240b0f696a4bc29a331a580ba0cdd5
Docs: man:nginx(8)
Process: 76 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 80 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 81 (nginx)
Tasks: 17 (limit: 8616)
Memory: 10.9M (peak: 11.7M)
CPU: 29ms
CGroup: /system.slice/nginx.service
├─81 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
├─82 "nginx: worker process"
├─83 "nginx: worker process"
(... un processus worker par cœur, 17 tâches au total ...)
Jul 12 16:54:11 srv01 systemd[1]: Starting nginx.service - A high performance web server and a reverse proxy server...
Jul 12 16:54:11 srv01 systemd[1]: Started nginx.service - A high performance web server and a reverse proxy server.

Chaque ligne répond à une question précise, et les trois premières suffisent le plus souvent :

LigneCe qu'elle vous dit
LoadedChemin du fichier unité utilisé, et si le service est activé au boot (enabled / disabled / masked)
ActiveÉtat courant et durée : active (running), inactive (dead), failed
ProcessLes commandes déjà terminées et leur code de sortie (status=0/SUCCESS ou une erreur)
Main PIDLe PID du processus principal ; s'il est absent, rien ne tourne
CGroupL'arborescence réelle des processus rattachés au service

La ligne Loaded est celle qu'on oublie de lire. Elle indique le chemin exact du fichier unité chargé, ce qui évite de passer dix minutes à éditer un fichier que systemd n'utilise pas.

Dans un script, un status complet est inexploitable : il faut une réponse courte et un code de retour fiable. Trois commandes le font, et elles s'utilisent aussi bien à la main que dans une automatisation Ansible ou un script de déploiement.

Fenêtre de terminal
systemctl is-active nginx # active | inactive | failed | activating
systemctl is-enabled nginx # enabled | disabled | static | masked
systemctl is-failed demo # failed si l'unité est en échec

Après avoir remis à zéro un service en échec avec reset-failed, is-failed répond par l'état courant :

Fenêtre de terminal
systemctl reset-failed demo && systemctl is-failed demo
inactive

Lister les services : list-units ou list-unit-files ?

Section intitulée « Lister les services : list-units ou list-unit-files ? »

C'est la question la plus posée sur systemctl, et la réponse est piégeuse : il existe deux listes de services, elles ne contiennent pas les mêmes choses, et la commande qu'on trouve partout (systemctl list-units) est justement celle qui cache une partie des services de la machine.

La distinction tient en une phrase : list-units liste les unités chargées en mémoire par systemd ; list-unit-files liste les fichiers d'unité installés sur le disque. Un service installé par un paquet mais jamais démarré existe bien sur le disque, mais systemd ne l'a pas chargé, donc il n'apparaît pas dans list-units. Sur le serveur de démonstration, l'écart est spectaculaire : 14 services chargés contre 119 fichiers d'unité installés.

systemctl list-units --type=service répond à la question « qu'est-ce que systemd manipule en ce moment ? ». C'est la vue runtime, celle qu'on veut quand on inspecte un serveur vivant.

Fenêtre de terminal
systemctl list-units --type=service
UNIT LOAD ACTIVE SUB DESCRIPTION
ldconfig.service loaded active exited Rebuild Dynamic Linker Cache
nginx.service loaded active running A high performance web server and a reverse proxy server
systemd-journal-catalog-update.service loaded active exited Rebuild Journal Catalog
systemd-journal-flush.service loaded active exited Flush Journal to Persistent Storage
systemd-journald.service loaded active running Journal Service
● systemd-modules-load.service loaded failed failed Load Kernel Modules
systemd-remount-fs.service loaded active exited Remount Root and Kernel File Systems
systemd-sysctl.service loaded active exited Apply Kernel Variables
systemd-sysusers.service loaded active exited Create System Users
systemd-tmpfiles-setup-dev-early.service loaded active exited Create Static Device Nodes in /dev gracefully
systemd-tmpfiles-setup-dev.service loaded active exited Create Static Device Nodes in /dev
systemd-tmpfiles-setup.service loaded active exited Create System Files and Directories
systemd-update-done.service loaded active exited Update is Completed
systemd-user-sessions.service loaded active exited Permit User Sessions
14 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

Trois colonnes portent l'information utile. LOAD dit si le fichier unité a été lu correctement, ACTIVE donne l'état général et SUB le détail : un service active (exited) a terminé sa tâche avec succès et ne laisse aucun processus derrière lui, ce qui est normal pour les tâches de démarrage. Le point noir en début de ligne signale les unités qui demandent votre attention, ici systemd-modules-load.service en failed.

Les deux dernières lignes de la sortie sont un mode d'emploi que systemd vous donne gratuitement : --all pour voir aussi les unités chargées mais inactives, list-unit-files pour voir tout ce qui est installé.

systemctl list-unit-files --type=service répond à la question « qu'est-ce qui est installé sur cette machine, et est-ce que ça démarrera au boot ? ». C'est la vue disque, celle qu'on veut pour un audit ou pour trouver un service qu'on n'a jamais démarré.

Fenêtre de terminal
systemctl list-unit-files --type=service
UNIT FILE STATE PRESET
apt-daily-upgrade.service static -
apt-daily.service static -
autovt@.service alias -
console-getty.service masked disabled
debug-shell.service disabled disabled
getty@.service enabled enabled
nginx.service enabled enabled
systemd-networkd.service disabled enabled
systemd-pstore.service enabled enabled
systemd-remount-fs.service enabled-runtime enabled
systemd-udevd.service masked enabled
x11-common.service masked enabled
119 unit files listed.

La sortie complète compte 119 lignes ; l'extrait ci-dessus montre un exemplaire de chaque état rencontré. La colonne STATE est le cœur de l'affaire : elle dit ce que systemd fera de ce service au prochain démarrage. La colonne PRESET indique ce que la distribution recommandait par défaut, ce qui permet de repérer d'un coup d'œil les services dont l'état a été modifié à la main.

STATECe que ça signifie
enabledDémarrera au boot : un lien symbolique existe dans un répertoire .wants
disabledNe démarrera pas au boot, mais reste démarrable à la main
staticAucune section [Install] : ne peut pas être activé, il est tiré par une dépendance
maskedLié vers /dev/null : impossible à démarrer, même manuellement
aliasAutre nom d'un service existant (kmod.service pointe vers un autre service)
enabled-runtimeActivé jusqu'au prochain reboot seulement, l'activation est en /run et non en /etc
indirectActivable, mais l'activation réelle passe par un autre service du même groupe
generatedFabriqué à la volée par un générateur, typiquement à partir d'un vieux script SysV

L'état static est celui qui surprend le plus. Un systemctl enable systemd-tmpfiles-clean.service échouera, non pas à cause d'une erreur de votre part, mais parce que ce service n'a pas vocation à être activé : il est déclenché par d'autres unités. La commande le confirme en un mot.

Fenêtre de terminal
systemctl is-enabled systemd-tmpfiles-clean.service
static

Lister les 119 unités d'un serveur n'a aucun intérêt opérationnel. Ce qu'on veut, c'est filtrer : quels services tournent, lesquels sont tombés, lesquels démarreront au prochain boot. Le filtre --state= s'applique aux deux commandes, avec des valeurs différentes puisqu'elles ne parlent pas de la même chose.

Les services qui tournent vraiment, processus vivant à l'appui :

Fenêtre de terminal
systemctl list-units --type=service --state=running
UNIT LOAD ACTIVE SUB DESCRIPTION
nginx.service loaded active running A high performance web server and a reverse proxy server
systemd-journald.service loaded active running Journal Service
2 loaded units listed.

Les services qui démarreront au prochain boot, la commande à connaître pour un audit de serveur :

Fenêtre de terminal
systemctl list-unit-files --type=service --state=enabled
UNIT FILE STATE PRESET
getty@.service enabled enabled
nginx.service enabled enabled
systemd-pstore.service enabled enabled
3 unit files listed.

Les services en échec, le premier réflexe quand on prend la main sur une machine dont on ne sait rien :

Fenêtre de terminal
systemctl list-units --state=failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● demo.service loaded failed failed Demo qui echoue
● systemd-modules-load.service loaded failed failed Load Kernel Modules
2 loaded units listed.

Deux options complètent la panoplie. --all ajoute les unités chargées mais inactives, ce qui fait passer la liste de 14 à 65 entrées sur la machine de démonstration : c'est là que réapparaissent les services arrêtés. --no-legend supprime l'en-tête et la légende, ce qui rend la sortie exploitable dans un script.

Fenêtre de terminal
systemctl list-units --type=service --no-legend | wc -l
14

Retenez la question que chaque commande pose vraiment. C'est le seul moyen de ne plus hésiter devant un serveur inconnu.

Vous voulez savoirCommandeAttention
Ce qui tourne en ce momentsystemctl list-units --type=service --state=runningNe montre pas les services installés mais jamais lancés
Tout ce que systemd a chargésystemctl list-units --type=serviceAjoutez --all pour inclure les unités inactives
Ce qui est installé sur la machinesystemctl list-unit-files --type=serviceLa liste la plus longue, c'est la vue disque
Ce qui démarrera au prochain bootsystemctl list-unit-files --type=service --state=enabledLa bonne commande pour un audit
Ce qui est tombésystemctl list-units --state=failedLe premier réflexe de diagnostic
Trouver un service par son nomsystemctl list-unit-files | grep dockerCherchez dans les unit files, pas dans les units chargées

Un service traverse plusieurs états au cours de sa vie, et systemctl status les affiche sur la ligne Active. Les connaître évite les faux diagnostics : un service active (exited) n'est pas cassé, il a simplement fini son travail.

ÉtatSignification
active (running)Le service tourne, un processus est vivant
active (exited)La tâche s'est terminée avec succès, aucun processus ne subsiste (Type=oneshot)
inactive (dead)Le service est arrêté, sans erreur
failedLe service a échoué, le journal contient la raison
activatingLe démarrage est en cours
deactivatingL'arrêt est en cours
maskedLe service est bloqué, un start refusera de faire quoi que ce soit

Cycle de vie des états d'un service systemd : active, inactive, failed, masked

C'est la confusion de départ de tout débutant, et elle produit des serveurs qui tournent parfaitement jusqu'au premier redémarrage. Les deux notions sont indépendantes : l'une parle du présent, l'autre du prochain boot.

ConceptQuestion poséeCommande
activeLe service tourne-t-il en ce moment ?systemctl is-active nginx
enabledDémarrera-t-il tout seul au prochain boot ?systemctl is-enabled nginx

Un service peut être enabled et inactive : il est arrêté maintenant, il repartira au reboot. Il peut être active et disabled : il tourne, mais il ne survivra pas au redémarrage. Ce dernier cas est le scénario classique du service installé un vendredi soir et disparu le lundi matin.

Commandes systemctl essentielles : contrôle runtime (start, stop, restart) et activation au boot (enable, disable)

Deux commandes suffisent au quotidien. enable crée le lien symbolique qui fera démarrer le service au boot, enable --now fait les deux d'un coup, et disable retire le lien.

Fenêtre de terminal
sudo systemctl enable nginx # au prochain boot
sudo systemctl enable --now nginx # au prochain boot ET maintenant
sudo systemctl disable nginx # ne démarrera plus au boot
systemctl is-enabled nginx # vérification

La sortie d'enable dépend de la distribution, et c'est déroutant la première fois. Sur RHEL, systemd affiche le lien symbolique créé. Sur Debian et Ubuntu, un paquet qui embarque encore un script SysV (c'est le cas de nginx) déclenche d'abord une synchronisation, et le message parle de SysV sans mentionner le moindre lien :

Synchronizing state of nginx.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable nginx

Le disable, lui, montre bien la suppression du lien, ce qui confirme la mécanique sous-jacente :

Removed '/etc/systemd/system/multi-user.target.wants/nginx.service'.

Dans tous les cas, la seule vérification qui compte est systemctl is-enabled nginx, qui doit répondre enabled. Ne vous fiez pas au message affiché, fiez-vous à l'état.

disable empêche le démarrage automatique, mais laisse la porte ouverte à un systemctl start manuel, y compris déclenché par une dépendance d'un autre service. mask ferme la porte : systemd crée un lien vers /dev/null, et plus rien ne peut lancer le service.

Fenêtre de terminal
sudo systemctl mask nginx
Created symlink '/etc/systemd/system/nginx.service' → '/dev/null'.

Toute tentative de démarrage échoue alors avec un message sans ambiguïté, et c'est exactement le comportement recherché pour un service qui ne doit jamais tourner sur un serveur, comme Bluetooth, Avahi ou CUPS :

Failed to start nginx.service: Unit nginx.service is masked.

Le retour en arrière se fait avec sudo systemctl unmask nginx, qui supprime le lien vers /dev/null et rend le service démarrable. Un systemctl is-enabled nginx confirme la sortie de l'état masked.

Faire tourner une application métier comme un service systemd apporte trois choses qu'un nohup ne donnera jamais : le redémarrage automatique en cas de crash, le démarrage au boot et les logs centralisés dans le journal. Le fichier d'unité vit dans /etc/systemd/system/ (le répertoire réservé à l'administrateur, prioritaire sur les unités livrées par les paquets).

Un fichier d'unité se lit en trois blocs, et chacun répond à une question différente : [Unit] décrit le service et ses dépendances, [Service] dit comment lancer le processus, [Install] dit quand l'activer au boot. Retenez le piège signalé en bas du schéma : sans section [Install], le service est static et systemctl enable n'aura aucun effet.

Structure d'un fichier .service : les sections Unit, Service et Install

  1. Créer le fichier d'unité avec l'éditeur intégré, qui gère le chemin et les droits pour vous :

    Fenêtre de terminal
    sudo systemctl edit --full --force mon-app.service
  2. Décrire le service, en nommant explicitement l'utilisateur non privilégié qui l'exécutera :

    [Unit]
    Description=API de facturation interne
    After=network-online.target postgresql.service
    Wants=network-online.target
    [Service]
    Type=exec
    User=appuser
    Group=appuser
    WorkingDirectory=/opt/mon-app
    ExecStart=/opt/mon-app/bin/api --config /etc/mon-app/api.toml
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    RestartSec=5s
    NoNewPrivileges=true
    [Install]
    WantedBy=multi-user.target
  3. Recharger systemd pour qu'il relise le fichier, puis démarrer :

    Fenêtre de terminal
    sudo systemctl daemon-reload
    sudo systemctl enable --now mon-app.service
  4. Vérifier réellement que le service tient debout, en laissant passer quelques secondes :

    Fenêtre de terminal
    sleep 3 && systemctl is-active mon-app.service

    La sortie doit afficher active. Si elle affiche failed, journalctl -xeu mon-app.service donne la raison.

Oublier daemon-reload après avoir modifié un fichier d'unité est l'erreur la plus fréquente : systemd continue d'utiliser la version qu'il a en mémoire, et vos changements semblent sans effet.

Un fichier d'unité se lit toujours de la même façon, ce qui rend n'importe quelle unité inconnue déchiffrable en trente secondes.

SectionRôle
[Unit]Description, dépendances (After=, Wants=, Requires=), ordre de démarrage
[Service]Le type, la commande, l'utilisateur, la politique de redémarrage
[Install]Ce qui se passe à l'enable : la cible qui tirera ce service au boot

Une unité sans section [Install] est justement une unité static : elle ne peut pas être activée, seulement tirée par une dépendance.

La directive Type= dit à systemd comment savoir que le service est démarré. C'est le réglage le plus mal compris de tout systemd, et le mauvais choix produit des diagnostics faux.

TypeComportementQuand l'utiliser
simpleLe processus lancé par ExecStart est le service ; systemd le considère démarré dès le forkLe défaut historique, à éviter au profit de exec
execComme simple, mais systemd attend que l'exec() réussisseLe bon défaut pour un binaire au premier plan (systemd 240 et plus)
forkingLe processus se détache, systemd suit le processus filsDaemons traditionnels avec un PIDFile=
oneshotExécute une commande puis se termineScripts de maintenance, tâches ponctuelles
notifyLe service prévient systemd qu'il est prêt via sd_notify()Applications compatibles, idéal pour l'ordre de démarrage
idleAttend que les autres jobs soient finisCas rares, affichage console

Le piège : Type=simple ne vérifie pas que votre binaire existe

Section intitulée « Le piège : Type=simple ne vérifie pas que votre binaire existe »

Voici le comportement que presque personne n'explique, et qui coûte des heures de débogage. Avec Type=simple, systemd considère le service démarré dès qu'il a forké, donc avant même d'avoir tenté d'exécuter le binaire. Résultat : systemctl start rend la main avec un code de retour 0, is-active répond active, et le service est déjà mort.

Deux unités identiques, un seul détail qui change, et deux comportements opposés. La première déclare Type=simple, la seconde Type=exec, et toutes deux pointent vers un binaire qui n'existe pas :

[Service]
Type=simple
ExecStart=/opt/demo/absent
Fenêtre de terminal
systemctl start t-simple; echo "code retour de start = $?"; systemctl is-active t-simple
code retour de start = 0
active

Le démarrage est un succès pour le shell, et le service se déclare actif. Avec Type=exec, systemd attend le résultat de l'exec() et refuse de mentir :

Fenêtre de terminal
systemctl start t-exec; echo "code retour de start = $?"; systemctl is-active t-exec
Job for t-exec.service failed because the control process exited with error code.
See "systemctl status t-exec.service" and "journalctl -xeu t-exec.service" for details.
code retour de start = 1
failed

La conséquence est très concrète. Un script de déploiement qui teste $? après un systemctl start se croit en succès alors que l'application est morte, et le pipeline passe au vert. Un systemctl status lancé une seconde trop tôt affiche un active (running) parfaitement mensonger, avec un Main PID entre doubles parenthèses qui trahit un processus qui n'a jamais réussi son exec() :

● demo.service - Demo qui echoue
Loaded: loaded (/etc/systemd/system/demo.service; disabled; preset: enabled)
Active: active (running) since Sun 2026-07-12 16:54:43 UTC; 11ms ago
Main PID: 551 ((app.py))

Un service qui meurt à trois heures du matin doit se relever tout seul. La directive Restart= gère ce cas, et les directives StartLimit* empêchent la boucle de redémarrage infinie qui masquerait un vrai problème.

DirectiveValeurEffet
Restarton-failureRedémarre si le code de sortie est non nul, ou après un signal ou un timeout
RestartalwaysRedémarre toujours, sauf après un systemctl stop explicite
RestartnoNe redémarre jamais (le défaut)
RestartSec5sAttend 5 secondes entre deux tentatives
StartLimitBurst3Au-delà de 3 tentatives dans la fenêtre, systemd abandonne
StartLimitIntervalSec60sLa fenêtre de comptage des tentatives

Restart=on-failure couplé à RestartSec=5s est le réglage par défaut raisonnable pour une application métier. Restart=always a un effet de bord vicieux : il relance aussi un service dont la configuration est cassée, ce qui remplit le journal et retarde le diagnostic.

Workflow de dépannage avec journalctl : status, logs, filtrage par erreurs, correction

Quand un service est en failed, la cause est presque toujours écrite noir sur blanc dans le journal. Encore faut-il la lire au bon endroit. Ce workflow en quatre temps résout la majorité des cas.

  1. Lire le statut, qui affiche déjà les dernières lignes de journal :

    Fenêtre de terminal
    systemctl status mon-app.service
  2. Ouvrir le journal complet de l'unité, avec les explications de systemd :

    Fenêtre de terminal
    journalctl -xeu mon-app.service

    L'option -x ajoute les explications contextuelles, -e saute à la fin, -u filtre sur l'unité.

  3. Repérer le code d'échec. Sur un service dont l'ExecStart= pointe vers un fichier absent, le journal est explicite :

    demo.service: Main process exited, code=exited, status=203/EXEC
    demo.service: Failed with result 'exit-code'.

    Le code 203/EXEC est de loin le plus fréquent : l'exécutable est introuvable, non exécutable, ou son chemin comporte une faute de frappe. Un ls -l sur le chemin de l'ExecStart= tranche en une seconde.

  4. Corriger, recharger, relancer, dans cet ordre :

    Fenêtre de terminal
    sudo systemctl daemon-reload
    sudo systemctl restart mon-app.service
    sleep 3 && systemctl is-active mon-app.service

Les codes d'échec les plus courants forment un vocabulaire à connaître par cœur : 203/EXEC pour un chemin invalide, 217/USER pour un User= qui n'existe pas, 200/CHDIR pour un WorkingDirectory= absent, 226/NAMESPACE pour une directive de durcissement trop stricte.

Un service accessible depuis le réseau ne devrait pas pouvoir lire /home, charger un module noyau ou obtenir de nouveaux privilèges. systemd fournit des directives de sandboxing qui s'ajoutent à la section [Service] sans modifier une ligne de l'application. Ces quatre-là couvrent déjà l'essentiel du risque et cassent rarement quoi que ce soit :

[Service]
NoNewPrivileges=true # interdit toute élévation de privilèges (suid)
ProtectSystem=strict # tout le système de fichiers en lecture seule
ReadWritePaths=/var/lib/mon-app
ProtectHome=true # /home, /root et /run/user invisibles
PrivateTmp=true # un /tmp isolé, invisible des autres services

La commande systemd-analyze security mon-app.service note le service de 0 à 10 (plus le score est bas, mieux c'est) et liste les protections manquantes une par une. C'est la façon la plus rapide de mesurer l'effet d'une directive : on note avant, on ajoute, on note après.

Les symptômes ci-dessous couvrent la quasi-totalité des appels au support sur un service systemd. La colonne de droite donne l'action, pas une piste.

SymptômeCause probableSolution
systemctl start réussit mais le service est mortType=simple ne vérifie pas l'exec()Passer en Type=exec, ou vérifier avec sleep 3 && systemctl is-active <service>
Service failed avec 203/EXECBinaire absent, chemin erroné ou non exécutablels -l sur le chemin de l'ExecStart=, puis chmod +x si besoin
Le service ne figure pas dans list-unitsIl est installé mais jamais chargésystemctl list-unit-files --type=service | grep <nom>
Modification du fichier d'unité sans effetsystemd utilise sa version en cachesudo systemctl daemon-reload puis restart
start répond Unit is maskedService masqué vers /dev/nullsudo systemctl unmask <service>
enable répond unit is staticAucune section [Install] dans l'unitéNormal : le service est tiré par une dépendance, pas par un enable
Le service tourne mais disparaît après rebootJamais activé au bootsudo systemctl enable <service> puis vérifier is-enabled
Permission denied dans le journalUser= sans droits sur les fichiersVérifier le propriétaire des fichiers et les directives de durcissement

Écrire une unité en lisant un guide et la faire tenir debout sur un système réel sont deux exercices distincts. Dans une VM jetable, vous rédigez un fichier .service complet, le chargez avec daemon-reload, l'activez avec enable --now et contrôlez son état réel avec is-active et le journal.

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • list-units liste ce qui est chargé en mémoire, list-unit-files ce qui est installé sur le disque. Un service installé mais jamais démarré n'apparaît pas dans list-units sans --all : 14 unités chargées contre 119 fichiers installés sur le serveur de démonstration.
  • Pour un audit, la bonne commande est systemctl list-unit-files --type=service --state=enabled : elle dit ce qui démarrera au prochain boot.
  • enabled et active sont indépendants : l'un parle du prochain boot, l'autre de maintenant.
  • Type=simple ment. Sur un binaire absent, systemctl start renvoie 0 et is-active répond active alors que le service est déjà mort en 203/EXEC. Déclarez Type=exec, ou vérifiez l'état quelques secondes après le démarrage.
  • 203/EXEC est le code d'échec le plus fréquent : chemin d'ExecStart= invalide ou fichier non exécutable.
  • Après toute modification d'un fichier d'unité, daemon-reload est obligatoire, sinon systemd garde sa version en cache.
  • reload relit la configuration sans couper les connexions, restart tue le processus : préférez reload quand l'unité déclare un ExecReload=.
  • mask est plus strict que disable : il rend le service impossible à démarrer, même par une dépendance.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn