Les hooks qui s’exécutent sans erreur et signalent pourtant un fichier manquant regardent généralement au mauvais endroit, pas qu’ils échouent dans leur tâche. Les chemins relatifs d’un script se résolvent par rapport au répertoire de travail du processus, et un service démarre avec un répertoire de travail que vous n’avez pas choisi. Le fichier à côté du script et le fichier que le processus ouvre ne sont la même chose que lorsque quelque chose les ancre. Cet écart explique une grande part des échecs de hook lus à tort comme des problèmes de permissions.

Vérifiez le chemin avant les permissions, car une erreur de permissions sur le mauvais fichier reste le mauvais fichier.

Un chemin relatif se résout par rapport au processus, pas au fichier

Quand un script appelle open("policy.json"), le noyau résout le nom par rapport au répertoire de travail courant du processus. Rien de l’emplacement du script lui-même ne participe à cette recherche. OpenVPN lance les hooks depuis un répertoire qu’il choisit lui-même, et l’option cd peut le changer, si bien qu’un script testé à la main depuis son propre dossier se comporte autrement une fois que le démon l’exécute. Le test manuel passe, l’exécution du service échoue, et la ligne de journal ne mentionne que le nom manquant.

Python expose l’emplacement du script sous la forme __file__, et c’est ce qui rend l’ancrage possible. Path(__file__).resolve().parent / "policy.json" construit un chemin à partir du fichier plutôt que du processus. Cette seule ligne supprime la dépendance au répertoire de travail sans rien changer aux privilèges.

Ancrez le chemin délibérément, puis vérifiez ce que fait resolve

resolve() suit les liens symboliques, donc une installation qui lie le hook en place s’ancre à la cible du lien, pas au répertoire qui contient le lien. C’est généralement ce que l’on veut pour un déploiement versionné, et c’est faux pour une disposition qui attend des données à côté du lien symbolique. Décidez ce que le déploiement veut dire, et écrivez le code en conséquence plutôt que de découvrir la différence en production. Path(__file__).parent sans resolve() conserve le répertoire propre du lien.

Si les données appartiennent à l’instance et non au programme, prenez un chemin absolu depuis la configuration. Coder en dur un emplacement lie le hook à une seule disposition d’hôte.

Parcourez quatre frontières dans l’ordre

Commencez par le répertoire de travail : comparez le WorkingDirectory, l’option cd d’OpenVPN et tout enveloppeur qui change de répertoire avant l’exec. Confirmez ensuite l’emplacement résolu, car un fichier de nom similaire dans un autre déploiement peut répondre à la recherche et masquer l’erreur. Vient ensuite la vue du système de fichiers : un chroot ou un espace de noms de montage du service peuvent rendre un chemin absolu de l’hôte simplement absent. Enfin, l’identité d’accès, qui est une question distincte de la visibilité.

ProtectHome et PrivateTmp masquent des emplacements différents, et aucun des deux n’apparaît dans une liste de répertoire prise depuis l’hôte. Un chemin qui existe pour root dans un shell peut être invisible à l’intérieur de l’espace de noms de l’unité, et c’est pourquoi tester la même commande hors du service prouve si peu.

Corrigez la recherche sans élargir le service

Ancrer le chemin ne résout que la première frontière. Cela n’expose pas un répertoire que le service masque, et cela ne donne pas à un compte non privilégié l’accès à un fichier réservé à root. Augmenter script-security change quels scripts OpenVPN exécutera; cela n’a aucun effet sur l’endroit où un nom relatif se résout. Changer le répertoire de travail de tout le service est plus large que le problème, car tout autre chemin relatif de certificat, de journal ou d’assistant se déplace avec lui.

Préférez la correction étroite : un chemin déterministe dans le script, une valeur de configuration explicite pour les données de l’instance et une propriété de fichier qui correspond au compte sous lequel le hook s’exécute réellement.

Consignez des preuves qui nomment la frontière

Un rapport d’échec utile contient trois choses : le chemin exact que le hook a tenté, l’environnement qui l’a produit et quelle frontière a refusé. Imprimez le chemin résolu et l’exception sans déverser le contenu du fichier. Ce trio sépare un ancrage erroné d’un montage caché et d’un refus de permissions, qui sont trois corrections différentes.

L’affirmation que root peut lire le fichier depuis un terminal répond à une de ces questions et à aucune des autres. Testez plutôt depuis le contexte du service lui-même.

Articles similaires