O script up do OpenVPN rodou cedo demais, ou nunca esteve pronto?
O hook up é executado quando o dispositivo do túnel aparece, antes das rotas e da prontidão das aplicações. Ajuste o script ao evento de que ele precisa em vez de adicionar uma pausa.
O script up é executado, sai com zero, e a tarefa dentro dele não alcança um serviço privado que, a partir de um terminal, funciona perfeitamente dois segundos depois. O instinto é o tempo, e o reparo usual é uma pausa, que esconde a corrida sem entendê-la. A leitura mais útil é que “up” nomeia um hook, não uma garantia de prontidão. Ele dispara quando o dispositivo do túnel é configurado, o que é antes das rotas, do DNS e certamente antes de qualquer aplicação atrás do túnel.
O teste no shell teve sucesso porque rodou depois que tudo se acomodou. O hook rodou num momento específico.
Onde fica o up na ordem de inicialização
OpenVPN configura o dispositivo do túnel e então executa o hook up. A instalação de rotas é um estágio posterior, e tem seu próprio hook, por isso uma tarefa dependente de rota colocada no up pode ver um dispositivo sem caminho útil. Coloque o trabalho de rotas no route-up e o problema de tempo geralmente desaparece.
O manual documenta essa ordem e o ambiente que cada hook recebe. Essa ordem é toda a explicação do clássico relato “funciona do meu shell”, e também é por isso que o mesmo script pode passar em uma máquina e falhar em outra com um estágio de rotas mais lento. Nenhum dos dois resultados diz nada sobre a qualidade do script.
O DNS e a prontidão das aplicações chegam ainda mais tarde. Nem mesmo rotas instaladas são prova de que o endpoint remoto está escutando, de que um nome resolve, ou de que existe uma sessão de desktop para uma tarefa no escopo do usuário.
O que o hook realmente herda
Um hook roda sob a conta e o ambiente do processo do OpenVPN, o que não é o mesmo que o seu shell interativo. Ele pode não ter o barramento de sessão do usuário, um ambiente de desktop ou uma credencial que só é desbloqueada no login. Anote qual desses itens a tarefa realmente precisa.
Isso importa para tarefas que parecem de rede mas dependem de um contexto de usuário: montar um compartilhamento com uma credencial de usuário, definir um proxy por usuário ou configurar uma impressora. Um hook de túnel privilegiado é o lugar errado para elas, e nenhuma espera conserta uma sessão ausente.
Quando uma tarefa falha em um hook, registre a conta, o ambiente e a primeira operação que falhou. Isso separa tempo prematuro de um problema de permissão ou contexto, e os dois têm reparos completamente diferentes. Adivinhar entre eles é como um conserto de cinco minutos vira uma tarde inteira.
Por que adicionar uma pausa não é uma verificação de prontidão
Uma pausa atrasa o script e desloca a janela da corrida. Num dia rápido a tarefa tem sucesso; num dia lento ela falha de novo, e a falha fica mais difícil de reproduzir porque o atraso parece funcionar. Um atraso que só funciona sob carga leve é coincidência, não reparo.
Se a dependência é uma rota, use o hook que corresponde à instalação de rotas. Se a dependência é um serviço atrás do túnel, use uma verificação limitada que espera por aquela condição específica e falha claramente quando ela nunca chega.
Mantenha a falha explícita. Um hook que sai com zero enquanto o trabalho real falhou é pior do que um hook que falha, porque o gerenciador de serviços registra um sucesso e ninguém olha de novo. Uma linha de log do próprio script é a maneira mais barata de manter isso honesto.
Limpeza e reconexão merecem o mesmo cuidado
Um script que muda estado compartilhado precisa de um caminho de desfazer correspondente. Rotas, entradas do resolver e marcações de firewall adicionadas por um hook devem ser idempotentes e reversíveis, ou uma reconexão empilhará uma segunda cópia sobre a primeira.
As reconexões também podem executar hooks com mais frequência do que uma inicialização completa do serviço. Uma interface persistente que restabelece uma sessão pode acionar de novo o ciclo up e route-up, então um script que assume uma execução por boot acabará se comportando mal. Conte as execuções no log ao longo de um dia de oscilações para ver com que frequência ele realmente roda. Depois torne o script seguro para rodar tantas vezes.
Teste o ciclo de vida que falhou, não um comando posterior. Reproduza o boot ou a reconexão, observe o hook executar e confirme que a tarefa teve sucesso no momento em que ele realmente roda. Um sucesso de um shell interativo depois é evidência sobre a dependência, não prova de que o caminho de inicialização funciona.
Dê nome ao evento de que cada tarefa depende e então ligue a tarefa a esse evento. Todo o resto é um atraso fingindo ser uma verificação.