PrivateTmp: o hook escreveu o arquivo, mas para onde ele foi?
Um espaço temporário privado esconde o arquivo em vez de excluí-lo. Verifique a raiz do processo antes de alterar a unidade e depois dê um caminho real aos dados compartilhados.
Os hooks relatam sucesso, e o mesmo caminho continua parecendo vazio a partir de um shell. Ambas as afirmações podem ser verdadeiras ao mesmo tempo, porque um serviço systemd pode viver no próprio espaço de nomes de montagem com um diretório temporário privado. Depois de entender isso, a pergunta interessante passa a ser se a escrita chegou a funcionar.
Dois diretórios temporários, um só caminho
A configuração de isolamento dá à unidade uma visão privada dos diretórios temporários em vez de torná-los somente leitura. Processos fora da unidade não conseguem ver o que ela escreve ali, e tudo o que ela deixa para trás é descartado quando a unidade para. Portanto, um caminho impresso pelo hook e um caminho verificado a partir de um shell podem se referir a objetos diferentes com o mesmo nome.
É um problema de visibilidade, e parece um problema de perda de dados. Nada foi excluído, porque o arquivo está simplesmente num espaço de nomes do qual o shell não faz parte. O mesmo comando se comporta de forma diferente quando executado dentro da unidade, e é essa observação que costuma resolver a discussão. Leia as configurações da unidade antes de concluir qualquer coisa sobre a escrita.
Separe o invisível do não gravável
Uma escrita bem-sucedida e uma abertura falha produzem evidências diferentes, e essa distinção decide o reparo. Se o hook diz que o arquivo foi criado mas um leitor externo não o encontra, você tem uma questão de espaço de nomes. Se o hook relata um erro de permissão ou uma abertura falha, o arquivo nunca foi escrito e nenhuma mudança de espaço de nomes ajudará.
systemctl show [email protected] -p PrivateTmp -p User -p Group -p RuntimeDirectory
systemctl show [email protected] -p MainPID --value
sudo ls -l /proc/PID/root/tmp/client-stateO caminho pela raiz do processo expõe a visão do sistema de arquivos do próprio serviço, sujeita às verificações de permissão sobre esse processo enquanto ele ainda está em execução. Leia o journal da unidade na mesma sessão, porque um erro de escrita e um arquivo ausente se confundem facilmente quando alguém já decidiu a causa.
Dê aos dados compartilhados um local explícito
Os dados de que só o serviço precisa pertencem ao seu diretório temporário privado. Os dados que outro processo precisa ler exigem um caminho definido para ambos, com proprietário, modo e validade declarados. Decida qual dos dois casos você tem antes de editar a unidade. A maioria desses incidentes vem de tratar um arquivo privado como compartilhado.
[Service]
RuntimeDirectory=openvpn-hook-office
RuntimeDirectoryMode=0750Um diretório de runtime coloca a pasta sob a área de runtime do sistema, cria-a para o usuário e o grupo configurados da unidade e a remove quando a unidade para. Adicione-o por meio de um drop-in para que a unidade do pacote permaneça intacta, depois recarregue o gerenciador e reinicie essa instância, aceitando que os clientes dela se reconectarão.
Mantenha qualquer diretório de runtime que a unidade já instalada exija. Substituir a lista em vez de acrescentar a ela é uma forma comum de quebrar uma funcionalidade não relacionada que ninguém liga à mudança.
Duas camadas de privilégios podem discordar
O gerenciador de serviços cria o diretório para o usuário configurado da unidade, enquanto o daemon VPN pode descer separadamente para a própria conta antes de executar um hook de conexão. São camadas diferentes, e podem nomear identidades diferentes.
Um diretório pertencente a root com modo restritivo é perfeitamente visível para um daemon que já abriu mão dos privilégios, e ainda assim não é gravável por ele. O erro então é lido como um problema de permissões, embora o caminho exista exatamente onde você esperava. Compare o proprietário do diretório com a identidade relatada pelo hook. Quando diferem, o modo nunca foi a questão.
Verifique a identidade sob a qual o hook realmente é executado antes de mudar a propriedade. Mudar o usuário de execução do serviço para consertar um diretório pode alterar o acesso a dispositivos e os privilégios de rede em outros lugares, o que é um preço alto para um problema pequeno.
Verifique toda a entrega
Confirme quatro coisas ao mesmo tempo: o hook escreve sob sua identidade real, o leitor pretendido consegue consumir o arquivo, usuários não relacionados não conseguem, e parar a unidade limpa conforme o projeto. O aparecimento de um arquivo no diretório temporário compartilhado do host não é um requisito, e normalmente é um sinal de que a troca nunca teve caminho próprio. Teste o leitor após um reinício, não apenas na primeira execução. O comportamento de limpeza faz parte do projeto, portanto observe-o em vez de supor.
O estado persistente pertence a um local com vida útil correspondente, já que um diretório de runtime serve para desaparecer. Escolha o local pela vida útil e não pela conveniência. Esse hábito evita a próxima versão dessa mesma investigação.