O túnel sobe e o cliente liga-se, mas o endereço fixo e as rotas empurradas que definiu para esse único utilizador faltam. O log não diz “file not found”, e é exatamente isso que leva as pessoas a regenerar certificados. Na maioria destes casos o daemon corre a partir de um diretório diferente da shell onde testou, e client-config-dir nunca foi resolvido como assumiu. A correção é uma correção de caminho, não uma reposição de credenciais.

Leia a unidade antes de tocar na configuração

Comece pelo processo que realmente corre, não pelo ficheiro que editou. Pergunte ao systemd pela linha de execução, pelo diretório de trabalho e pela conta para a qual desce. Essas três respostas explicam a maioria das falhas desta classe:

systemctl show openvpn-server@server -p ExecStart -p WorkingDirectory -p User -p RootDirectory

Um WorkingDirectory vazio significa que a unidade arranca em /, por isso um client-config-dir ccd relativo é procurado em /ccd. Esse diretório quase nunca existe, e o daemon não considera a ausência fatal.

Compare com o arranque interativo que usou durante os testes, onde o diretório atual da sua shell era provavelmente o da configuração. O mesmo ficheiro, as mesmas palavras-chave, dois resultados diferentes.

Contra o que é resolvido um caminho relativo

A palavra-chave é resolvida contra o diretório de trabalho do processo no momento em que a opção é usada. Não significa “ao lado do ficheiro de configuração que passei com --config”. O OpenVPN lê de bom grado uma configuração a partir de um caminho absoluto e ainda assim resolve os valores relativos noutro sítio, e é exatamente essa a armadilha. O manual do OpenVPN 2.6 enuncia a regra em --client-config-dir e de novo em --cd.

A palavra-chave cd altera esse contexto antes de outros ficheiros serem lidos, por isso uma unidade que define cd /etc/openvpn/server e depois client-config-dir ccd resolve-se em /etc/openvpn/server/ccd. Se acrescentar cd, verifique a ordem das diretivas e lembre-se de que afeta qualquer outra referência relativa no mesmo ficheiro.

Percorra o caminho como a conta do daemon

Um caminho pode estar correto e continuar ilegível. Depois da queda de privilégios o daemon já não é root, por isso cada diretório pai precisa de permissão de procura para essa conta, e o próprio ficheiro do cliente precisa de permissão de leitura. Basta um bit de execução em falta num pai para esconder o ficheiro, e o erro só se manifesta como um cliente que recebe em silêncio o conjunto predefinido.

O namei imprime a permissão de cada componente por ordem, o que é mais rápido do que verificar os diretórios um a um:

namei -l /etc/openvpn/server/ccd/client1

Depois teste a leitura como a conta do serviço e não como você mesmo:

runuser -u openvpn -- test -r /etc/openvpn/server/ccd/client1 && echo readable

Se a unidade usar chroot, o diretório tem de existir dentro da jaula, e o caminho na configuração é interpretado depois de o chroot ser aplicado. Um ficheiro que está no anfitrião fora da jaula é invisível a partir de dentro.

Confirme a procura em vez de adivinhar

Suba o nível do log para um reinício e leia o que o servidor diz sobre as opções específicas do cliente. Em verb 4 o daemon reporta a configuração por cliente que importou, por isso uma linha ausente é prova direta de que nenhum ficheiro foi lido para essa ligação.

openvpn --config /etc/openvpn/server.conf --verb 4 --client-config-dir /etc/openvpn/server/ccd

Execute isso em primeiro plano numa porta livre e ligue um cliente. Isso retira o systemd completamente da equação: se as substituições aparecerem aqui e não sob o serviço, a diferença é o contexto da unidade, não o ficheiro.

Decida o que deve acontecer quando nenhum ficheiro corresponde. Sem ccd-exclusive o cliente é admitido apenas com as definições globais do conjunto, e essa é a falha silenciosa descrita acima. Com ela, um ficheiro em falta torna-se uma ligação recusada, e essa recusa é mais fácil de notar mas mais difícil de depurar sob carga.

Corrija, reinicie, verifique

Torne o diretório absoluto na configuração e mantenha-o assim. Os caminhos relativos só são seguros quando a unidade fixa o diretório de trabalho, e fixá-lo é uma peça móvel extra que alguém removerá mais tarde.

client-config-dir /etc/openvpn/server/ccd
ccd-exclusive

Reinicie a instância, volte a ligar um cliente conhecido e leia o endereço que recebeu juntamente com as rotas empurradas para ele. Se o endereço corresponder à linha ifconfig-push no ficheiro desse cliente, a procura funcionou. Se o cliente continuar a cair no conjunto geral, volte à contagem de linhas do log: zero importações significa que o caminho ou a identidade estão errados, uma importação com conteúdo errado significa que está a editar um ficheiro diferente do que o daemon lê.

Volte atrás restaurando a unidade e a configuração anteriores em conjunto, e depois reinicie. Os certificados não precisam de ser reemitidos por nada disto, e tratar um problema de diretório como um problema de credenciais é como uma correção de cinco minutos se transforma numa janela de manutenção.

Artigos relacionados