Existe-t-il un moyen typique de transmettre un mot de passe à un fichier Systemd Unit?

10

Je voudrais démarrer un service en utilisant un fichier d'unité systemd. Ce service nécessite un mot de passe pour démarrer. Je ne veux pas stocker le mot de passe en clair dans le fichier d'unité systemd, car il est lisible par tout le monde. Je ne veux pas non plus fournir ce mot de passe de manière interactive.

Si j'écrivais un script normal pour cela, je stockerais les informations d'identification dans un fichier appartenant à root avec des autorisations restreintes (400 ou 600), puis lirais le fichier dans le cadre du script. Existe-t-il un moyen particulier de style systemd pour ce faire, ou dois-je simplement suivre le même processus que je le ferais dans un script shell normal?

SauceCode
la source

Réponses:

11

Il existe deux approches possibles ici, selon vos besoins. Si vous ne souhaitez pas être invité à entrer le mot de passe lorsque le service est activé, utilisez la EnvironmentFiledirective. De man systemd.exec:

Similaire à Environment = mais lit les variables d'environnement à partir d'un fichier texte. Le fichier texte doit contenir des affectations de variables séparées par une nouvelle ligne.

Si vous ne souhaitez être invité, vous devez utiliser l' une des systemd-ask-passworddirectives. De man systemd-ask-password:

systemd-ask-password peut être utilisé pour interroger un mot de passe système ou une phrase secrète de l'utilisateur, à l'aide d'un message de question spécifié sur la ligne de commande. Lorsqu'il est exécuté à partir d'un TTY, il interroge un mot de passe sur le TTY et l'imprime sur la sortie standard. Lorsqu'il est exécuté sans TTY ou avec --no-tty, il utilisera le mécanisme de requête à l'échelle du système, qui permet aux utilisateurs actifs de répondre via plusieurs agents

jasonwryan
la source
2
Notez qu'il y a des inconvénients à passer des mots de passe dans les variables d'environnement (même si le fichier dans lequel les variables sont définies est protégé), car il est généralement possible de fouiner dans les variables d'environnement des processus appartenant à d'autres utilisateurs (par exemple, en utilisant ps ajxewww) pour que quelqu'un puisse ramasser à partir de là.
filbranden
Merci! EnvironmentFilel'entrée avec un chemin absolu vers un fichier avec 400 autorisations fonctionne bien.
lévibostian
@filbranden Vous ne pouvez pas lire les variables d'environnement des processus appartenant à d'autres utilisateurs.
woky
1

Je peux vous proposer une alternative supplémentaire qui peut convenir à vos besoins mais qui nécessite plusieurs conditions préalables:

Les étapes suivantes sont les suivantes:

Utilisez secret-toolfrom libsecretpour enregistrer votre mot de passe. Par exemple:

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

Si votre exécutable prend en charge la lecture du mot de passe à partir d'une variable d'environnement, il vaut mieux:

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

Si votre exécutable accepte le mot de passe comme argument, vous pouvez toujours l'utiliser secret-toolcomme ceci:

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

Attention : le mot de passe sera bien visible lors de votre exécution systemctl --user status myUnit.servicecar il montre que l'argument est exécuté sur la ligne de commande. Cela signifie que cela sera également visible pour les utilisateurs exécutant topou ps -aux.

Doron Behar
la source
1

Il y a une troisième alternative à cela ainsi que la suggestion de @jasonwryan.

extrait de la réponse de Michael Hampton à ServerFault - Comment définir la variable d'environnement dans le service systemd?

La meilleure façon actuelle de le faire est d'exécuter systemctl edit myservice, ce qui créera un fichier de remplacement pour vous ou vous permettra de modifier un fichier existant.

Dans les installations normales, cela créera un répertoire /etc/systemd/system/myservice.service.d, et à l'intérieur de ce répertoire, créera un fichier dont le nom se termine .conf(généralement override.conf), et dans ce fichier, vous pouvez ajouter ou remplacer n'importe quelle partie de l'unité livrée par la distribution.

Par exemple, dans un fichier /etc/systemd/system/myservice.service.d/myenv.conf:

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

Notez également que si le répertoire existe et est vide, votre service sera désactivé! Si vous n'avez pas l'intention de mettre quelque chose dans le répertoire, assurez-vous qu'il n'existe pas.

slm
la source