Il job parte all'accesso, il log mostra l'avvio del client, ma il tunnel non sale mai. Oppure sale e sparisce pochi secondi dopo. In entrambi i casi il property list era probabilmente corretto. launchd ha fatto due promesse quando ha accettato il job: supervisionerà un processo e quel processo continuerà a girare. La VPN ha bisogno di entrambe, e un file XML corretto non ne fornisce nessuna.

Un property list valido non è un servizio funzionante

plutil -lint controlla la struttura. Non può dirti se il binario esiste, se gli argomenti sono supportati da questa versione del client o se il job parte in un contesto in cui le credenziali sono disponibili. Sono domande semantiche e spiegano la maggior parte dei guasti che sembrano problemi di launchd.

plutil -lint /Library/LaunchDaemons/com.example.vpn.plist
launchctl print system/com.example.vpn

Leggi l'output del secondo comando invece di dare per scontato che il job sia caricato. Riporta l'ultimo stato di uscita e se il servizio è in esecuzione, il che distingue «non è mai partito» da «è partito ed è morto» prima che tu tocchi il profilo.

Gli agent ereditano una sessione utente, i daemon no

La documentazione di Apple su launchd separa gli agent per utente dai daemon di sistema. Un agent gira nel contesto dell'utente connesso, con il suo portachiavi e il suo ambiente. Un daemon gira senza quella sessione, e spostare un job in una directory di sistema non ricrea le credenziali interattive dell'utente.

È questa distinzione a decidere il progetto. Se la connessione richiede che una persona acceda o approvi un prompt MFA, la soluzione supportata è un job nella sessione utente che parte dopo l'accesso. Se deve funzionare senza nessuno connesso, il client ha bisogno di un'identità non presidiata approvata, con un proprio processo di rinnovo e revoca. Scegliere la riga sbagliata produce un job che parte pulito e fallisce al primo passo di autenticazione.

Non mascherare la differenza con una password nell'array di argomenti o disattivando i controlli sui certificati. Entrambe trasformano un requisito di autenticazione in un segreto permanente dentro un file leggibile, e la seconda significa che il tunnel autentica qualunque cosa risponda.

La supervisione funziona solo se il processo resta in primo piano

Un client che si trasforma in daemon restituisce subito il controllo a launchd, e il supervisore sorveglia allora un processo già terminato. Il tunnel può essere attivo, ma launchd ritiene che il job sia fallito e la sua politica di riavvio farà qualcosa che non volevi.

Usa la modalità primo piano o servizio documentata dal client. Se il prodotto ha una propria funzione di avvio supportata, quella funzione sa già come restare in primo piano e come passare lo stack di rete; un job personalizzato è un progetto separato, non un miglioramento.

Assegna al job un'etichetta univoca, l'eseguibile previsto e un array di argomenti deliberato. Un array non è una riga di comando della shell, quindi pipe e reindirizzamenti non funzionano lì, e le virgolette si comportano diversamente. Un comando che riesce nel terminale di un amministratore è al massimo un controllo preliminare.

Le credenziali devono funzionare senza prompt

Il funzionamento non presidiato sposta il problema delle credenziali invece di eliminarlo. Qualcuno deve possedere l'identità, decidere quanto dura e documentare come viene sostituita. Un certificato senza monitoraggio della scadenza diventa un'interruzione con una data sul calendario.

Tieni i segreti fuori dagli argomenti e fuori dallo standard output del job. Se il client supporta la lettura di una credenziale da un archivio protetto, usa quel percorso, e verifica che il contesto di esecuzione del job possa raggiungere l'archivio. Un daemon che gira come root di solito non può leggere un elemento del portachiavi di accesso, ed è il tipo di dettaglio che emerge solo nel contesto di sistema.

Definisci cosa significa pronto, poi prova lì

Un avvio riuscito dimostra che il processo è partito. Non dimostra che la rete sia attiva, che il gateway abbia accettato l'identità o che l'applicazione privata sia raggiungibile. Se qualcos'altro dipende dal tunnel, ha bisogno di un segnale di prontezza che rifletta la connessione, non l'ora di avvio del job.

I tentativi devono essere limitati e devono distinguere una rete assente da una credenziale rifiutata. Rilanciare a ogni errore non può riparare un certificato scaduto e produce un log pieno di tentativi identici che nasconde quello vero.

Accetta il job nel contesto in cui girerà davvero: nessuna rete all'avvio, un accesso normale, un risveglio dallo standby e un arresto controllato. Poi registra insieme l'etichetta del job, la versione del client e la revisione del profilo, così la persona successiva eredita un servizio attribuibile invece di un file che una volta funzionava.

Articoli correlati