[gull] systemd - script de demarrage/arret - aide [Resolu]

Frederic Dumas f.dumas at siteparc.fr
Sun Aug 19 22:28:17 CEST 2018


Si ça peut intéresser d’autres personnes, voici le fichier « Unit » auquel je suis parvenu, après quelques heures de lecture, d'essais et d’erreurs.


Pour replacer le contexte (cf. mails fin juillet), ce fichier « Unit » pour systemd contrôle le fonctionnement de l'application iPerf3 (1) afin de :

 1 - Lancer automatiquement iPerf3 au démarrage sans intervention humaine, en tache de fond, comme démon.
 2 - Contrôler qu’il est en permanence en fonctionnement, et s’il ne l’est plus, le relancer immédiatement. 


Comme tu le disais Alexandre, le corps d’un fichier « Unit » pour systemd n’est pas un script, par contre très souvent dans ces fichiers créés pour d’autres services, l’option ExecStart= pointe vers un script, enregistré dans un fichier « init » externe. A cause de ça, je croyais indispensable avec systemd de définir dans un script les conditions de démarrage et d’arrêt de l’application. Ce n’est pas le cas. Dans mon fichier « Unit » ci-dessous, l’option ExecStart= pointe directement vers l’exécutable iPerf3, sans passer par aucun script. 


Le 31 juil. 2018 à 15:18, Alexandre Rosenberg <arekkusu at r42.ch> a écrit :

