Dois problemas de nomes aparecem em quase todos os gateways OpenVPN pequenos. Não consegue chegar a um portátil ligado pelo nome do seu certificado, e os serviços atrás do túnel não têm nome nenhum. Parecem um só problema e exigem tratamentos opostos, porque um endereço muda a cada sessão e o outro não. Decida que tipo de nome está a acrescentar antes de editar o que quer que seja.

Decida por nome, não por gateway

O teste é simples: este endereço muda quando um cliente se volta a ligar? Se sim, o nome tem de ser gerado a partir da sessão VPN. Se não, pertence a uma entrada estática que pode ler e rever.

Name kindSource of truthWhere it lives
Connected clientThe address OpenVPN just assignedGenerated hosts file, rewritten per session
Service behind the tunnelA fixed address you choseStatic address= drop-in
Anything with a certificate nameThe certificate, not the poolEither, but the name must match the certificate

Misturá-los é a falha habitual. Um serviço fixado no ficheiro gerado desaparece na primeira vez que o script o reescreve, e um cliente escrito numa entrada estática aponta para quem tinha esse endereço por último. Ambos os erros ficam invisíveis até um nome resolver para a máquina errada. A essa altura, quem depura assume que o DNS está avariado e não o ficheiro.

O caminho dinâmico: learn-address e o pool

O OpenVPN conhece a atribuição, por isso deixe que lhe diga. Estas opções do servidor tornam a atribuição duradoura e programável:

client-config-dir /etc/openvpn/ccd
ifconfig-pool-persist /etc/openvpn/ip-pool 60
script-security 2
learn-address /etc/openvpn/learn-address.sh

learn-address executa o seu script sempre que um endereço é adicionado, atualizado ou removido, e passa a operação, o endereço e o nome comum. Um script mínimo acrescenta uma linha por cliente e remove-a ao apagar:

#!/bin/sh
HOSTS=/etc/openvpn/hosts.lan
case "$1" in
  add|update) echo "$2 $3" >> "$HOSTS" ;;
  delete)     sed -i "/^$2 /d" "$HOSTS" ;;
esac
kill -HUP $(cat /var/run/dnsmasq.pid)

Num dispositivo tun o segundo argumento é o endereço de túnel do cliente, por isso a linha é diretamente utilizável. Num dispositivo tap o OpenVPN passa, em vez disso, o endereço MAC do cliente, porque um segmento tap pode transportar protocolos que não o IPv4, e nesse caso tem de procurar o endereço no ficheiro do pool pelo nome comum antes de escrever o que quer que seja.

Seja claro quanto ao que é o ficheiro gerado: uma fotografia de quem está ligado neste momento. Os nomes desaparecem ao desligar, o que é exatamente o que quer para portáteis que passam de rede em rede e exatamente o que não quer para um servidor ligado toda a noite.

O caminho estático: address= e expansão de domínio

Aponte o dnsmasq para o ficheiro gerado em vez do ficheiro hosts do sistema, e dê-lhe um domínio para que os nomes curtos se expandam em nomes plenamente qualificados:

domain=corp.example
no-hosts
addn-hosts=/etc/openvpn/hosts.lan
listen-address=127.0.0.1,10.8.0.1
bind-interfaces

Com domain definido, uma linha como 10.8.0.6 alice responde tanto por alice como por alice.corp.example. Mantenha o listen-address no gateway do túnel e no loopback, porque um resolver publicado por acidente na interface LAN é um serviço que não pretendia oferecer.

Os serviços que nunca vêm do pool têm as suas próprias entradas. Coloque-os num ficheiro drop-in separado no diretório de configuração da distribuição para que uma atualização de pacote não os possa substituir:

address=/files.corp.example/10.8.0.20
address=/db.corp.example/10.9.0.5

Entregue o resolver ou não acontece nada

Um resolver que ninguém consulta não muda nada. O servidor tem de o anunciar:

push "dhcp-option DNS 10.8.0.1"
push "dhcp-option DOMAIN corp.example"

Os clientes Windows aplicam ambas as opções por si próprios. A maioria dos clientes Linux não: precisam de uma integração de resolver suportada, como o gancho update-resolv-conf da distribuição ou o tratamento de DNS do NetworkManager, ou de um domínio de pesquisa e servidor de nomes manuais. Verifique o resolver real do cliente em vez de assumir que o push foi respeitado, porque um push ignorado parece exatamente um servidor que não responde.

Verifique em três camadas

Pergunte primeiro ao servidor diretamente, depois a um cliente e depois à aplicação:

dig +short @10.8.0.1 alice.corp.example
getent hosts files.corp.example

Se as consultas diretas respondem e a aplicação não, a culpa é da entrega ao cliente e não da zona. Se o nome resolve e a ligação continua a falhar, o nome está bem e o próximo ponto a ver é a rota ou a firewall.

Anote as duas categorias ao lado da configuração: que nomes são gerados, quais estão fixados e com que certificado cada um tem de coincidir. A próxima pessoa que acrescentar um servidor vai copiar o primeiro padrão que encontrar.

Artigos relacionados