FreeBind contra After=: ligar um socket do systemd a um endereço VPN
O FreeBind permite que o systemd possua o ouvinte antes de o endereço VPN existir; o After= apenas ordena tarefas. Compare os dois e depois teste a ordem e a prontidão.
Na inicialização, uma unidade socket que liga um endereço VPN fixo pode falhar antes de o túnel o ter atribuído, e o serviço por trás nunca arranca. Dois interruptores parecem correções e resolvem metades diferentes desse problema. O FreeBind permite que o systemd crie o ouvinte enquanto o endereço ainda falta. O After= apenas ordena tarefas, por isso muda quando as coisas começam sem fazer o endereço chegar mais cedo.
Dois problemas diferentes, dois interruptores diferentes
O primeiro problema é uma falha de ligação: o kernel recusa escutar num endereço que o anfitrião não possui, por isso a unidade socket falha de imediato e o serviço nunca é ativado. O segundo problema é uma falha de prontidão: o endereço acaba por existir, mas algo tenta usá-lo antes de o túnel transportar tráfego. O FreeBind trata do primeiro e não faz nada pelo segundo. As diretivas de ordem não tratam de nenhum dos dois diretamente, porque apenas decidem o que começa e em que sequência. Nomear a falha que realmente tem é toda a decisão.
Confirme qual dos dois tem no registo, e não na descrição do serviço. Uma falha de ligação nomeia um endereço e relata que não pode ser atribuído. Uma falha de prontidão aparece normalmente mais tarde, como tempo limite esgotado ou ligação recusada vista do outro lado, com uma unidade socket perfeitamente saudável nos registos.
FreeBind: o ouvinte existe antes do endereço
O FreeBind diz ao kernel para permitir uma ligação a um endereço não local, para que o systemd possa criar o socket à escuta no arranque e entregá-lo à aplicação sempre que a aplicação arranca. É esse o sentido da ativação por socket, e a razão pela qual o socket pode sobreviver ao serviço por trás dele.
[Socket]
ListenStream=
ListenStream=10.8.0.1:8443
FreeBind=yes
A atribuição vazia apaga as entradas de escuta herdadas da unidade do fornecedor antes de a nova ser adicionada, o que impede que um ouvinte wildcard remanescente responda em todas as interfaces. Substitua o endereço e a porta pelos seus e verifique a unidade efetiva, não apenas o ficheiro drop-in. Use um drop-in com o nome da unidade em vez de editar um ficheiro do pacote no local, porque a próxima atualização do pacote sobrescreve a edição e não deixa qualquer rasto da intenção. Depois aplique-o através do procedimento de recarga e reinício que a unidade socket espera.
A referência de sockets do systemd documenta o comportamento IPv4 e IPv6 por trás desta opção, e o detalhe importante é que se aplica à ligação e não ao encaminhamento. Nada nela atribui um endereço ou inicia uma VPN. O FreeBind é uma permissão concedida ao ouvinte, não um substituto da interface.
After= e Wants=: a ordem não é prontidão
Ordem e requisito são eixos separados, e confundi-los produz unidades que arrancam na ordem certa e mesmo assim falham. After=vpn-client.service significa apenas que, se ambas as tarefas forem iniciadas, esta espera que a outra seja iniciada. Não puxa a VPN e não espera que a VPN termine de ligar.
As diretivas de requisito como Wants= e Requires= tratam da ativação e diferem no que acontece quando a dependência falha: uma continua e a outra para. Nenhuma das duas sabe o que significa um túnel ligado. Um processo VPN pode estar ativo sem endereço atribuído, ou com endereço atribuído e sem rota até ao par, e ambos os estados satisfazem a dependência. Se a aplicação precisa que o endereço exista, modele essa condição explicitamente em vez de tratar o arranque do processo como prova de prontidão.
Verifique o que a unidade declara realmente com systemctl cat e systemctl show -p After -p Wants -p Requires. Drop-ins de três diretórios diferentes podem acrescentar diretivas que nunca escreveu, e a unidade efetiva é a única coisa que o systemd lê.
O que o network-online.target não faz
Uma unidade ordenada depois de network-online.target espera que o gestor de rede declare a rede utilizável, o que é um ponto de sincronização do arranque e não uma condição contínua. Não diz nada sobre se um túnel específico está ativo, e não volta a disparar quando uma VPN se reconecta a meio da tarde. Tratá-lo como um monitor de reconexão é a leitura errada mais comum desse objetivo.
O projeto systemd documenta essa distinção diretamente, e a consequência prática é que tudo o que precisa de um endereço de túnel tem de possuir a dependência por si. Uma unidade que espera pelo network-online e depois liga um endereço de túnel só está correta quando o túnel sobe primeiro por acaso, o que é uma coincidência e não um desenho.
Teste o ciclo de vida que realmente escolheu
Teste um arranque limpo, um pedido depois de o endereço aparecer e o comportamento depois de a VPN cair e voltar. Esses três casos separam um ouvinte funcional de um serviço funcional.
systemd-analyze verify myapp.socket
systemctl cat myapp.socket
ss -ltn "sport = :8443"
O primeiro comando apanha erros do ficheiro de unidade antes de um reinício, o segundo mostra a unidade fundida e o terceiro prova se o ouvinte existe e em que endereço. Um ouvinte num endereço wildcard onde esperava um endereço de túnel é exatamente o resto que o ListenStream vazio devia remover. Repita o terceiro comando após uma reconexão da VPN para ver se o endereço se deslocou.
Escolha o ciclo de vida deliberadamente: ou um ouvinte ligado livremente que espera o regresso de um endereço estável, ou um serviço que para com o túnel e arranca de novo na recuperação. São desenhos diferentes e falham de formas diferentes. Depois mantenha a política de acesso ligada às fontes e caminhos que pretendia, porque ligar um endereço de destino não exige que os pacotes aceites tenham chegado por uma interface de confiança.