O cliente VPN precisa de ajuda privilegiada para reconfigurar a rede, e esse fato é aplicado de forma ampla demais a tudo ao seu redor. Um script que monta um compartilhamento de arquivos não precisa de root, porque o compartilhamento pertence à sessão do usuário conectado e às credenciais desse usuário. Tirar a montagem do caminho privilegiado elimina a necessidade de regras sudo, hooks de root e edições em aplicativos fornecidos. O que resta é um pequeno applet que permanece aberto, vigia um perfil e faz uma única tentativa.

Por que isso pertence à sessão do usuário

Um volume montado é uma propriedade da sessão que o montou. A sessão de outro usuário não o vê, e uma montagem pertencente a root comporta-se de modo diferente da que o Finder criou. Manter a montagem na sessão do usuário preserva essa semântica.

Os auxiliares privilegiados existem para as partes que realmente precisam deles: criar uma interface de túnel, alterar rotas, atualizar o resolvedor. Montar um compartilhamento SMB não é uma dessas partes. Tratá-lo como se fosse força uma escolha entre sudo sem senha e um script de root que roda sem ninguém presente. Ambos são riscos maiores do que o problema justifica, e a abordagem de sessão do usuário evita a escolha por completo.

Os hooks de conexão do próprio Tunnelblick não são um substituto aqui, pois rodam fora da sessão da área de trabalho e sua ordem em relação aos scripts do cliente não é definida. Consultar o estado a partir de um applet de usuário é um mecanismo menor, com menos suposições.

Provar primeiro à mão que o compartilhamento funciona

A automação não pode fornecer uma rota, uma permissão ou uma conta que não exista. Conecte a VPN manualmente e abra o compartilhamento no Finder antes de escrever qualquer script. Se isso falhar, o script falhará de uma forma mais confusa.

Anote os três valores que o script usará: o nome do perfil exatamente como o Tunnelblick o lista, a URL do compartilhamento e o nome do volume que o Finder mostra após a montagem. O nome do volume importa porque a verificação de uma montagem existente o usa, e uma verificação apenas pelo nome é uma proteção de conveniência, não uma prova da identidade do servidor. Use um nome único na máquina. Depois confirme que o servidor responde, no mínimo.

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

O primeiro comando prova que o servidor responde, o segundo que o nome do perfil é resolvido, e o terceiro mostra como é uma montagem bem-sucedida. Registre os três antes de automatizar qualquer coisa.

Ler o estado do perfil a partir do Tunnelblick

O Tunnelblick expõe suas configurações e os estados delas via AppleScript, e esse é o único hook de que este projeto precisa. O estado que importa é a string relatada para esse perfil específico, não a presença do aplicativo.

A consulta tem consequências que vale a pena declarar. Uma reconexão mais curta que o intervalo pode passar despercebida, e o applet não vê a transição de modo algum. Isso é aceitável para uma proteção de montagem e inaceitável para qualquer coisa que precise reagir a cada evento. Se você precisa de fidelidade de eventos, este é o mecanismo errado, e não um mecanismo que precise de um temporizador mais curto. Escolha o intervalo com esse compromisso em mente.

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

Exporte-o como aplicativo com a opção de permanecer aberto e então inicie-o na sessão conectada em vez de pelo sudo.

Montar uma vez e então parar de tentar

O sinalizador de tentativa é o que impede que isso se torne um laço que adivinha credenciais. Depois que o applet tentou, ele espera que o estado da conexão mude antes de tentar de novo.

Esse comportamento é deliberado. Um compartilhamento que recusa a montagem costuma recusá-la por um motivo que uma nova tentativa não pode corrigir, e tentativas repetidas transformam um pedido em um fluxo deles. O sinalizador é redefinido quando o perfil deixa o estado conectado, então uma reconexão real produz exatamente uma nova tentativa. Sair e reiniciar o applet também o redefine, e essa é a solução manual. Nenhum dos dois caminhos esconde uma falha; ambos a deixam visível no Finder.

O script não carrega nenhuma senha, e deveria continuar assim. Deixe a operação de montagem perguntar e deixe o chaveiro fazer o que a organização suporta. Incorporar uma credencial numa URL transforma um script de conveniência em um segredo que precisa ser rotacionado.

O que o auxiliar não pode fazer

Três limites merecem ser escritos ao lado do applet. Ele não pode ejetar um volume ocupado após uma falha de rede, não pode garantir que o DNS e o servidor estejam prontos quando o estado diz conectado, e não reage a cada reconexão.

O primeiro limite é o que mais importa na prática. Um compartilhamento cujo servidor desaparece deixa um volume que parece montado e bloqueia no acesso, e a correção educada é concluir as operações de arquivo e ejetar antes de uma desconexão planejada. O segundo explica a maioria das primeiras tentativas falhas: o túnel está no ar enquanto o resolvedor ainda não acompanhou, então espere e depois monte uma vez à mão para confirmar. O terceiro é o compromisso de consulta já citado, não um bug a corrigir.

Para uma máquina sem supervisão ou uma frota gerenciada, este projeto tem a forma errada. Use uma política de montagem de propriedade do administrador em vez de estender um applet de desktop a serviço privilegiado.

Artigos relacionados