Cliente VPN num servidor LAN: por que as respostas saem pelo caminho errado
Um host que disca uma VPN ganha uma rota predefinida, então as respostas aos clientes LAN saem pelo túnel. Adicione a rota de retorno mais específica e confirme-a.
Os sintomas seguem uma mesma forma: um host funciona, depois liga-se a uma VPN como cliente e agora os clientes LAN alcançam-no enquanto as suas respostas desaparecem. Uma captura no host mostra que as respostas saem pelo dispositivo do túnel em vez da interface LAN. Nada do túnel está avariado, e a correção é uma rota, não uma reconexão. Faça as quatro verificações abaixo por ordem e pare na primeira que falhar.
Uma resposta é um pacote novo, não uma inversão
Ajuda abandonar a ideia de que uma resposta volta pelo caminho que um pedido tomou. O encaminhamento decide-se por pacote, por direção, no host emissor. Um pedido que chegou de 10.64.0.23 dentro do túnel não cria nenhum caminho de retorno; quando o host responde, essa resposta é comparada com a tabela como um pacote novo e sai pela rota que vencer.
É por isso que um cliente de túnel completo numa máquina que também serve uma LAN produz uma falha tão confusa. O cliente instala uma rota predefinida, ou as duas meias rotas predefinidas que alguns clientes preferem, e a resposta a um cliente LAN passa agora a coincidir com o túnel. Vai para o fornecedor, que não tem motivo para a reencaminhar, e o cliente LAN vê um tempo limite apesar de o host estar ativo e a responder localmente. A captura torna isso óbvio, e a tabela de encaminhamento explica-o.
Tenha duas sub-redes em mente enquanto lê o resto. Uma é o conjunto de endereços VPN de onde vêm os clientes remotos, neste exemplo 10.64.0.0/24. A outra é a LAN que tem de continuar a funcionar, 172.16.24.0/24 com o seu router em 172.16.24.1. O erro é que o tráfego entre ambas é decidido pela rota predefinida.
Prove-o com a captura e a consulta
Antes de mudar qualquer coisa, confirme que dispositivo a resposta vai usar. Uma consulta é mais rápida do que uma captura e responde exatamente à pergunta que o núcleo responderá quando o pacote for construído.
ip route get 10.64.0.23 from 172.16.24.10
tcpdump -ni any -c 6 icmp
Leia a resposta em duas partes. Se nomear dev tun0, o host encapsulará a resposta e entregá-la-á ao fornecedor, e o cliente LAN nunca a verá. Se nomear dev eth0 mas o cliente continuar a esgotar o tempo, a rota já está correta e o pacote é descartado mais tarde, o que é outro problema com outra correção.
A captura no mesmo passo resolve a dúvida que um ping não consegue. Um eco de resposta que chega ao cliente LAN prova que algum caminho funciona, não qual interface o transportou, por isso faça a captura no próprio host e observe por onde saem as tramas. Uma impressora na mesma sub-rede continua a responder, porque a sua rota direta é mais específica do que a rota predefinida do túnel. Uma porta reencaminhada falha exatamente como qualquer outro fluxo, porque a tabela escolhe a interface e a ligação não.
Instale a rota mais específica que supera o túnel
Decide o comprimento do prefixo, não a métrica, por isso uma rota para o conjunto de clientes através do router LAN ganha a qualquer rota predefinida que o cliente VPN instale. Não é necessária cirurgia de métricas, e a rota predefinida pode ficar exatamente onde o cliente a colocou.
ip route replace 10.64.0.0/24 via 172.16.24.1 dev eth0
ip route get 10.64.0.23 from 172.16.24.10
Use replace em vez de add, porque um cliente que se reconecte já terá instalado a sua própria entrada e um segundo add falha com um erro de rota existente que se lê como um problema de permissões. Num host Windows o equivalente é route add 10.64.0.0 mask 255.255.255.0 172.16.24.1 -p, onde -p mantém a entrada entre reinícios, já que o cliente pode reconstruir a tabela quando o túnel volta a subir. Num host Windows atual o equivalente suportado é New-NetRoute -DestinationPrefix 10.64.0.0/24 -NextHop 172.16.24.1 -InterfaceAlias Ethernet -PolicyStore PersistentStore, com o comando route mais antigo preservado como forma herdada.
Um detalhe decide se isto está correto ou apenas é plausível: o próximo salto tem de ser o router que realmente possui o caminho de volta aos clientes. Apontar a rota para um endereço a que se chega justamente pelo túnel cria um ciclo que se manifesta como perda intermitente em vez de uma falha limpa. Confirme que o próximo salto está na sub-rede LAN antes de confirmar a linha.
Mantenha a resposta após uma reconexão
Uma rota adicionada à mão sobrevive, no melhor caso, até à reconexão seguinte. Se o conjunto de clientes for dinâmico, fixe-o na configuração do servidor para que o prefixo que encaminhou continue a ser o prefixo que os clientes recebem; caso contrário a entrada aponta para um intervalo vazio e o sintoma regressa semanas depois sem causa evidente. Escrever a rota no próprio script up do cliente é a outra opção fiável, porque é executado depois de o cliente ter reescrito a tabela.
Uma firewall com estado ainda pode derrotar uma rota correta. Se a captura agora mostrar que a resposta sai por eth0 e o cliente continuar a esgotar o tempo, verifique se o host está a descartar o pacote antes de o enviar. A filtragem estrita do caminho inverso e net.ipv4.conf.all.rp_filter definido como 1 descartam pacotes cuja origem não seria encaminhada de volta pela interface por onde chegaram, e esse é exatamente o caso assimétrico que acabou de criar e depois corrigiu, e o estado do conntrack conta a mesma história para as portas reencaminhadas.
A última verificação é a que as pessoas saltam: repita a consulta depois de o túnel ter estado em baixo e de ter voltado a subir. Quatro valores devem coincidir com o que anotou: o destino, o próximo salto, o dispositivo e a origem escolhida. Se algum deles mudou de lugar, o cliente reescreveu a tabela e a correção pertence aos seus hooks e não ao histórico de uma shell.