O servizo arrinca, le o perfil sen queixarse e despois morre nunha liña que parece non ter relación: non pode abrir ca.crt. Nada do certificado cambiou, e a ruta do perfil na unidade é absoluta. Esa combinación é a pista. A ruta que pasou localiza un ficheiro, e os nomes dentro dese ficheiro resólvense noutro lugar por completo, así que unha execución que parece plenamente cualificada pode seguir lendo as súas chaves desde un directorio que ninguén pretendía.

O fallo ten poucas causas, e cómpre separalas por orde: o directorio base que o proceso tiña en realidade, o contexto de execución do servizo e os permisos ou o sandbox arredor do ficheiro unha vez que a ruta é correcta. Cada unha deixa un rastro distinto: na unidade, no proceso e no sistema de ficheiros.

A ruta do perfil non é un directorio base

Imagine un proceso que arrinca en /tmp e recibe /etc/vpn/prod/tenant-a.ovpn. Dentro dese perfil, a liña ca ca.crt nomea unha ruta relativa. Nada no argumento que localizou o perfil reescribe ese nome, así que o proceso busca /tmp/ca.crt e informa dun ficheiro que falta.

O confuso é a orde dos erros. OpenVPN analiza primeiro a configuración e abre os ficheiros referenciados a medida que chega a eles, así que unha errata no perfil infórmase antes de tocar ningunha chave, mentres que un certificado ausente só aparece cando a análise chega ata alí. Polo tanto, un perfil que carga é proba de que a sintaxe é correcta, non de que se atopasen os ficheiros que nomea.

Que separa o manual: --config e --cd

O manual de OpenVPN 2.6 describe dúas opcións distintas. Unha carga un ficheiro de configuración. A outra cambia o directorio do proceso antes de que se lean a configuración, a chave, o script e outros ficheiros, e esixe un directorio absoluto sen referencia ao actual.

openvpn --cd /etc/vpn/prod --config tenant-a.ovpn

Esa invocación é unha forma, non unha instrución para lanzar o perfil doutro. O que achega é determinismo: a base de cada nome relativo da cadea declárase na orde en lugar de herdarse da shell ou do xestor que inicie o proceso. A alternativa é igual de válida e a miúdo mellor para un servizo: deixe o directorio de traballo en paz e faga absoluto cada ficheiro referenciado dentro do perfil.

Escolla o que escolla, audite toda a cadea e non o primeiro fallo. Un perfil pode incorporar outro ficheiro de configuración, e os nomes relativos do ficheiro incluído resólvense contra o mesmo directorio do proceso, non contra o directorio do ficheiro que os incluíu. As rutas de rexistro, os ficheiros de autenticación e os scripts auxiliares seguen a mesma regra.

O servizo arrinca noutro sitio

Unha shell interactiva no directorio do perfil non demostra nada sobre unha unidade empaquetada. Os xestores fixan o seu propio directorio de traballo, e un script envoltorio pode volvelo cambiar antes de que se execute o binario. A unidade que falla é a única execución sobre a que paga a pena razoar.

systemctl show -p WorkingDirectory -p ExecStart --value openvpn@tenant-a
ls -l /proc/$(pgrep -n openvpn)/cwd

A segunda orde mostra o directorio que o proceso vivo mantén en realidade, algo máis fiable que o ficheiro da unidade cando hai un envoltorio. Se ambos non coinciden, o envoltorio é a súa resposta e a unidade é unha pista falsa.

Tras a busca: permisos, chroot e sandbox

Un directorio base correcto pode producir igualmente a mesma mensaxe, porque resolución e acceso son pasos separados. O proceso necesita permiso de execución en cada directorio pai e permiso de lectura no ficheiro, e unha unidade de servizo que oculta parte do sistema de ficheiros cambia o que o proceso pode ver sequera.

Tres variantes habituais producen o mesmo erro. O ficheiro só é lexible por root mentres o servizo cede privilexios antes de abrilo. A unidade establece unha vista protectora do sistema de ficheiros que non inclúe o directorio do perfil. O demonio execútase con chroot, así que a ruta que existe no host non existe dentro desa vista.

Diagnostique coa propiedade do ficheiro e a identidade do proceso, non afrouxando permisos. Facer que unha chave privada sexa lexible por todos para calar este erro cambia un fallo ruidoso por un silencioso, e a chave é a parte do directorio que menos desexa expor.

Demostre a corrección coa execución propia

Reinicie a unidade real desde un directorio sen relación co perfil e observe a mesma liña de arrinque. Despois confirme que o proceso mantén o directorio previsto mentres se executa e que o certificado que cargou é o que espera.

systemctl restart openvpn@tenant-a
systemctl status openvpn@tenant-a --no-pager
journalctl -u openvpn@tenant-a -n 20 --no-pager

Cando a carga de rutas ten éxito, a autenticación e o encamiñamento seguen sendo etapas separadas cos seus propios fallos, e unha conexión que sobe pero non pasa tráfico é outra investigación. A corrección de aquí só trata de de que directorio viñeron os ficheiros, e debería verse na invocación en lugar de lembrala quen a executou a man a última vez.

Se o perfil se despregue cun xestor de configuración, poña tamén alí o directorio base ou os nomes absolutos dos ficheiros. Unha corrección manual nun só host é a versión deste problema que volve tras a seguinte reconstrución.

Artigos relacionados