Les unités peuvent sembler correctes, systemctl start peut annoncer un succès, et dix secondes plus tard le service reste inactif. Ou il redémarre toutes les demi-minutes jusqu'à ce que la limite de démarrage l'arrête. Aucun des deux comportements n'est une panne réseau : l'unité décrit une durée de vie de processus qui ne correspond pas à ce que le client fait réellement. Le client peut forker et sortir, ou configurer la session et sortir immédiatement.

Pourquoi l'unité devient inactive quelques secondes après un démarrage réussi

systemd déduit l'état du processus qu'il a lancé, donc Type= est une affirmation sur ce processus, non une documentation. Avec Type=simple, l'unité compte comme active tant que la commande tourne et devient inactive quand elle revient. Un client qui confie la connexion à un assistant et sort passe donc pour un plantage, même quand le tunnel est monté. Le journal montre alors un schéma de démarrage et d'arrêt qui se lit comme un binaire défaillant.

Lisez le type de l'unité à côté du comportement du client avant de toucher à la configuration réseau.

Choisissez le type qui correspond au client

Deux schémas couvrent la plupart des CLI de fournisseurs : une commande qui configure une session et sort, et une commande qui forke un assistant avant de revenir. Chacun exige une forme d'unité différente.

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/protonvpn-cli connect -f
ExecStop=/usr/bin/protonvpn-cli disconnect

oneshot avec RemainAfterExit=true garde l'unité active après le retour de la commande, ce qui correspond au schéma configurer et sortir, et la commande d'arrêt donne au service un arrêt propre. Un client qui forke garde la même forme mais a besoin de Type=forking pour que systemd suive l'enfant. Réglez Restart=on-failure, RestartSec=30 et un StartLimitBurst fini, pour qu'une panne du fournisseur ne devienne pas une boucle de redémarrage qui enterre l'erreur.

Ne laissez jamais un client supervisé se démoniser

Les superviseurs hors de systemd butent sur le même mur. Un script runit qui lance un client démonisé revient aussitôt au superviseur, qui lit ce retour comme un plantage et démarre une autre copie. Tout superviseur s'attend à posséder le processus de premier plan, comme sshd -D reste devant. Retirez l'option démon des commandes supervisées et laissez le superviseur gérer l'arrière-plan. Les scripts d'enrobage qui reviennent avant que le tunnel existe provoquent la même confusion.

Un processus qui se détache lui-même est invisible pour tout ce qui était censé le surveiller.

La session se termine et emporte le tunnel

Une session de bureau possède le client qu'elle lance. Terminez la connexion et le bus de session disparaît, emportant le tunnel, ce qui explique pourquoi la connexion d'un client graphique tombe souvent quand la dernière fenêtre se ferme. Les serveurs devraient utiliser une unité système ou un profil NetworkManager qui monte tout seul. Une unité utilisateur n'a de sens que si le tunnel doit finir avec la connexion, alors liez-la à la cible de la session graphique et indiquez-le dans sa description.

L'utilisateur du service est l'autre moitié du même problème. Une clé possédée par root en mode 0600 est illisible pour une unité qui tourne sous un autre compte, quoi que sudo ait obtenu dans votre shell.

systemctl cat openvpn-server@work
sudo chown -R openvpn:network /etc/openvpn/server
sudo find /etc/openvpn -type f -perm /077 -ls

Ordonnez les dépendants une fois l'adresse présente

Quand un démon se lie à une adresse de tunnel qui n'existe pas encore, il sort avec Cannot assign requested address. Le remède est un ordonnancement explicite, pas une boucle de réessai.

[Unit]
After=network.target [email protected]
Requires=sys-devices-virtual-net-wg0.device

After= ordonne les tâches, tandis que Requires= sur l'unité du périphérique lie le dépendant à l'existence de l'interface, ce qui est plus fort qu'attendre seulement la cible réseau. Rechargez le gestionnaire après édition et redémarrez le service dépendant, puis lisez son journal au lieu de supposer que l'ordre a pris effet. Envoyez la sortie du client au journal avec StandardOutput=journal ou une option de log, car un client supervisé qui écrit dans un fichier que personne n'ouvre ressemble à un client qui n'a jamais démarré.

Redémarrez ensuite une fois et confirmez que l'unité est active quand le périphérique tunnel apparaît. Un correctif vérifié seulement par systemctl start n'a pas testé l'ordre de démarrage qu'il devait réparer.

Articles similaires