client-config-dir se ignora cuando OpenVPN pasa a ser un servicio
Un client-config-dir relativo se resuelve contra el directorio de trabajo del demonio. Lee la unidad, recorre los permisos de la ruta y luego confirma la búsqueda en el registro.
El túnel levanta y el cliente se conecta, pero la dirección fija y las rutas empujadas que definiste para ese usuario concreto faltan. En el registro no pone “file not found”, y eso es justo lo que manda a la gente a regenerar certificados. En la mayoría de estos casos el demonio se ejecuta desde un directorio distinto del shell en el que probaste, y client-config-dir nunca se resolvió como suponías. El arreglo es corregir la ruta, no restablecer credenciales.
Lee la unidad antes de tocar la configuración
Empieza por el proceso que realmente se ejecuta, no por el archivo que editaste. Pregunta a systemd por la línea de ejecución, el directorio de trabajo y la cuenta a la que baja. Esas tres respuestas explican la mayoría de fallos de esta clase:
systemctl show openvpn-server@server -p ExecStart -p WorkingDirectory -p User -p RootDirectoryUn WorkingDirectory vacío significa que la unidad arranca en /, así que un client-config-dir ccd relativo se busca en /ccd. Ese directorio casi nunca existe, y el demonio no considera fatal su ausencia.
Compáralo con el arranque interactivo que usaste durante las pruebas, donde el directorio actual de tu shell era probablemente el de configuración. El mismo archivo, las mismas palabras clave, dos resultados distintos.
Contra qué se resuelve una ruta relativa
La palabra clave se resuelve contra el directorio de trabajo del proceso en el momento en que se usa la opción. No significa “junto al archivo de configuración que pasé con --config”. OpenVPN leerá encantado una configuración desde una ruta absoluta y aun así resolverá los valores relativos en otro sitio, y esa es exactamente la trampa. El manual de OpenVPN 2.6 expone la regla bajo --client-config-dir y de nuevo bajo --cd.
La palabra clave cd cambia ese contexto antes de que se lean otros archivos, así que una unidad que define cd /etc/openvpn/server y luego client-config-dir ccd se resuelve en /etc/openvpn/server/ccd. Si añades cd, revisa el orden de las directivas y recuerda que afecta a cualquier otra referencia relativa del mismo archivo.
Recorre la ruta como la cuenta del demonio
Una ruta puede ser correcta y aun así no ser legible. Tras soltar privilegios el demonio ya no es root, así que cada directorio padre necesita permiso de búsqueda para esa cuenta, y el archivo del cliente necesita permiso de lectura. Basta un bit de ejecución ausente en un padre para ocultar el archivo, y el error solo se manifiesta como un cliente que recibe en silencio el grupo por defecto.
namei imprime el permiso de cada componente en orden, lo que es más rápido que comprobar los directorios uno a uno:
namei -l /etc/openvpn/server/ccd/client1Luego prueba la lectura como la cuenta del servicio y no como tú mismo:
runuser -u openvpn -- test -r /etc/openvpn/server/ccd/client1 && echo readableSi la unidad usa chroot, el directorio debe existir dentro de la jaula, y la ruta de la configuración se interpreta después de aplicar el chroot. Un archivo que está en el host fuera de la jaula es invisible desde dentro.
Confirma la búsqueda en lugar de adivinar
Sube el nivel del registro para un reinicio y lee lo que dice el servidor sobre las opciones específicas del cliente. Con verb 4 el demonio informa de la configuración por cliente que ha importado, así que una línea ausente es prueba directa de que no se leyó ningún archivo para esa conexión.
openvpn --config /etc/openvpn/server.conf --verb 4 --client-config-dir /etc/openvpn/server/ccdEjecuta eso en primer plano en un puerto libre y conecta un cliente. Así systemd sale por completo de la ecuación: si las sustituciones aparecen aquí y no bajo el servicio, la diferencia es el contexto de la unidad, no el archivo.
Decide qué debe pasar cuando ningún archivo coincide. Sin ccd-exclusive el cliente se admite solo con los ajustes globales del grupo, y ese es el fallo silencioso descrito antes. Con ella, un archivo ausente se convierte en una conexión rechazada, y ese rechazo es más fácil de ver pero más difícil de depurar bajo carga.
Corrige, reinicia, verifica
Haz el directorio absoluto en la configuración y déjalo así. Las rutas relativas solo son seguras cuando la unidad fija el directorio de trabajo, y fijarlo es una pieza móvil extra que alguien quitará más adelante.
client-config-dir /etc/openvpn/server/ccd
ccd-exclusiveReinicia la instancia, vuelve a conectar un cliente conocido y lee la dirección que recibió junto con las rutas empujadas hacia él. Si la dirección coincide con la línea ifconfig-push del archivo de ese cliente, la búsqueda funcionó. Si el cliente sigue cayendo en el grupo general, vuelve al recuento de líneas del registro: cero importaciones significa que la ruta o la identidad son incorrectas, una importación con contenido equivocado significa que estás editando un archivo distinto del que lee el demonio.
Deshaz restaurando la unidad y la configuración anteriores juntas y luego reinicia. No hace falta reemitir certificados por nada de esto, y tratar un problema de directorio como un problema de credenciales es como un arreglo de cinco minutos se convierte en una ventana de mantenimiento.