Dos problemas de nombres aparecen en casi cualquier puerta de enlace OpenVPN pequeña. No puede llegar a un portátil conectado por el nombre de su certificado, y los servicios detrás del túnel no tienen ningún nombre. Parecen un solo problema y necesitan tratamientos opuestos, porque una dirección se mueve con cada sesión y la otra no. Decida qué tipo de nombre está añadiendo antes de editar nada.

Decida por nombre, no por puerta de enlace

La prueba es sencilla: ¿cambia esta dirección cuando un cliente se reconecta? Si es así, el nombre debe generarse a partir de la sesión VPN. Si no, pertenece a una entrada estática que puede leer y revisar.

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

Mezclarlos es el fallo habitual. Un servicio fijado en el archivo generado desaparece la primera vez que el script lo reescribe, y un cliente escrito en una entrada estática apunta a quien tuvo esa dirección por última vez. Ambos errores permanecen invisibles hasta que un nombre se resuelve a la máquina equivocada. Para entonces, quien depura supone que el DNS está roto y no el archivo.

La ruta dinámica: learn-address y el pool

OpenVPN conoce la asignación, así que deje que se la diga. Estas opciones del servidor hacen que la asignación sea duradera y programable:

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 ejecuta su script cada vez que se añade, actualiza o elimina una dirección, y pasa la operación, la dirección y el nombre común. Un script mínimo añade una línea por cliente y la elimina al borrar:

#!/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)

En un dispositivo tun el segundo argumento es la dirección de túnel del cliente, así que la línea es directamente utilizable. En un dispositivo tap OpenVPN pasa en cambio la dirección MAC del cliente, porque un segmento tap puede transportar protocolos distintos de IPv4, y entonces debe buscar la dirección en el archivo del pool por el nombre común antes de escribir nada.

Tenga claro qué es el archivo generado: una instantánea de quién está conectado ahora mismo. Los nombres desaparecen al desconectar, que es justo lo que quiere para portátiles que se mueven entre redes y justo lo que no quiere para un servidor encendido toda la noche.

La ruta estática: address= y expansión de dominio

Apunte dnsmasq al archivo generado en lugar del archivo hosts del sistema, y dele un dominio para que los nombres cortos se expandan a nombres plenamente cualificados:

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

Con domain definido, una línea como 10.8.0.6 alice responde tanto para alice como para alice.corp.example. Mantenga listen-address en la puerta de enlace del túnel y loopback, porque un resolutor publicado por accidente en la interfaz LAN es un servicio que no pretendía ofrecer.

Los servicios que nunca vienen del pool tienen sus propias entradas. Póngalos en un archivo drop-in separado dentro del directorio de configuración de la distribución para que una actualización de paquete no pueda sobrescribirlos:

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

Entregue el resolutor o no pasará nada

Un resolutor que nadie consulta no cambia nada. El servidor tiene que anunciarlo:

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

Los clientes de Windows aplican ambas opciones por sí mismos. La mayoría de los clientes de Linux no: necesitan una integración de resolutor compatible, como el gancho update-resolv-conf de la distribución o la gestión de DNS de NetworkManager, o bien un dominio de búsqueda y un servidor de nombres manuales. Compruebe el resolutor real del cliente en lugar de suponer que se respetó el push, porque un push ignorado se ve exactamente como un servidor que no responde.

Verifique en tres capas

Pregunte primero al servidor directamente, luego a un cliente y luego a la aplicación:

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

Si las consultas directas responden y la aplicación no, la culpa es de la entrega al cliente y no de la zona. Si el nombre se resuelve y la conexión sigue fallando, el nombre está bien y lo siguiente que hay que mirar es la ruta o el cortafuegos.

Anote las dos categorías junto a la configuración: qué nombres se generan, cuáles están fijados y con qué certificado debe coincidir cada uno. La próxima persona que añada un servidor copiará el primer patrón que encuentre.

Artículos relacionados