Product SiteDocumentation Site

Chapitre 9. Services Unix

9.1. Démarrage du système
9.1.1. Le système d'initialisation systemd
9.1.2. Le système d'initialisation System V
9.2. Connexion à distance
9.2.1. Connexion à distance sécurisée : SSH
9.2.2. Accéder à distance à des bureaux graphiques
9.3. Gestion des droits
9.3.1. Owners and Permissions
9.3.2. ACLs - Access Control Lists
9.4. Interfaces d'administration
9.4.1. Administrer sur interface web : webmin
9.4.2. Configuration des paquets : debconf
9.5. Les événements système de syslog
9.5.1. Principe et fonctionnement
9.5.2. Le fichier de configuration
9.6. Le super-serveur inetd
9.7. Planification de tâches : cron et atd
9.7.1. Format d'un fichier crontab
9.7.2. Emploi de la commande at
9.8. Planification asynchrone : anacron
9.9. Les quotas
9.10. Sauvegarde
9.10.1. Sauvegarde avec rsync
9.10.2. Restauration des machines non sauvegardées
9.11. Branchements « à chaud » : hotplug
9.11.1. Introduction
9.11.2. La problématique du nommage
9.11.3. Fonctionnement de udev
9.11.4. Cas pratique
9.12. Gestion de l'énergie : Advanced Configuration and Power Interface (ACPI)
Ce chapitre parcourt un ensemble de services fondamentaux, souvent communs à beaucoup d'Unix. Tout administrateur se doit de les connaître.

9.1. Démarrage du système

Lorsque l'ordinateur démarre, les messages défilant sur la console révèlent de nombreuses initialisations et configurations automatiques. Parfois, il est souhaitable de modifier légèrement le déroulement de cette étape, ce qui implique de bien la comprendre. C'est l'objet de cette section.
On systems with a BIOS, first, the BIOS takes control of the computer, initializes the controllers and hardware, detects the disks, and bridges everything together. Then it looks up the Master Boot Record (MBR) of the first disk in the boot order and loads the code stored there (first stage). This code then launches the second stage and finally executes the bootloader.
In contrast to the BIOS, UEFI is more sophisticated, it knows filesystems and can read the partition tables. The interface searches the system storage for a partition labeled with a specific globally unique identifier (GUID) that marks it as the EFI System Partition (ESP), where the bootloaders, boot managers, UEFI shell, etc., are located, and launches the desired bootloader. If Secure Boot is enabled, the boot process will verify authenticity of the EFI binaries there by signature (thus grub-efi-arch-signed is required in this case). The UEFI specification also defines support for booting in legacy BIOS mode. This is called the Compatibility Support Module (CSM). If CSM is enabled, it will attempt to boot from a drive's MBR. However, many new systems do no longer support the CSM mode.
In both cases then the actual bootloader takes over, finds either a chained bootloader or the kernel on the disk, loads, and executes it. The kernel is then initialized, and starts to search for and mount the partition containing the root filesystem, and finally executes the first program — init. Frequently, this “root partition” and this init are, in fact, located in a virtual filesystem that only exists in RAM (hence its name, “initramfs”, formerly called “initrd” for “initialization RAM disk”). This filesystem is loaded in memory by the bootloader, often from a file on a hard drive or from the network. It contains the bare minimum required by the kernel to load the “true” root filesystem: this may be driver modules for the hard drive, or other devices without which the system cannot boot, or, more frequently, initialization scripts and modules for assembling RAID arrays, opening encrypted partitions, activating LVM volumes, etc. Once the root partition is mounted, the initramfs hands over control to the real init, and the machine goes back to the standard boot process.

9.1.1. Le système d'initialisation systemd

Le « vrai init » est actuellement fourni par systemd, sur lequel cette section se focalise.
Étapes du démarrage d'un ordinateur sous Linux avec systemd

Figure 9.1. Étapes du démarrage d'un ordinateur sous Linux avec systemd

