Gibt es eine typische Möglichkeit, ein Kennwort an eine Systemd Unit-Datei zu übergeben?

10

Ich möchte einen Dienst mit einer systemd-Einheitendatei starten. Für diesen Dienst ist zum Starten ein Kennwort erforderlich. Ich möchte das Passwort nicht im Klartext in der systemd-Einheitendatei speichern, da es weltweit lesbar ist. Ich möchte dieses Passwort auch nicht interaktiv bereitstellen.

Wenn ich dafür ein normales Skript schreiben würde, würde ich die Anmeldeinformationen in einer Datei speichern, die root mit eingeschränkten Berechtigungen gehört (400 oder 600), und dann die Datei als Teil des Skripts lesen. Gibt es eine bestimmte systemd-artige Möglichkeit, dies zu tun, oder sollte ich einfach den gleichen Prozess wie in einem normalen Shell-Skript ausführen?

SauceCode
quelle

Antworten:

11

Abhängig von Ihren Anforderungen gibt es hier zwei mögliche Ansätze. Wenn Sie bei Aktivierung des Dienstes nicht zur Eingabe des Kennworts aufgefordert werden möchten, verwenden Sie die EnvironmentFileAnweisung. Von man systemd.exec:

Ähnlich wie Environment =, liest jedoch die Umgebungsvariablen aus einer Textdatei. Die Textdatei sollte durch neue Zeilen getrennte Variablenzuweisungen enthalten.

Wenn Sie dazu aufgefordert werden möchten, verwenden Sie eine der systemd-ask-passwordAnweisungen. Von man systemd-ask-password:

systemd-ask-password kann verwendet werden, um ein Systemkennwort oder eine Passphrase vom Benutzer mithilfe einer in der Befehlszeile angegebenen Fragennachricht abzufragen. Wenn es von einem TTY ausgeführt wird, fragt es ein Kennwort auf dem TTY ab und druckt es in der Standardausgabe aus. Bei Ausführung ohne TTY oder mit --no-tty wird der systemweite Abfragemechanismus verwendet, mit dem aktive Benutzer über mehrere Agenten antworten können

Jasonwryan
quelle
2
Beachten Sie, dass die Übergabe von Kennwörtern in Umgebungsvariablen Mängel aufweist (selbst wenn die Datei, in der die Variablen festgelegt sind, geschützt ist), da es normalerweise möglich ist, Umgebungsvariablen von Prozessen anderer Benutzer zu durchsuchen (z. B. mithilfe von ps ajxewww), sodass möglicherweise jemand dazu in der Lage ist nimm es von dort auf.
Filbranden
Vielen Dank! EnvironmentFileDer Eintrag mit einem absoluten Pfad zu einer Datei mit 400 Berechtigungen funktioniert gut.
Levibostian
@filbranden Sie können keine Umgebungsvariablen von Prozessen lesen, die anderen Benutzern gehören.
woky
1

Ich kann eine zusätzliche Alternative anbieten, die Ihren Anforderungen entspricht, für die jedoch mehrere Voraussetzungen erfüllt sein müssen:

Die nächsten Schritte sind wie folgt:

Verwenden Sie secret-toolvon libsecret, um Ihr Passwort zu speichern. Zum Beispiel:

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

Wenn Ihre ausführbare Datei das Lesen des Kennworts aus einer Umgebungsvariablen unterstützt, ist es besser:

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

Wenn Ihre ausführbare Datei das Kennwort als Argument akzeptiert, können Sie dennoch Folgendes verwenden secret-tool:

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

Achtung : Das Kennwort ist beim Ausführen deutlich sichtbar, systemctl --user status myUnit.serviceda das Argument in der Befehlszeile ausgeführt wird. Dies bedeutet, dass dies auch für Benutzer sichtbar ist, die topoder ausführen ps -aux.

Doron Behar
quelle
1

Es gibt eine dritte Alternative dazu sowie den 2 Vorschlag von @jasonwryan.

Auszug aus der Antwort von Michael Hampton bei ServerFault - Wie wird die Umgebungsvariable im systemd-Dienst festgelegt?

Der derzeit beste Weg, dies zu tun, ist das Ausführen systemctl edit myservice, wodurch eine Überschreibungsdatei für Sie erstellt oder Sie eine vorhandene bearbeiten können.

Bei normalen Installationen wird ein Verzeichnis erstellt /etc/systemd/system/myservice.service.d, und in diesem Verzeichnis wird eine Datei erstellt, deren Name .conf(normalerweise override.conf) endet. In dieser Datei können Sie einen beliebigen Teil der von der Distribution gelieferten Einheit hinzufügen oder überschreiben.

Zum Beispiel in einer Datei /etc/systemd/system/myservice.service.d/myenv.conf:

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

Beachten Sie auch, dass Ihr Dienst deaktiviert wird, wenn das Verzeichnis vorhanden und leer ist! Wenn Sie nicht beabsichtigen, etwas in das Verzeichnis aufzunehmen, stellen Sie sicher, dass es nicht vorhanden ist.

slm
quelle