Eu tinha uma máquina de laboratório que aceitava um túnel de um site remoto e também discava para uma rede de fornecedor. O perfil de saída funcionava havia semanas. Depois que o servidor de entrada foi adicionado, o de saída conectava e então parava de passar tráfego em segundos, ou se recusava a iniciar com um erro de endereço já em uso. Os arquivos de configuração não haviam mudado; o host simplesmente ganhara um segundo processo OpenVPN com sua própria opinião sobre portas e rotas.

A falha não é aleatória, e não é um problema de autenticação. Dois daemons em uma máquina competem pelo mesmo socket local e pela mesma tabela de rotas, e quem inicia ou se reconecta por último costuma vencer. Saber qual dessas duas colisões você tem decide onde olhar primeiro.

Leia o sintoma ao contrário

Comece por quando o túnel morre. Um erro de bind na inicialização aponta para o lado que escuta: algo já possui aquela porta, e o OpenVPN se recusa a iniciar em vez de compartilhá-la. Um túnel que sobe e depois fica em silêncio aponta para o roteamento, porque uma rota instalada pela outra instância pode tirar os pacotes da conexão externa do caminho.

Os dois casos produzem a mesma reclamação do usuário, por isso os laços de nova tentativa e os scripts de watchdog não consertam nada. Eles reconectam o cliente no mesmo conflito. A primeira pergunta útil é se o processo ainda está rodando quando o tráfego para.

Um socket e um dispositivo por instância

Um servidor que escuta vincula sua porta; um cliente de saída também precisa de uma porta local para seu tráfego encapsulado. Quando os dois vivem no mesmo host, o comportamento padrão do cliente pode colidir com a porta do servidor. A porta local do cliente pode ser fixada, e a vinculação pode ser dispensada onde o par não precisa de uma porta de origem fixa:

lport 1195
nobind
dev tun1

Esses números são exemplos, não um requisito. O importante é que o cliente pare de competir pela porta do servidor e que cada instância receba um dispositivo de túnel separado. Dois daemons que compartilham tun0 sobrescrevem o estado do dispositivo um do outro mesmo quando as portas diferem, então um dispositivo por túnel não é opcional.

nobind pertence ao lado do cliente. Um servidor ainda precisa vincular e escutar, então não copie a linha para a configuração do servidor, e não desative a vinculação em um cliente cujo par filtra por uma porta de origem fixa.

Escolha um único dono para a rota padrão

Apenas uma conexão pode instalar uma rota padrão. Se os dois perfis redirecionam todo o tráfego, a segunda conexão substitui silenciosamente a primeira, e a primeira parece quebrar. Ou você mantém o túnel de saída dividido e empurra apenas os prefixos do fornecedor, ou dá a ele uma tabela de rotas separada.

ip rule add from 10.9.0.2 table 120
ip route add default dev tun1 table 120
ip route get 10.9.0.2

Os endereços e o número da tabela acima são marcadores de posição. Imediatamente depois de adicionar a regra, confirme que o endereço do próprio servidor VPN ainda é resolvido pela tabela normal; uma tabela que captura o transporte externo quebra o túnel que ela deveria proteger, e o laço de reconexão que se segue parece um provedor não confiável.

Para uma configuração que precisa sobreviver a reconexões e reinicializações, um namespace de rede é a fronteira mais sólida. O segundo cliente roda dentro do próprio namespace, com suas próprias interfaces e rotas, e apenas os serviços que precisam cruzar são expostos. O host mantém uma rota padrão, e uma reconexão do namespace não pode reescrevê-la.

Verifique com a tabela, não com a linha de status

Um cliente que relata estar conectado prova apenas seu canal de controle. Capture o estado de roteamento antes e depois de cada conexão, e então pergunte ao kernel qual dispositivo um destino real usaria:

ip route show
ip route get 10.40.0.20
ss -lunp | grep 1194

Se o dispositivo selecionado para o endereço do fornecedor muda quando o segundo túnel inicia, você tem a colisão de rotas. Se os dois processos aparecem na mesma porta local, você tem a colisão de sockets. Corrigir a primeira sem a segunda apenas move a falha para a próxima reconexão.

Escreva as portas, dispositivos, tabelas e dono da rota no runbook do host. Caso contrário, a próxima pessoa que adicionar um terceiro túnel redescobrirá a mesma colisão, e a única evidência visível será uma conexão que funciona até o daemon de outra pessoa reiniciar.

Artigos relacionados