VPN Mac au démarrage : launchd supervise la tâche, pas le tunnel
Un plist propre ne prouve rien sur les identifiants ni sur l’état de préparation. Adaptez la tâche à sa session, gardez le client au premier plan et testez dans ce contexte.
La tâche s’exécute à l’ouverture de session, le journal montre le client qui démarre, et le tunnel ne monte jamais. Ou il monte et disparaît quelques secondes plus tard. Dans les deux cas, la liste de propriétés était probablement correcte. launchd a fait deux promesses en acceptant la tâche : il supervisera un processus, et ce processus continuera de s’exécuter. Le VPN a besoin des deux, et un fichier XML correct n’en fournit aucun.
Une liste de propriétés valide n’est pas un service qui fonctionne
plutil -lint vérifie la structure. Il ne peut pas vous dire si le binaire existe, si les arguments sont pris en charge par cette version du client, ou si la tâche démarre dans un contexte où les identifiants sont disponibles. Ce sont des questions sémantiques, et elles expliquent la plupart des échecs qui ressemblent à des problèmes de launchd.
plutil -lint /Library/LaunchDaemons/com.example.vpn.plist
launchctl print system/com.example.vpn
Lisez la sortie de la seconde commande au lieu de supposer que la tâche est chargée. Elle indique le dernier code de sortie et si le service tourne, ce qui distingue « jamais démarré » de « démarré puis mort » avant que vous ne touchiez au profil.
Les agents héritent d’une session utilisateur, les démons non
La documentation launchd d’Apple sépare les agents par utilisateur des démons système. Un agent s’exécute dans le contexte de l’utilisateur connecté, avec son trousseau et son environnement. Un démon s’exécute sans cette session, et déplacer une tâche dans un répertoire système ne recrée pas les identifiants interactifs de l’utilisateur.
Cette distinction décide de la conception. Si la connexion exige qu’une personne se connecte ou approuve une demande MFA, la disposition prise en charge est une tâche dans la session utilisateur qui s’exécute après l’ouverture de session. S’il doit fonctionner sans personne connectée, le client a besoin d’une identité approuvée sans surveillance, avec son propre processus de renouvellement et de révocation. Choisir la mauvaise ligne produit une tâche qui démarre proprement et échoue à la première étape d’authentification.
Ne masquez pas la différence avec un mot de passe dans le tableau d’arguments ou en désactivant les vérifications de certificat. Les deux transforment une exigence d’authentification en secret permanent dans un fichier lisible, et la seconde signifie que le tunnel authentifie tout ce qui répond.
La supervision ne fonctionne que si le processus reste au premier plan
Un client qui se transforme lui-même en démon rend immédiatement le contrôle à launchd, et le superviseur surveille alors un processus déjà terminé. Le tunnel peut être monté, mais launchd croit que la tâche a échoué, et sa politique de redémarrage fera quelque chose que vous n’aviez pas prévu.
Utilisez le mode premier plan ou service documenté du client. Si le produit dispose de sa propre fonction de démarrage prise en charge, elle sait déjà rester au premier plan et passer la main à la pile réseau ; une tâche personnalisée est une conception séparée, pas une amélioration de celle-ci.
Donnez à la tâche une étiquette unique, l’exécutable prévu et un tableau d’arguments réfléchi. Un tableau n’est pas une ligne de commande shell, donc les tubes et les redirections n’y fonctionnent pas, et les guillemets se comportent différemment. Une commande qui réussit dans le terminal d’un administrateur n’est au mieux qu’une vérification préliminaire.
Les identifiants doivent fonctionner sans invite
Le fonctionnement sans surveillance déplace le problème des identifiants au lieu de le supprimer. Quelqu’un doit posséder l’identité, décider combien de temps elle vit et documenter comment elle est remplacée. Un certificat sans suivi d’expiration devient une panne avec une date au calendrier.
Gardez les secrets hors des arguments et hors de la sortie standard de la tâche. Si le client sait lire un identifiant depuis un magasin protégé, utilisez ce chemin, et vérifiez que le contexte d’exécution de la tâche atteint le magasin. Un démon exécuté en root ne peut généralement pas lire un élément du trousseau de session, et c’est le genre de détail qui n’apparaît que dans le contexte système.
Définissez ce que signifie être prêt, puis testez-le là
Un lancement réussi prouve que le processus a démarré. Il ne prouve pas que le réseau est opérationnel, que la passerelle a accepté l’identité ou que l’application privée est joignable. Si autre chose dépend du tunnel, il lui faut un signal de disponibilité qui reflète la connexion, pas l’heure de démarrage de la tâche.
Les nouvelles tentatives doivent être bornées et distinguer un réseau absent d’un identifiant rejeté. Relancer à chaque échec ne répare pas un certificat expiré et produit un journal rempli de tentatives identiques qui masque la vraie.
Acceptez la tâche dans le contexte où elle s’exécutera réellement : pas de réseau au démarrage, une ouverture de session normale, un réveil après veille et un arrêt contrôlé. Enregistrez ensuite ensemble l’étiquette de la tâche, la version du client et la révision du profil, afin que la personne suivante hérite d’un service attribuable plutôt que d’un fichier qui a fonctionné autrefois.