PrivateTmp : le hook a écrit le fichier, mais où est-il passé ?
Un espace temporaire privé cache le fichier au lieu de le supprimer. Vérifiez la racine du processus avant de modifier l’unité, puis donnez un vrai chemin aux données partagées.
Les hooks signalent un succès, et le même chemin semble toujours vide depuis un shell. Les deux affirmations peuvent être vraies en même temps, car un service systemd peut vivre dans son propre espace de noms de montage avec un répertoire temporaire privé. Une fois cela compris, la question intéressante devient de savoir si l’écriture a réellement abouti.
Deux répertoires temporaires, un seul chemin
Le réglage d’isolation donne à l’unité une vue privée des répertoires temporaires au lieu de les rendre en lecture seule. Les processus extérieurs à l’unité ne peuvent pas voir ce qu’elle y écrit, et tout ce qu’elle laisse derrière elle est jeté lorsque l’unité s’arrête. Un chemin affiché par le hook et un chemin vérifié depuis un shell peuvent donc désigner des objets différents portant le même nom.
C’est un problème de visibilité, et cela ressemble à un problème de perte de données. Rien n’a été supprimé, car le fichier se trouve simplement dans un espace de noms dont le shell n’est pas membre. La même commande se comporte différemment lorsqu’elle est exécutée dans l’unité, et c’est l’observation qui tranche généralement le débat. Lisez les réglages de l’unité avant de conclure quoi que ce soit sur l’écriture.
Séparez l’invisible de l’impossible à écrire
Une écriture réussie et une ouverture échouée produisent des preuves différentes, et cette distinction décide de la réparation. Si le hook dit que le fichier a été créé mais qu’un lecteur extérieur ne le trouve pas, vous avez une question d’espace de noms. Si le hook signale une erreur de permission ou une ouverture échouée, le fichier n’a jamais été écrit et aucun changement d’espace de noms n’aidera.
systemctl show [email protected] -p PrivateTmp -p User -p Group -p RuntimeDirectory
systemctl show [email protected] -p MainPID --value
sudo ls -l /proc/PID/root/tmp/client-stateLe chemin via la racine du processus expose la propre vue du service sur le système de fichiers, sous réserve des contrôles de permission sur ce processus tant qu’il tourne encore. Lisez le journal de l’unité dans la même session, car une erreur d’écriture et un fichier manquant se confondent facilement dès que quelqu’un a déjà décidé de la cause.
Donnez aux données partagées un emplacement explicite
Les données dont seul le service a besoin appartiennent à son répertoire temporaire privé. Les données qu’un autre processus doit lire ont besoin d’un chemin défini pour les deux, avec un propriétaire, un mode et une expiration déclarés. Décidez lequel des deux cas vous avez avant de modifier l’unité. La plupart de ces incidents viennent du fait de traiter un fichier privé comme un fichier partagé.
[Service]
RuntimeDirectory=openvpn-hook-office
RuntimeDirectoryMode=0750Un répertoire d’exécution place le dossier sous la zone d’exécution du système, le crée pour l’utilisateur et le groupe configurés de l’unité et le supprime lorsque l’unité s’arrête. Ajoutez-le via un drop-in pour que l’unité du paquet reste intacte, puis rechargez le gestionnaire et redémarrez cette instance, en acceptant que ses clients se reconnectent.
Conservez tout répertoire d’exécution dont l’unité installée a déjà besoin. Remplacer la liste au lieu d’y ajouter est une façon courante de casser une fonctionnalité sans rapport que personne ne relie au changement.
Deux couches de privilèges peuvent être en désaccord
Le gestionnaire de services crée le répertoire pour l’utilisateur configuré de l’unité, tandis que le démon VPN peut descendre séparément vers son propre compte avant d’exécuter un hook de connexion. Ce sont des couches différentes, et elles peuvent nommer des identités différentes.
Un répertoire appartenant à root avec un mode restrictif est parfaitement visible pour un démon qui a déjà abandonné ses privilèges, et reste non inscriptible pour lui. L’erreur se lit alors comme un problème de permissions alors que le chemin existe exactement là où vous l’attendiez. Comparez le propriétaire du répertoire à l’identité que le hook signale. Lorsqu’ils diffèrent, le mode n’a jamais été la question.
Vérifiez l’identité sous laquelle le hook s’exécute réellement avant de changer la propriété. Changer l’utilisateur d’exécution du service pour réparer un répertoire peut modifier l’accès aux périphériques et les privilèges réseau ailleurs, ce qui est un prix élevé pour un petit problème.
Vérifiez toute la remise
Confirmez quatre choses à la fois : le hook écrit sous sa véritable identité, le lecteur prévu peut consommer le fichier, les utilisateurs sans rapport ne le peuvent pas, et l’arrêt de l’unité nettoie comme prévu. Qu’un fichier apparaisse dans le répertoire temporaire partagé de l’hôte n’est pas une exigence, et c’est généralement le signe que l’échange n’a jamais obtenu son propre chemin. Testez le lecteur après un redémarrage, pas seulement lors de la première exécution. Le comportement de nettoyage fait partie de la conception, alors observez-le au lieu de le supposer.
L’état persistant appartient à un endroit dont la durée de vie correspond, car un répertoire d’exécution est censé disparaître. Choisissez l’emplacement selon la durée de vie plutôt que selon la commodité. Cette habitude évite la prochaine version de cette même enquête.