Systemd executes several processes, in charge of setting up the system: keyboard, drivers, filesystems, network, services. It does this while keeping a global view of the system as a whole, and the requirements of the components. Each component is described by a “unit file” (sometimes more); the general syntax is derived from the widely-used “*.ini files“ syntax, with key = value pairs grouped between [section] headers. Unit files are stored under /lib/systemd/system/ and /etc/systemd/system/; they come in several flavors, but we will focus on “services” and “targets” here.
A systemd “.service file” describes a process managed by systemd. It contains roughly the same information as old-style init-scripts, but expressed in a declaratory (and much more concise) way. Systemd handles the bulk of the repetitive tasks (starting and stopping the process, checking its status, logging, dropping privileges, and so on), and the service file only needs to fill in the specifics of the process. For instance, here is the service file for SSH:
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=sshd.service
The [Unit] section contains generic information about the service, like its description and manual page resources, as well as relations (dependency and order) to other services. The [Service] part contains the declarations related to the service execution (starting, stopping, killing, restarting), directories and configuration file(s) used. The last section, [Install], again carries generic information into which targets to install the service and, in this case, the alias that can be used instead of the service name. As you can see, there is very little code in there, only declarations. Systemd takes care of displaying progress reports, keeping track of the processes, and even restarting them when needed. The syntax of these files is fully described in several manual pages (e.g. systemd.service(5), systemd.unit(5), systemd.exec(5), etc.).
A systemd “.target file” describes a state of the system where a set of services are known to be operational. It can be thought of as an equivalent of the old-style runlevel. One of the pre-defined targets is local-fs.target; when it is reached, the rest of the system can assume that all local filesystems are mounted and accessible. Other targets include network-online.target and sound.target (for a full list of special targets see systemd.special(7)). The dependencies of a target can be listed either within the target file (in the Requires= line), or using a symbolic link to a service file in the /lib/systemd/system/targetname.target.wants/ directory. For instance, /etc/systemd/system/printer.target.wants/ contains a link to /lib/systemd/system/cups.service; systemd will therefore ensure CUPS is running in order to reach printer.target.
Puisque les fichiers de systemd ne sont pas des scripts ou des programmes, ils ne peuvent être exécutés directement : ils doivent être interprétés par systemd. C'est pourquoi l'administrateur dispose de plusieurs utilitaires pour interagir avec systemd, et contrôler l'état du système et de chacun de ses composants.
Le premier de ces outils est systemctl. Lorsqu'il est exécuté sans paramètres, il liste toutes les « unités » connues de systemd (à l'exception de celles qui ont été désactivées), ainsi que leur état. systemctl status donne une meilleure vue des services, et des processus associés. En lui passant un nom de service (comme dans systemctl status ntp.service), il renvoie encore plus de détails, ainsi que les dernières lignes de log en rapport avec le service (nous reviendrons là dessus plus loin).
Démarrer un service manuellement se fait simplement avec systemctl start nom-de-service.service. Inversement et sans surprise, arrêter un service se fait avec systemctl stop nom-de-service.service ; d'autres sous-commandes existent, comme reload (« recharger ») et restart (« redémarrer »).
Pour activer un service (autrement dit pour qu'il soit lancé automatiquement au démarrage de l'ordinateur), il convient de faire systemctl enable nom-du-service.service (ou disable pour le désactiver). La sous-commande is-enabled permet de vérifier l'état d'activation du service.
An interesting feature of systemd is that it includes a logging component named journald. It comes as a complement to more traditional logging systems such as syslogd, but it adds interesting features such as a formal link between a service and the messages it generates, and the ability to capture error messages generated by its initialization sequence. The messages can be displayed later on, with a little help from the journalctl command. Without any arguments, it simply spews all log messages that occurred since system boot; it will rarely be used in such a manner. Most of the time, it will be used with a service identifier:
# journalctl -u ssh.service
-- Logs begin at mar. 2015-03-31 10:08:49 CEST, end at mar. 2015-03-31 17:06:02 CEST. --
Mar 31 10:08:55 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.
Mar 31 10:08:55 mirtuel sshd[430]: Server listening on :: port 22.
Mar 31 10:09:00 mirtuel sshd[430]: Received SIGHUP; restarting.
Mar 31 10:09:00 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.
Mar 31 10:09:00 mirtuel sshd[430]: Server listening on :: port 22.
Mar 31 10:09:32 mirtuel sshd[1151]: Accepted password for roland from 192.168.1.129 port 53394 ssh2
Mar 31 10:09:32 mirtuel sshd[1151]: pam_unix(sshd:session): session opened for user roland by (uid=0)
Une autre option très utile est -f, qui demande à journalctl d'afficher les nouveaux messages au fur et à mesure de leur émission (de manière similaire à ce que réalise tail -f fichier).
Lorsqu'un service n'a pas l'air de fonctionner correctement, la première étape pour résoudre le problème est de vérifier si le service est lancé avec systemctl status ; si ce n'est pas le cas, et si les messages affichés par cette première commande ne suffisent pas à identifier le problème, il convient alors de consulter les messages que journald a collecté au sujet de ce service. Prenons le cas d'un serveur SSH qui ne fonctionne pas :
# systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
   Active: failed (Result: start-limit) since mar. 2015-03-31 17:30:36 CEST; 1s ago
  Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
  Process: 1188 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=255)
 Main PID: 1188 (code=exited, status=255)

Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.
Mar 31 17:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
# journalctl -u ssh.service
-- Logs begin at mar. 2015-03-31 17:29:27 CEST, end at mar. 2015-03-31 17:30:36 CEST. --
Mar 31 17:29:27 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.
Mar 31 17:29:27 mirtuel sshd[424]: Server listening on :: port 22.
Mar 31 17:29:29 mirtuel sshd[424]: Received SIGHUP; restarting.
Mar 31 17:29:29 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.
Mar 31 17:29:29 mirtuel sshd[424]: Server listening on :: port 22.
Mar 31 17:30:10 mirtuel sshd[1147]: Accepted password for roland from 192.168.1.129 port 38742 ssh2
Mar 31 17:30:10 mirtuel sshd[1147]: pam_unix(sshd:session): session opened for user roland by (uid=0)
Mar 31 17:30:35 mirtuel sshd[1180]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:35 mirtuel sshd[1182]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:35 mirtuel sshd[1184]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel sshd[1186]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel sshd[1188]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.
Mar 31 17:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
# vi /etc/ssh/sshd_config
# systemctl start ssh.service
# systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
   Active: active (running) since mar. 2015-03-31 17:31:09 CEST; 2s ago
  Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 1222 (sshd)
   CGroup: /system.slice/ssh.service
           └─1222 /usr/sbin/sshd -D
