Gérer les services
Objectif : manipuler les services et gérer le démarrage et l'arrêt d'un système Linux.
Au cours des précédents ateliers, nous avons eu l'occasion de parler des "services", ces logiciels qui tournent en tâche de fond pendant que l'utilisateur fait autre chose. C'est un peu comme un serveur (un vrai, en chair et en os) dans un café, discrètement à l'affût dans un coin, attendant que vous daigniez interrompre la lecture de votre journal pour commander un café et deux croissants.
Cet exemple est résolument utopique. Dans un café français qui se respecte, c'est le client qui est à l'affût du serveur.
Certains de ces services sont indispensables pour le fonctionnement cohérent du système et doivent être lancés au démarrage de la machine. D'autres sont facultatifs et dépendent de l'utilisation spécifique que vous faites de votre serveur. Le présent chapitre vous propose une introduction facile et pratique à la gestion des services sous Oracle Linux.
Qu'est-ce qu'un service ?
Pour avoir une idée de ce qu'est un service, nous n'avons qu'à en prendre un au hasard sur notre machine pour le regarder de près :
$ ps ax | grep -v grep | grep sshd
1016 ? Ss 0:00 /usr/sbin/sshd -D
1267 ? Ss 0:00 sshd: microlinux [priv]
1271 ? S 0:00 sshd: microlinux@pts/0
Le service OpenSSH (/usr/sbin/sshd
) attend en permanence des connexions
depuis des clients. Lorsqu'il reçoit une requête, il se charge d'établir une
connexion sécurisée après une authentification.
Un service connaît principalement deux états :
-
marche ;
-
arrêt.
C'est un peu comme le moteur d'une voiture. Soit il est démarré, soit il ne tourne pas. Après, savoir si vous le laissez tourner au point mort ou si vous embrayez, c'est une autre histoire...
Arrêter et (re)démarrer un service
Dans une voiture, je coupe le contact pour arrêter le moteur. Je peux faire pareil pour un service, après avoir acquis les droits d'administrateur :
$ sudo systemctl stop sshd
Vous serez peut-être vaguement surpris de ne pas avoir été déconnecté. Essayez de lancer une deuxième session à distance :
[microlinux@alphamule:~] $ ssh linuxbox
ssh: connect to host linuxbox port 22: Connection refused
Pour relancer le service, je dois invoquer la commande suivante :
$ sudo systemctl start sshd
Le serveur est à nouveau accessible depuis une machine distante :
[microlinux@alphamule:~] $ ssh linuxbox
microlinux@linuxbox's password:
Dans certaines situations, il est nécessaire de redémarrer un service, par exemple après avoir apporté des modifications à sa configuration, pour que celles-ci soient prises en compte :
$ sudo systemctl restart sshd
Le "redémarrage" n'est pas véritablement une fonctionnalité à part. Pour le système, il s'agit simplement d'une commande
stop
suivie d'une commandestart
.
Interdire les connexions SSH de l'utilisateur root
Dans la configuration par défaut d'Oracle Linux 7, le serveur OpenSSH
accepte les connexions distantes de l'utilisateur root
. Pour renforcer la
sécurité de leurs machines, certains administrateurs interdisent à root
de se
connecter directement.
Pour mettre en place cette politique, il faut éditer le fichier
/etc/ssh/sshd_config
. Repérez la directive PermitRootLogin
, décommentez la
ligne en supprimant le dièse #
initial et passez la directive à no
:
PermitRootLogin no
Redémarrez le service SSH pour prendre en compte les modifications :
$ sudo systemctl restart sshd
Recharger la configuration d'un service
Certains services – dont OpenSSH – sont capables de prendre en compte une nouvelle configuration sans pour autant passer par un redémarrage :
$ sudo systemctl reload sshd
La commande reload
offre une manière plus gracieuse de recharger la
configuration d'un service. Pour vous entraîner, reprenez l'exemple précédent
en bloquant et en autorisant successivement l'accès distant pour l'utilisateur
root
. Cette fois-ci, utilisez reload
au lieu de restart
.
Activer un service au démarrage de la machine
La commande systemctl
est un véritable couteau suisse qui gère
l'initialisation et les services de la machine. Jetez un coup d'oeil sur la
page de manuel systemctl(1)
; vous serez sans doute surpris par la
pléthore d'options existantes. Là comme ailleurs, nous n'allons pas nous
décourager face à l'abondance ; nous nous contentons de mettre un pied
devant l'autre.
Affichez les services installés et actifs. Notez en passant que vous avez le droit d'effectuer cette opération en tant que simple utilisateur :
$ systemctl list-units --type service
UNIT LOAD ACTIVE SUB DESCRIPTION
auditd.service loaded active running Security Auditing Service
chronyd.service loaded active running NTP client/server
crond.service loaded active running Command Scheduler
dbus.service loaded active running D-Bus System Message Bus
firewalld.service loaded active running firewalld - dynamic firewall daemon
...
Repérez le service OpenSSH dans la liste. Éventuellement, filtrez les résultats :
$ systemctl list-units --type service | grep sshd
sshd.service loaded active running OpenSSH server daemon
L'option list-unit-files
affiche l'ensemble des services installés,
indépendamment de leur état :
$ systemctl list-unit-files –-type service
UNIT FILE STATE
auditd.service enabled
autovt@.service enabled
blk-availability.service disabled
brandbot.service static
chrony-dnssrv@.service static
chrony-wait.service disabled
chronyd.service enabled
...
Là aussi, repérez sshd.service
dans la liste :
$ systemctl list-unit-files –-type service | grep sshd
sshd-keygen.service static
sshd.service enabled
sshd@.service static
Désactivez le service en utilisant l'option disable
. Vous vous doutez
probablement que ce genre d'opération requiert certains privilèges :
$ sudo systemctl disable sshd
Notez bien que le service n'est pas arrêté pour autant :
$ ps ax | grep -v grep | grep sshd
1267 ? Ss 0:00 sshd: microlinux [priv]
1271 ? S 0:00 sshd: microlinux@pts/0
1528 ? Ss 0:00 /usr/sbin/sshd -D
L'option status
est bien plus pratique pour afficher l'état d'un
service :
$ systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; ...)
Active: active (running) since Sat 2021-05-29 11:34:03 CEST; 9min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1020 (sshd)
CGroup: /system.slice/sshd.service
└─1020 /usr/sbin/sshd -D
Quelle est donc la portée de la directive disable
? Pour en avoir le
coeur net, redémarrez la machine et affichez l'ensemble des services :
$ systemctl list-units –-type service
$ systemctl list-unit-files –-type service
Repérez sshd.service
dans l'affichage des résultats des deux commandes, puis
vérifiez son état :
$ systemctl status sshd
En effet, la directive disable
n'a pas arrêté le service OpenSSH. Elle a juste
empêché son lancement au prochain démarrage.
Inversement, la directive enable
active le lancement du service au prochain
démarrage :
$ sudo systemctl enable sshd
Les cibles systemd
Les cibles systemd
(ou targets) représentent les différents modes
opératoires de notre système. Elles permettent de démarrer une machine avec
juste les services requis pour une tâche définie.
$ systemctl list-units --type target
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
...
multi-user.target loaded active active Multi-User System
...
network.target loaded active active Network
...
$ systemctl get-default
multi-user.target
La cible multi-user.target
représente ici l'état final de notre système au
démarrage. Les autres cibles comme basic.target
ou network.target
constituent autant d'étapes intermédiaires pour atteindre cet état final.
Dans la pratique quotidienne, nous aurons essentiellement affaire à deux cibles :
-
multi-user.target
-
graphical.target
Pour les opérations de dépannage, nous utiliserons les deux cibles suivantes :
-
rescue.target
-
emergency.target
La distinction entre
multi-user.target
etgraphical.target
a un sens sur les machines dotées d'un environnement graphique, comme les postes de travail ou les stations de travail. Sur les serveurs sans environnement graphique, on définiramulti-user.target
comme cible par défaut.
Démarrer en mode de secours
Les cibles rescue.target
et emergency.target
servent à dépanner un système
qui ne démarre pas normalement. En l'occurrence, le démarrage s'effectue avec
un nombre de services réduit et permet à l'administrateur root
d'ouvrir une
console pour chercher la cause de la panne.
-
Redémarrez la machine.
-
Lorsque l'écran du chargeur de démarrage GRUB s'affiche, appuyez sur la touche E (edit).
-
Naviguez dans les paramètres de démarrage avec les touches fléchées.
-
Repérez la ligne avec les paramètres du kernel. Elle commence par
linux16 /vmlinuz-3.10.0-quelquechose
et se termine par des options de démarrage commerhgb
etquiet
. -
Ajoutez l'option
systemd.unit=rescue.target
à la fin de cette ligne. Le clavier est en QWERTY américain par défaut, vous devrez donc tâtonner un peu. -
Démarrez en utilisant la combinaison de touches Ctrl+X.
-
Lorsque l'invite de commande vous affiche
Welcome to emergency mode
, fournissez le mot de passeroot
pour ouvrir une console.
En temps normal – c'est-à-dire en mode multi-user.target
– notre installation
minimale lance pas moins de trente-sept services. Voyons comment les choses se
présentent maintenant :
# systemctl list-units --type service
...
19 loaded units listed.
Nous constatons que le mode de secours n'affiche plus que dix-neuf services actifs, soit près de la moitié du mode normal. Si cela ne vous semble pas si minimal que ça, sachez que nous pouvons faire mieux.
Réitérez l'expérience précédente en éditant les paramètres de démarrage de
GRUB, mais en remplaçant rescue.target
par emergency.target
.
L'invite de commande Welcome to emergency mode
reste la même et vous devez
fournir le mot de passe root
comme vous l'avez fait auparavant pour ouvrir
une console. C'est le nombre de services chargés qui fait la différence :
# systemctl list-units --type service
...
2 loaded units listed.
Cette fois-ci, nous sommes bien passés en mode "minimum syndical". Rien ne
tourne sur notre machine en dehors du shell de secours (emergency.service
)
et des fichiers journaux (systemd-journald.service
) du système.
Changer de cible à la volée
Admettons que nous souhaitions basculer du mode de fonctionnement normal
multi-user.target
vers le mode de secours rescue.target
. Nous pouvons le
faire directement, sans passer par un redémarrage et la modification des
options du kernel dans GRUB :
$ sudo systemctl isolate rescue.target
Le système fait mine de redémarrer, mais au bout de quelques secondes, vous vous retrouvez confronté à l'invite du mode de secours :
Welcome to emergency mode!
Une fois que vous vous êtes connecté à la console de secours, procédez à l'inverse pour basculer directement vers le mode de fonctionnement normal :
# systemctl isolate multi-user.target
Afficher l'état du système
Est-ce qu'il y a moyen de savoir si tout s'est bien passé ? Est-ce que
tous les services ont été lancés comme prévu ? C'est la directive status
qui nous le dira.
$ systemctl status
● linuxbox.microlinux.lan
State: running
Jobs: 0 queued
Failed: 0 units
...
À quoi ressemblerait un échec au démarrage ? Je vais utiliser une astuce pour vous en faire une simulation.
-
Redémarrez la machine.
-
Éditez les options de GRUB et démarrez avec le paramètre
systemd.unit=emergency.target
. -
Connectez-vous à la console de secours minimale.
-
Basculez directement vers le mode de fonctionnement normal avec
systemctl isolate multi-user.target
.
Une fois que j'ai effectué cette manipulation, j'affiche l'état de mon système :
$ systemctl status
● linuxbox.microlinux.lan
State: degraded
Jobs: 0 queued
Failed: 1 units
...
Le statut degraded
apparaît en rouge et me suggère qu'il y a eu un problème
quelque part... mais où ? C'est l'option --failed
qui me le dira :
$ systemctl --failed
UNIT LOAD ACTIVE SUB ...
● systemd-vconsole-setup.service loaded failed failed ...
Je tente de démarrer manuellement ce service :
$ sudo systemctl start systemd-vconsole-setup
J'affiche à nouveau l'état du système :
$ systemctl status
● linuxbox.microlinux.lan
State: running
Jobs: 0 queued
Failed: 0 units
...
Apparemment, tout est rentré dans l'ordre.
Définir la cible par défaut
En temps normal – c'est-à-dire si nous ne modifions pas les paramètres de
démarrage de GRUB – notre système démarre en mode multi-user.target
:
$ systemctl get-default
multi-user.target
Je peux modifier la cible par défaut :
$ sudo systemctl set-default rescue.target
Au prochain redémarrage, le système m'affichera directement l'invite du mode de secours :
Welcome to emergency mode!
Le mode de secours rescue.target
correspond désormais au mode de fonctionnement
"normal" de ma machine :
# systemctl get-default
rescue.target
Pour redéfinir la cible multi-user.target
comme mode de fonctionnement par
défaut, je dois invoquer la commande suivante :
# systemctl set-default multi-user.target
Basculer entre les cibles sur un poste de travail
Dans la pratique quotidienne, on utilisera systemctl set-default
et
systemctl isolate
principalement sur les postes de travail ou les stations de
travail pour basculer entre le mode graphique (graphical.target
) et le mode
texte (multi-user.target
).
Lorsque je dois changer une carte graphique dans un poste client, je commence par basculer vers le mode texte :
$ sudo systemctl set-default multi-user.target
$ sudo systemctl isolate multi-user.target
Une fois que j'ai apporté les modifications nécessaires à mon système, je teste d'abord si l'affichage graphique fonctionne correctement :
$ sudo systemctl isolate graphical.target
Si tout se passe comme prévu, je redéfinis le mode graphique par défaut :
$ sudo systemctl set-default graphical.target
Dans ce contexte, le mode multi-user.target
est considéré comme une sorte de
mode de secours qui me permet de manipuler mon poste de travail sans affichage
graphique.
Éteindre et redémarrer la machine
Tout comme pour le démarrage, le système doit suivre une certaine procédure
pour arrêter tous les services. L'extinction du système nécessite de tuer les
processus dans un ordre cohérent et de faire le ménage dans les systèmes de
fichiers avant l'arrêt des disques. C'est la commande halt
qui s'en
charge :
$ sudo halt -p
L'option -p
(poweroff) se charge d'éteindre la machine lors de l'arrêt du
système. Consultez la page de manuel halt(8)
pour en savoir plus.
La commande reboot
a le même effet que halt
, au détail près que la machine
redémarre au lieu de s'éteindre :
$ sudo reboot
Alternativement, nous pouvons invoquer systemctl
avec les options respectives
poweroff
et reboot
pour arrêter et redémarrer le système :
$ sudo systemctl poweroff
Lorsque je suis directement connecté à ma console, je peux également utiliser la combinaison de touches Ctrl+Alt+Del pour redémarrer.
Les utilisateurs de systèmes Microsoft Windows seront probablement bien familiarisés avec la combinaison de touches Ctrl+Alt+Del, qui sert à afficher un mot de leur sponsor en cas de plantage d'une application. Sachez que, sous Linux, il s'agit là du raccourci clavier normal pour redémarrer une machine en mode console.
Un peu de contexte historique
Les lecteurs de mon ouvrage Débuter avec Linux paru en 2017 et basé sur Slackware Linux ont eu l'occasion de découvrir le système d'initialisation BSD. Ce système "brut de décoffrage" reste fidèle à la philosophie Unix aussi bien qu'au principe KISS (Keep It Simple Stupid) et se base sur une série de scripts shell pour gérer les services et les niveaux d'exécution.
Red Hat Enterprise Linux, Oracle Linux et Debian ont longtemps utilisé la
procédure System V, avec des niveaux d'exécution organisés différemment.
D'autres systèmes d'initialisation ont vu le jour petit à petit, comme Upstart,
développé par Canonical et adopté pendant quelque temps par Ubuntu et Fedora,
ou encore OpenRC, utilisé par Gentoo depuis ses débuts. Actuellement,
l'écrasante majorité des distributions a décidé d'adopter systemd
, une
alternative à System V spécifiquement conçue pour le noyau Linux.
L'adoption de systemd
a suscité une série de controverses sans précédent dans
le monde du libre. En résumé, les objections ne portent pas tant sur ses
mérites en tant que système d'initialisation, mais sur le fait qu'il s'est
imposé de force au détriment des solutions alternatives en s'étendant de façon
tentaculaire dans des domaines qui n'ont plus rien à voir avec l'initialisation
à proprement parler, sans oublier qu'il casse volontairement la compatibilité
Posix avec les systèmes non-Linux comme la famille des BSD.
Quoi qu'il en soit, systemd
a bel et bien gagné la bataille et s'est
progressivement imposé un peu partout. En dépit de son côté "usine à gaz", il
constitue une solution robuste qui offre quelques fonctionnalités fort
pratiques pour les administrateurs système, sans oublier le mérite d'abolir les
différences inutiles entre les distributions Linux.
La rédaction de ces cours demande du temps et des quantités significatives de café espresso. Vous appréciez cette formation ? Offrez un café au formateur en cliquant sur la tasse.