Dois daemons de OpenVPN podem ambos relatar um túnel bem-sucedido enquanto o gateway envia cada cliente pelo mesmo. Nada no handshake decide qual túnel um cliente usa; o kernel decide, pacote a pacote, percorrendo as regras de política e depois a tabela que cada regra nomeia. Visto assim, a configuração deixa de ser sobre opções do OpenVPN e passa a ser uma matriz de encaminhamento com dois donos.

É o kernel que decide, não o daemon

Um pacote encaminhado chega à interface LAN e o código de encaminhamento avalia a lista de regras por ordem de prioridade. A primeira regra cujo seletor corresponde nomeia uma tabela, e as rotas dessa tabela escolhem o dispositivo de saída. Se a tabela não tiver uma rota correspondente, a busca segue para a regra seguinte, e é esse detalhe que faz uma configuração pela metade falhar em silêncio em vez de ruidosamente.

O processo do túnel não tem voz nesse percurso. Ele cria uma interface e pode instalar rotas, mas se o pacote de um determinado cliente entra nessa interface depende inteiramente da tabela para a qual foi enviado. Por isso dois túneis com rotas importadas idênticas competem, e o último a escrever ganha para todos. É por isso que uma configuração pode parecer equilibrada nos ficheiros e ainda assim enviar todos os clientes por um único daemon.

Dê a cada instância o seu próprio conjunto de recursos

Comece pelos nomes, porque nomes reutilizados são a forma como as duas instâncias acabam por partilhar estado por acidente. Atribua dispositivos de túnel distintos, ficheiros de configuração distintos, credenciais distintas e unidades de serviço distintas. Registe o ponto final exterior e o endereço do túnel de cada instância na mesma tabela que a matriz de política, para que uma alteração posterior tenha um único lugar onde olhar.

dev tun-office
route-nopull
pull-filter ignore "redirect-gateway"

dev tun-lab
route-nopull

route-nopull mantém as rotas empurradas por um servidor fora da tabela local, e é exatamente o que quer quando as tabelas de política devem ser explícitas. Se um determinado servidor também empurra uma opção redirect-gateway, e se a sua versão de cliente suporta a forma com filtro, vale a pena confirmar no manual em vez de assumir.

Escreva a matriz: origem, tabela, dispositivo

Para cada grupo de clientes, acrescente uma regra que seleciona uma tabela pelo endereço de origem e depois coloque o caminho pretendido nessa tabela:

ip rule add from 10.8.1.0/24 lookup 100 priority 1000
ip rule add from 10.9.1.0/24 lookup 200 priority 1000
ip route add default dev tun-office table 100
ip route add default dev tun-lab table 200

A tabela precisa das rotas de destino que o grupo deve ter, mais as exceções locais ou de gestão que mantêm o gateway utilizável. Uma tabela que contém apenas uma rota predefinida é uma política de túnel completo para esse grupo, o que pode ser exatamente o correto, mas deve ser uma decisão e não uma omissão.

O transporte do próprio túnel não está num grupo de clientes

Os pacotes cifrados de cada daemon nascem no próprio gateway, endereçados ao par exterior. Uma regra que só corresponde a um prefixo de origem de cliente deixa esses pacotes em paz, e por isso as regras limitadas à origem são mais seguras do que as que correspondem a tudo. Uma regra sem seletor pode capturar o transporte do próprio túnel e devolvê-lo por um túnel, e então a ligação falha de uma forma que parece um problema do fornecedor.

Mantenha a sessão de gestão local e o caminho da camada inferior explicitamente fora das tabelas de política. Anote essas exceções ao lado da matriz; fazem parte do desenho, não são uma solução provisória a redescobrir durante um incidente.

Escolher um caminho não o permite

A permissão de encaminhamento é uma segunda decisão tomada mais adiante no caminho. Uma regra de firewall que aceita pacotes que saem pelo segundo túnel não faz o código de encaminhamento escolhê-lo, e uma tabela correta não concede permissão para encaminhar. Ambas têm de existir, e um teste que só prova uma delas irá enganá-lo sobre a outra. Quando um grupo funciona e o outro não, verifique esses dois passos em separado em vez de reescrever as tabelas.

A tradução de origem é uma terceira decisão, e deve ficar limitada ao grupo de origem e ao dispositivo de túnel que realmente o transporta. Acrescente uma cadeia dedicada para as duas instâncias em vez de esvaziar a cadeia postrouting, porque serviços não relacionados podem ter lá entradas e um esvaziamento remove-as em silêncio.

O que acontece quando um túnel cai

Decida o comportamento em caso de falha com antecedência. Quando uma tabela de túnel perde a sua rota, a busca cai para a regra seguinte e o tráfego do grupo continua pelo outro túnel ou pela ligação ascendente normal sem qualquer erro. Se isso não for aceitável, acrescente uma regra terminal com um número de prioridade mais baixo que devolva um resultado inalcançável para essa origem, para que a perda fique visível em vez de ser absorvida.

Envie um pedido novo de cada grupo de origem e registe quatro factos: a tabela selecionada, o dispositivo de saída, a origem traduzida e se a resposta voltou pelo mesmo caminho. Depois desligue um túnel e repita. Dois dispositivos TUN numa lista de interfaces provam que ambos os daemons arrancaram; não dizem nada sobre qual foi usado por um determinado cliente. A segunda execução, com um túnel a menos, é a que mostra se a sua regra de recurso faz o que pretendia.

Artigos relacionados