# 
Après avoir vérifié l'état du service (failed, en échec), nous avons consulté les messages du journal ; ils indiquaient une erreur dans le fichier de configuration. Après avoir corrigé ce dernier, nous avons redémarré le service et nous avons vérifié qu'il fonctionnait pour de bon.

9.1.2. Le système d'initialisation System V

The System V init system (which we'll call init for brevity) executes several processes, following instructions from the /etc/inittab file. The first program that is executed (which corresponds to the sysinit step) is /etc/init.d/rcS, a script that executes all of the programs in the /etc/rcS.d/ directory.
Parmi ceux-ci, on trouve successivement :
  • la configuration du clavier de la console ;
  • le chargement des pilotes : la plupart des modules noyau sont chargés par le noyau lui-même en fonction du matériel détecté ; certains pilotes peuvent ensuite être systématiquement chargés, les modules correspondants doivent être listés dans /etc/modules ;
  • la vérification de l'intégrité des systèmes de fichiers ;
  • le montage des partitions locales ;
  • la configuration du réseau ;
  • le montage des systèmes de fichiers distants (NFS).
Après cette phase, init reprend la main et démarre les programmes associés au niveau d'exécution (runlevel) normal, soit par défaut le niveau 2. Il exécute /etc/init.d/rc 2, script qui démarre tous les services donnés du répertoire /etc/rc2.d/ débutant par la lettre « S ». Le nombre (à deux chiffres) qui suit servait historiquement à classer les services pour les démarrer dans le bon ordre, mais de nos jours le système de démarrage par défaut utilise insserv, un système de démarrage où l'ordonnancement se fait en fonction des dépendances entre scripts. Chaque script de démarrage déclare ainsi les contraintes qui s'appliquent à lui (par exemple, s'il doit démarrer avant ou après tel autre service) ; init les lance alors dans un ordre qui satisfait les contraintes. La numérotation statique des scripts n'est donc plus prise en compte (mais ils doivent toujours s'appeler d'un nom composé d'un « S » suivi de deux caractères, suivis à leur tour du véritable nom du script utilisé pour les dépendances). D'une manière générale, les services de base (comme le service de collecte des journaux, rsyslog, ou celui d'attribution des ports, portmap) sont démarrés en premier, suivis par les services standards et l'interface graphique (gdm3).
Ce système de démarrage par dépendances permet d'automatiser des renumérotations qui pourraient s'avérer fastidieuses si elles devaient être faites manuellement et il prévient les erreurs humaines, puisque l'ordonnancement se fait en fonction des contraintes exprimées. Il présente également l'avantage supplémentaire de permettre le démarrage de plusieurs services en parallèle, si plusieurs scripts sont indépendants entre eux, ce qui peut accélérer la séquence de démarrage.
init distingue plusieurs niveaux d'exécution car il peut basculer de l'un à l'autre par la commande telinit nouveau-niveau. Dès son invocation, init exécute à nouveau /etc/init.d/rc avec le nouveau niveau d'exécution désiré, script qui démarre à son tour les services manquants et arrête ceux qui ne sont plus souhaités. Pour cela, il se réfère au contenu du répertoire /etc/rcX.d (où X représente le nouveau niveau d'exécution). Les scripts débutant par « S » (comme Start) sont des services à démarrer, ceux débutant par « K » (comme Kill) sont des services à stopper. Le script évite de redémarrer tout service déjà actif dans le niveau d'exécution précédent.
Dans Debian, le système d'initialisation System V n'utilise par défaut que quatre runlevels différents|:
  • Le niveau 0 n'est utilisé que de manière transitoire, lors de la phase d'extinction de l'ordinateur. Il contient donc de nombreux scripts « K ».
  • Le niveau 1, aussi connu sous le nom de single-user, correspond au système en mode dégradé ; il ne contient que les services de base et est prévu pour les opérations de maintenance en dehors de l'interaction des utilisateurs.
  • Le niveau 2 est le niveau de fonctionnement normal, qui inclut les services réseau, l'interface graphique, les connexions des utilisateurs, etc.
  • Le niveau 6 est similaire au niveau 0, à ceci près qu'il est utilisé lors de la phase d'extinction qui précède un redémarrage.
D'autres niveaux existent, notamment de 3 à 5. Ils sont par défaut configurés pour fonctionner de la même manière que le niveau 2, mais l'administrateur peut les modifier (en ajoutant ou supprimant des scripts dans les répertoires /etc/rcX.d/ correspondants) pour les adapter à un besoin particulier.
Étapes du démarrage d'un ordinateur sous Linux avec le système d'initialisation System V

Figure 9.2. Étapes du démarrage d'un ordinateur sous Linux avec le système d'initialisation System V

All the scripts contained in the various /etc/rcX.d directories are really only symbolic links — created upon package installation by the update-rc.d program — pointing to the actual scripts which are stored in /etc/init.d/. The administrator can fine tune the services available in each runlevel by re-running update-rc.d with adjusted parameters. The update-rc.d(1) manual page describes the syntax in detail. Please note that removing all symbolic links (with the remove parameter) is not a good method to disable a service. Instead you should simply configure it to not start in the desired runlevel (while preserving the corresponding calls to stop it in the event that the service runs in the previous runlevel). Since update-rc.d has a somewhat convoluted interface, you may prefer using rcconf (from the rcconf package) which provides a more user-friendly interface.
Enfin, init démarre les programmes de contrôle des différentes consoles virtuelles (getty). Ils affichent une invite, attendent un nom d'utilisateur, puis exécutent login utilisateur pour démarrer une session.