Il client VPN ha bisogno di un aiuto privilegiato per riconfigurare la rete, e questo fatto viene applicato troppo ampiamente a tutto ciò che lo circonda. Uno script che monta una condivisione di file non ha bisogno di root, perché la condivisione appartiene alla sessione dell’utente connesso e alle credenziali di quell’utente. Spostare il montaggio fuori dal percorso privilegiato elimina la necessità di regole sudo, hook root e modifiche alle applicazioni fornite. Ciò che resta è una piccola applet che resta aperta, sorveglia un profilo e fa un solo tentativo.

Perché questo appartiene alla sessione utente

Un volume montato è una proprietà della sessione che lo ha montato. La sessione di un altro utente non lo vede, e un montaggio posseduto da root si comporta diversamente da quello creato dal Finder. Mantenere il montaggio nella sessione utente preserva quella semantica.

Gli helper privilegiati esistono per le parti che ne hanno davvero bisogno: creare un’interfaccia di tunnel, cambiare le rotte, aggiornare il resolver. Montare una condivisione SMB non è una di quelle parti. Trattarlo come se lo fosse impone una scelta tra sudo senza password e uno script root che viene eseguito mentre non c’è nessuno. Entrambi sono rischi più grandi di quanto il problema giustifichi, e l’approccio della sessione utente evita del tutto la scelta.

Gli hook di connessione di Tunnelblick non sono un sostituto qui, perché vengono eseguiti fuori dalla sessione desktop e il loro ordine rispetto agli script del client non è definito. Interrogare lo stato da un’applet utente è un meccanismo più piccolo, con meno presupposti.

Dimostrare prima a mano che la condivisione funziona

L’automazione non può fornire una rotta, un permesso o un account che non esiste. Connetti la VPN manualmente e apri la condivisione nel Finder prima di scrivere qualunque script. Se questo fallisce, lo script fallirà in un modo più confuso.

Annota i tre valori che lo script userà: il nome del profilo esattamente come Tunnelblick lo elenca, l’URL della condivisione e il nome del volume che il Finder mostra dopo il montaggio. Il nome del volume conta perché il controllo di un montaggio esistente lo usa, e un controllo basato solo sul nome è una protezione di comodità, non una prova dell’identità del server. Usa un nome unico sulla macchina. Poi conferma che il server risponda quanto meno.

smbutil view //files.corp.example
osascript -e 'tell application "Tunnelblick" to get state of first configuration whose name is "Office"'
mount | grep -i smbfs

Il primo comando dimostra che il server risponde, il secondo che il nome del profilo viene risolto, e il terzo mostra com’è un montaggio riuscito. Registra tutti e tre prima di automatizzare qualcosa.

Leggere lo stato del profilo da Tunnelblick

Tunnelblick espone le sue configurazioni e i loro stati tramite AppleScript, ed è l’unico hook di cui questo progetto ha bisogno. Lo stato che conta è la stringa riportata per quel profilo specifico, non la presenza dell’applicazione.

L’interrogazione ha conseguenze che vale la pena dichiarare. Una riconnessione più breve dell’intervallo può passare inosservata, e l’applet non vede affatto la transizione. È accettabile per una protezione di montaggio e inaccettabile per qualcosa che debba reagire a ogni evento. Se ti serve fedeltà agli eventi, questo è il meccanismo sbagliato, non un meccanismo che richieda un timer più corto. Scegli l’intervallo tenendo presente questo compromesso.

property attempted : false

on idle
    set profileName to "Office"
    set shareURL to "smb://files.corp.example/OfficeTeam"
    set volName to "OfficeTeam"
    tell application "Tunnelblick" to set vpnState to state of first configuration whose name is profileName
    if vpnState is not "CONNECTED" then
        set attempted to false
        return 20
    end if
    tell application "Finder" to set mounted to (exists disk volName)
    if (not mounted) and (not attempted) then
        set attempted to true
        try
            mount volume shareURL
        end try
    end if
    return 20
end idle

Esportalo come applicazione con l’opzione di restare aperta, poi avviala nella sessione connessa invece che tramite sudo.

Montare una volta, poi smettere di provare

Il flag di tentativo è ciò che impedisce a questo di diventare un ciclo che indovina le credenziali. Una volta che l’applet ha provato, attende che lo stato della connessione cambi prima di riprovare.

Questo comportamento è deliberato. Una condivisione che rifiuta il montaggio di solito lo rifiuta per una ragione che un nuovo tentativo non può correggere, e i tentativi ripetuti trasformano una richiesta in un flusso di richieste. Il flag viene reimpostato quando il profilo lascia lo stato connesso, così una vera riconnessione produce esattamente un nuovo tentativo. Uscire e riavviare l’applet lo reimposta pure, e questa è la soluzione manuale. Nessuna delle due strade nasconde un guasto; entrambe lo lasciano visibile nel Finder.

Lo script non contiene alcuna password, e dovrebbe restare così. Lascia che l’operazione di montaggio chieda, e lascia che il portachiavi faccia ciò che l’organizzazione supporta. Incorporare una credenziale in un URL trasforma uno script di comodità in un segreto da ruotare.

Cosa l’helper non può fare

Tre limiti meritano di essere scritti accanto all’applet. Non può espellere un volume occupato dopo un guasto di rete, non può garantire che il DNS e il server siano pronti quando lo stato dice connesso, e non reagisce a ogni riconnessione.

Il primo limite è il più importante in pratica. Una condivisione il cui server scompare lascia un volume che sembra montato e blocca all’accesso, e la correzione educata è terminare le operazioni sui file ed espellere prima di una disconnessione pianificata. Il secondo spiega la maggior parte dei primi tentativi falliti: il tunnel è attivo mentre il resolver non ha ancora recuperato, quindi aspetta e poi monta una volta a mano per confermare. Il terzo è il compromesso sull’interrogazione di prima, non un bug da correggere.

Per una macchina incustodita o una flotta gestita, questo progetto ha la forma sbagliata. Usa una politica di montaggio gestita dall’amministratore invece di estendere un’applet desktop in servizio privilegiato.

Articoli correlati