Existe uma maneira típica de passar uma senha para um arquivo da unidade SystemD?

10

Gostaria de iniciar um serviço usando um arquivo de unidade systemd. Este serviço requer uma senha para iniciar. Eu não quero armazenar a senha em texto sem formatação no arquivo de unidade systemd, porque é legível pelo mundo. Também não quero fornecer essa senha interativamente.

Se eu estivesse escrevendo um script normal para isso, armazenaria as credenciais em um arquivo pertencente à raiz com permissões restritas (400 ou 600) e, em seguida, leria o arquivo como parte do script. Existe alguma maneira específica de estilo systemd de fazer isso, ou devo seguir o mesmo processo que faria em um script de shell comum?

SauceCode
fonte

Respostas:

11

Existem duas abordagens possíveis aqui, dependendo dos seus requisitos. Se você não deseja que a senha seja solicitada quando o serviço estiver ativado, use a EnvironmentFilediretiva. De man systemd.exec:

Semelhante ao Ambiente = mas lê as variáveis ​​de ambiente de um arquivo de texto. O arquivo de texto deve conter atribuições de variáveis ​​separadas por nova linha.

Se você não quiser ser solicitado, você usaria uma das systemd-ask-passworddirectivas. De man systemd-ask-password:

systemd-ask-password pode ser usado para consultar uma senha ou frase secreta do sistema do usuário, usando uma mensagem de pergunta especificada na linha de comando. Quando executado a partir de um TTY, ele consulta uma senha no TTY e a imprime na saída padrão. Quando executado sem TTY ou com --no-tty, ele usa o mecanismo de consulta em todo o sistema, que permite que usuários ativos respondam por vários agentes

jasonwryan
fonte
2
Observe que existem falhas na passagem de senhas em variáveis ​​de ambiente (mesmo que o arquivo em que as variáveis ​​estão configuradas esteja protegido), pois geralmente é possível bisbilhotar variáveis ​​de ambiente de processos pertencentes a outros usuários (por exemplo, usando ps ajxewww) para que alguém possa pegue de lá.
Filbranden
Obrigado! EnvironmentFileentrada com um caminho absoluto para um arquivo com 400 permissões funciona bem.
levibostian 09/12/19
@filbranden Você não pode ler variáveis ​​de ambiente de processos pertencentes a outros usuários.
woky
1

Posso oferecer uma alternativa adicional que pode atender às suas necessidades, mas exige que várias pré-condições sejam atendidas:

Os próximos passos são os seguintes:

Use secret-toolfrom libsecretpara armazenar sua senha. Por exemplo:

$ secret-tool store --label=myProgram myService password
Password: <type it here>

Se o seu executável suportar a leitura da senha de uma variável ambiental, é melhor:

[Service]
ExecStart=/usr/bin/sh -c 'env SECRET=$(secret-tool lookup myService password) /usr/bin/script'

Se o seu executável aceitar a senha como argumento, você ainda poderá usar secret-toolo seguinte:

[Service]
ExecStart=/usr/bin/sh -c '/usr/bin/script --secret=$(secret-tool lookup myService password)'

Cuidado : a senha ficará visível quando você executar, systemctl --user status myUnit.servicepois mostra o argumento como sendo executado na linha de comando. Isso significa que isso também será visível para usuários executando topou ps -aux.

Doron Behar
fonte
1

Há uma terceira alternativa para isso, bem como a sugestão 2 de @jasonwryan.

trecho da resposta de Michael Hampton no ServerFault - Como definir variáveis ​​de ambiente no serviço systemd?

A melhor maneira atual de fazer isso é executar systemctl edit myservice, o que criará um arquivo de substituição para você ou permitirá que você edite um existente.

Em instalações normais, isso criará um diretório /etc/systemd/system/myservice.service.de, dentro desse diretório, criará um arquivo cujo nome termina em .conf(normalmente override.conf) e, nesse arquivo, você poderá adicionar ou substituir qualquer parte da unidade enviada pela distribuição.

Por exemplo, em um arquivo /etc/systemd/system/myservice.service.d/myenv.conf:

[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"

Observe também que, se o diretório existir e estiver vazio, seu serviço será desativado! Se você não pretende colocar algo no diretório, verifique se ele não existe.

slm
fonte