Problema
En entornos donde OPNSense actúa como firewall, servidor OpenVPN y host de servicios como Caddy y Unbound, es frecuente que los clientes VPN pierdan la capacidad de resolver nombres internos (por ejemplo homeassistant.mynetwork.local) y, como consecuencia, no puedan alcanzar los sitios publicados por el reverse proxy. La conectividad IP (ping, acceso a interfaces LAN) funciona, pero cualquier solicitud basada en el nombre de dominio interno devuelve NXDOMAIN o timeout. El síntoma se reproduce tanto en IPv4 como en IPv6 y ocurre únicamente cuando el tráfico proviene de la interfaz tun0 del túnel VPN.
Causa
Los fallos de resolución y de acceso al reverse proxy suelen deberse a una combinación de tres áreas:
-
Configuración de Unbound/DNS
- La zona local no está asociada a la interfaz VPN. Unbound solo escucha en las interfaces LAN y descarta consultas que llegan por tun0.
- Los dominios locales no están incluidos en la lista Domain Overrides o Search Domains para la red VPN, por lo que el cliente sigue usando su DNS externo.
-
Reglas de firewall en OPNSense
- La política de entrada (INPUT) permite tráfico LAN → LAN pero no permite que la interfaz tun0 acceda a puertos 53 (DNS) y 80/443 (Caddy).
- Las reglas de “allow any” aplicadas a la red VPN pueden estar limitadas a la tabla LAN y no abarcar la zona OpenVPN.
-
Binding del reverse proxy
- Caddy está configurado para escuchar en
*:80y*:443, pero el proceso de resolución de nombres interno depende de la IP que el cliente usa para la conexión. Si el cliente resuelve el dominio a una IP LAN y el firewall bloquea el tráfico desde tun0 a esa IP, la conexión nunca llega al proceso de Caddy. - En algunos casos, la opción Redirect‑gateway del servidor OpenVPN envía todo el tráfico al túnel, pero la ruta está incompleta para la subred donde reside Caddy, provocando un “blackhole”.
- Caddy está configurado para escuchar en
Solución
1. Asegurar que Unbound escuche en la interfaz VPN
- En Services → Unbound DNS → General, marca la opción Network Interfaces y selecciona tanto la(s) interfaz(es) LAN como OpenVPN.
- En Advanced Settings, añade la subred VPN a Domain Overrides si utilizas un dominio distinto para la zona interna.
- En DHCP → Server → OpenVPN, habilita Domain Search List con
mynetwork.local. Esto fuerza a los clientes a enviar consultas a la IP del servidor DNS de OPNSense (normalmente la IP del túnel, p.e.10.8.0.1).
2. Permitir tráfico DNS y HTTP/HTTPS desde tun0
Crea una regla de firewall específica para la interfaz OpenVPN:
- Action: Pass
- Interface: OpenVPN
- Source: OpenVPN net (p.e.
10.8.0.0/24) - Destination: This firewall (IP)
- Destination Port: 53 (TCP/UDP), 80, 443
- Description: “Allow VPN clients to reach DNS and reverse proxy”
Si prefieres una regla única, usa Destination = any y Port = 53,80,443. Asegúrate de colocar la regla por encima de cualquier regla de bloqueo implícito.
3. Verificar el binding de Caddy
Aunque sockstat muestra *:80 y *:443, es buena práctica forzar la escucha en todas las interfaces explícitamente en el archivo de configuración de Caddy:
{
servers {
protocol {
# Escucha en todas las interfaces, incluyendo tun0
listen :80
listen :443
}
}
}
Reinicia Caddy después de modificar la configuración.
4. Añadir rutas estáticas si es necesario
Si el túnel OpenVPN no incluye la subred donde reside Caddy (por ejemplo, 192.168.10.0/24), añade una ruta estática en el servidor OpenVPN:
push "route 192.168.10.0 255.255.255.0"
Y, en la configuración del cliente, verifica que la ruta aparezca con route -n (Linux) o netstat -rn (Windows).
5. Comprobar la configuración del cliente VPN
En el cliente, fuerza el uso del DNS interno:
# Windows
netsh interface ip set dns "OpenVPN Connection" static 10.8.0.1 primary
# Linux (NetworkManager)
nmcli con modify "OpenVPN" ipv4.dns "10.8.0.1"
nmcli con up "OpenVPN"
Desactiva la opción block‑outside‑dns solo si el cliente necesita resolver nombres externos mediante el DNS del ISP; de lo contrario, mantenla para evitar fugas de DNS.
Cuándo aplicar esta solución
- Los clientes VPN pueden hacer ping a la IP LAN pero fallan al resolver nombres internos.
curlcontra la IP LAN del reverse proxy funciona, pero la URL basada en el dominio interno devuelve error de resolución.- Las reglas de firewall existentes permiten tráfico LAN ↔ LAN pero no incluyen la interfaz OpenVPN.
- Unbound muestra “Listening on: 127.0.0.1” o “LAN only” en el diagnóstico.
No es necesario aplicar estos pasos si:
- El DNS interno ya está configurado en la interfaz VPN y los clientes pueden resolver sin problemas.
- La política de firewall ya incluye una regla de paso para
any → anyen la interfaz OpenVPN.
Código
# 1. Habilitar Unbound en la interfaz OpenVPN
opnsense-shell -c "configctl unbound reload"
# 2. Añadir regla de firewall (CLI)
pfctl -a openvpn -f - <<EOF
pass in quick on openvpn from 10.8.0.0/24 to any port {53,80,443} keep state
EOF
# 3. Reiniciar Caddy
service caddy restart
Verificación
-
Comprobación DNS
Desde el cliente VPN, ejecuta:nslookup homeassistant.mynetwork.local 10.8.0.1La respuesta debe contener la IP LAN de Home Assistant.
-
Prueba de HTTP
curl -vk https://homeassistant.mynetwork.localDebería devolver
200 OKy el encabezadoServer: Caddy. -
Revisión de rutas
En el cliente, muestra la tabla de rutas y verifica que la subred del reverse proxy está presente a través del túnel. -
Logs de firewall
En OPNSense, abre Firewall → Log Files → Live View y filtra porOpenVPN. No deben aparecer paquetes bloqueados hacia los puertos 53, 80 o 443.
Si todos los pasos son satisfactorios, el problema de resolución y acceso al reverse proxy queda resuelto.
Notas adicionales
- En entornos con varios túneles OpenVPN, repite la regla de firewall para cada interfaz VPN.
- Cuando se usan split‑tunnel y redirect‑gateway simultáneamente, revisa que la lista de rutas empujadas (
push "route …") cubra todas las subredes que alojan servicios internos. - Si el cliente está en Windows y sigue usando el DNS del ISP, verifica que la política de grupo
Disable DNS over HTTPSno esté sobrescribiendo la configuración. - Mantén una copia de la configuración de Unbound y de las reglas de firewall en un repositorio Git; facilita la recuperación tras actualizaciones de OPNSense.