> Inutile de dire que lancer le service en tant que root est une mauvaise idée.
> (voir l'option "User=").


Pour lancer les applications sous d’autres utilisateurs que root, il faut contourner les restrictions de droits d’accès sur les répertoires /run/ (où l'application écrit son PID) et /var/log/ (où l'application écrit son log). J’ai créé un utilisateur iperf3, sans répertoire home/ et sans accès au shell. Quand il est démarré avec systemd sous cet utilisateur, iPerf3 n'a évidemment pas le droit d’écrire dans les répertoires /run/ et /var/log. Par contre il peut les traverser.

Pour éviter de bidouiller les modes et les groupes de ces deux répertoires système, j’ai suivi les recommandations suivantes, trouvées sur la toile :

 - faire créer par systemd un répertoire iperf3/ dans /run/, un autre répertoire iperf3/ dans /var/log/;
   ces répertoires appartiennent à l’utilisateur iperf3;

 - faire créer par iPerf3 un fichier iperf3.pid dans /run/iperf3/
   et un fichier iperf3.log dans /var/log/iperf3/;

 - le propriétaire de /run/iperf3/ et de /var/log/iperf3/ étant iperf3,
   l’application n’a désormais plus d’obstacle pour y écrire tout ce qu’elle veut;

 - enfin, déclarer à systemd le chemin du fichier dans lequel l'application
   écrit son PID : /run/iperf3/iperf3.pid

Les droits par défaut appliqués par systemd à la création de ces répertoires sont 0755, mais il est possible de choisir un autre mode.


Maintenant, la situation concernant /run/iperf3/ et /var/log/iperf3/ n’est pas tout à fait la même.

 - /run/iperf3/ est créé sur un système de fichier temporaire;
   systemd l’efface aussitôt que le démon est arrêté;
   de même, s’il avait été créé à la main,
   ce répertoire aurait été perdu au prochain redémarrage.

   Il n’y a donc pas d’autre choix que de le faire créer à la volée par systemd.


 - /var/log/iperf3/ est créé dans le système de fichier persistant;
   On a donc le choix de le créer soit à la main une fois pour toute,
   soit de demander à systemd de le créer au démarrage du démon

   Je n’ai pas pu expérimenter la seconde option, qui ne marche pas avec la version
   de systemd de ma distribution; le journal de systemd me renvoie systématiquement :


   systemd[1]:
   [/lib/systemd/system/iperf3.service:9] Unknown lvalue 'LogsDirectory' in section 'Service'


   J’ai donc créé à la main le répertoire capable d’accueillir le log de iPerf3 :

   $ sudo mkdir /var/log/iperf3/
   $ sudo chown iperf3:nogroup /var/log/iperf3/
   $ sudo chmod 755 /var/log/iperf3/


Quelques commentaires sur les autres options dans le fichier « Unit ». L’option Restart=always fait ce qu’on espère d’elle : iPerf3 est increvable, dès que l’application est fermée manuellement, elle ressuscite aussitôt avec un autre PID. C’est exactement ce que je cherchais. L’option Restart=on-abort par contre ne la relance pas après un kill sur son PID. Je n’ai pas suffisamment testé pour bien comprendre les différences entre Restart=always, Restart=on-abort, Restart=on-failure, Restart=on-watchdog, etc.



Voilà le fichier « Unit » avec mes commentaires, pour qui voudrait s’en inspirer :


[Unit]

# Pour faire s’afficher ces informations cosmétiques à chaque action sur l’application au moyen de systemd
Description=Active measurements of the maximum achievable bandwidth on IP networks
Documentation=https://iperf.fr/iperf-doc.php

# Pour que iPerf3 ne démarre pas tant qu'une adresse IP n’aura pas été reçue du serveur DHCP :
After=network-online.target


[Service]

# Pour que iPerf3 ne tourne pas sous root, mais sous un utilisateur sans privilèges
User=iperf3

# Pour que systemd crée un répertoire iperf3/ appartenant à l’utilisateur iperf3 dans le répertoire /run/
RuntimeDirectory=iperf3

# Pour que iPerf3 soit supervisé comme démon en tache de fond par systemd
Type=forking

# Pour dire à systemd où se trouve le fichier contenant le PID d’iPerf3
PIDFile=/run/iperf3/iperf3.pid

# Pour que systemd crée un répertoire iperf3/ appartenant à l’utilisateur iperf3 dans le répertoire /var/log/
# Ne marche pas sur ma distribution / je n’ai pas su le faire fonctionner
# LogsDirectory=iperf3

# Pour lancer iPerf3 :
#  - sur son port par défaut
#  - en mode serveur, c.a.d. à l’écoute du port
#  - en mode démon, c.a.d. en tâche de fonds
#  - en écrivant son PID dans le fichier /run/iperf3/iperf3.pid
#  - en écrivant son log dans le fichier /var/log/iperf3/iperf3.log
ExecStart=/usr/bin/iperf3 --port 5201 --server --daemon --pidfile /run/iperf3/iperf3.pid --logfile /var/log/iperf3/iperf3.log

# Pour ressusciter automatiquement iPerf3 à chaque fois qu’il aurait planté ou aurait été arrêté manuellement
Restart=always


[Install]
# Pour que iPerf3 soit normalement lancé au démarrage avec le reste des services
WantedBy=multi-user.target

# Options pour finasser :
# RuntimeDirectoryMode=0755
# LogsDirectoryMode=0755
# UMask=0022




Pour finir, j’aimerai en savoir plus sur les options de sandboxing et de sécurité telles que ProtectSystem= et NoNewPrivileges= par exemple. D’après la documentation de systemd, la première option restreint l’accès au système de fichiers et la seconde interdit toute élévation de privilèges. Je n’évalue pas bien leurs conséquences.

Quand on a une application qui tourne 24/24 en écoute de port et prend du trafic entrant inconnu, on se dit que plus on blinde la sécurité, mieux ça vaut. Faute d’avoir lu suffisamment à propos de ces options, je demande conseille ici. Quelles seraient les options de systemd pertinentes à activer, pour réduire les risques de compromission du système, en cas d’exploitation d’une faille applicative ? La question pourrait concerner aussi d’autres services lancés en tache de fond et frontalement accessibles depuis l’Internet: systemd peut-il aider à renforcer leur sécurité ? Je connais et utilise évidemment fail2ban.



Voici les pages sur le web qui m’ont aidé à comprendre un peu systemd et construire ce fichier « Unit » ; je les cite par ordre d'utilité décroissante:

https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files

https://patrakov.blogspot.com/2011/01/writing-systemd-service-files.html

https://www.freedesktop.org/software/systemd/man/systemd.exec.html

https://unix.stackexchange.com/questions/47695/how-to-write-startup-script-for-systemd

https://scottlinux.com/2014/12/08/how-to-create-a-systemd-service-in-linux-centos-7/




(1) https://iperf.fr/



Le 2 août 2018 à 19:31, Frederic Dumas <f.dumas at siteparc.fr> a écrit :

> 
> Merci Philippe,
> 
> vous m’avez effectivement envoyé au bon endroit. J’aurai peut-être d’autres questions, mais je vais déjà lire ce qu’on y trouve là.
> 
> Frédéric.
> 
> 
> Le 1 août 2018 à 18:26, Philippe Ney <philippe at overcool.ch> a écrit :
> 
>> Bonjour,
>> 
>> Avez-vous trouvé ce lien ?
>> 
>> https://unix.stackexchange.com/questions/15348/writing-basic-systemd-service-files
>> 
>> Il me semble contenir beaucoup d'information et liens intéressants.






More information about the gull mailing list