Systemd-Dienst nur als bestimmter Benutzer neu starten?

9

Ich habe einige systemd-Dienste erstellt, die im Grunde funktionieren:

Standort:

/etc/systemd/system/multi-user.target.wants/publicapi.service

Inhalt:

[Unit]
Description=public api startup script

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=-/etc/environment
WorkingDirectory=/home/techops
ExecStart=/home/techops/publicapi start
ExecStop=/home/techops/publicapi stop

[Install]
WantedBy=multi-user.target

Wenn ich versuche, den Dienst als Techops-Benutzer in der Befehlszeile neu zu starten, wird folgende Ausgabe angezeigt:

==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'publicapi.service'.
Multiple identities can be used for authentication:
 1.  Myself,,, (defaultuser)
 2.  ,,, (techops)
Choose identity to authenticate as (1-2):

Ich möchte, dass nur Techops Dienste neu starten können, und ich möchte, dass diese Eingabeaufforderung nicht angezeigt wird, wenn Sie als Techops angemeldet sind. Wie kann ich das machen?

Ich habe gelesen, dass es bei Polkit-1 oder Sudoern unterschiedliche Ansätze gibt, bin mir aber nicht sicher.

[UPDATE] 27.01.2019 16:40
Vielen Dank für diese umfassende Antwort an Thomas und Perlduck. Es hat mir geholfen, meine Kenntnisse über systemd zu verbessern.

Entsprechend dem Ansatz, den Dienst ohne Passwortabfrage zu starten, und ich möchte mich entschuldigen, dass ich das eigentliche Problem nicht genug betont habe:

Was für mich am wichtigsten ist, ist, dass kein anderer Benutzer als Techops den Dienst stoppen oder starten sollte. Aber zumindest mit den ersten beiden Ansätzen kann ich noch laufen service publicapi stopund bekomme die Aufforderung ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===erneut. Wenn ich den Standardbenutzer auswähle und das Kennwort kenne, kann ich alle Dienste beenden. Ich möchte diesem Benutzer dies verweigern, auch wenn er das Passwort hat . Wichtige Hintergrundinformationen, um besser zu verstehen, warum dies für mich der wichtigere Teil ist:
Der Standardbenutzer ist der einzige Benutzer, der ssh ausgesetzt ist, aber dieser Benutzer kann nichts anderes tun (außer zu anderen Benutzern zu wechseln, wenn Sie das Kennwort dieser anderen Benutzer haben). . Im Moment kann er die Dienste starten oder stoppen, aber dieser Benutzer darf dies nicht tun.
Wenn jemand das Passwort des Standardbenutzers erhält und sich über ssh anmeldet, kann er momentan alle Dienste beenden. Dies meinte ich mit "Ich möchte, dass nur Techniker Dienste neu starten können". Entschuldigung, dass ich bei meiner ersten Frage nicht so genau war. Ich dachte, dass das Sudoing des Techops-Benutzers dieses Problem vielleicht umgehen würde, aber das tut es nicht. Das Problem selbst besteht nicht darin, den Befehl ohne Kennwortabfrage auszuführen. (Ich könnte das leicht als Techops-Benutzer tun, wenn ich es gerade ausführe /home/techops/publicapi start). Das Problem selbst besteht darin, den Standardbenutzer vom Starten dieser Dienste auszuschließen.

Und ich hoffte, dass jede der Lösungen das könnte.

Ich begann mit den Ansätzen von Thomas. Der Ansatz mit sudo funktioniert, wenn ich nicht nach dem Kennwort für die Benutzer-Techops gefragt werden möchte, wenn ich die Befehle wie erläutert ausführe, z

sudo systemctl start publicapi.service
sudo systemctl stop publicapi.service

Der zweite Ansatz funktioniert bei mir noch nicht. Ich kann den Dienst nicht ohne Passwortabfrage starten ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===und kann mich als Standardbenutzer anmelden, wenn ich das Passwort dieses Benutzers habe.

Mit dem dritten Ansatz startet der Dienst nicht einmal mehr beim Booten, daher bin ich mir nicht sicher, ob dieser Ansatz überhaupt der richtige für mich ist. Ich kann es nicht einmal, systemctl enable publicapi.servicewas mich zu folgendem Fehler führt:

Failed to enable unit: Unit file mycuisine-publicapi.service does not exist.

Der Fehler tritt nicht auf, wenn ich alle Dienste zurück in / etc / systemd / system / verschiebe und ausführe systemctl enable publicapi.service. Dann startet der Dienst beim Booten erneut.

All diese Ansätze helfen mehr oder weniger dabei, die Kennwortabfrage für den Techops-Benutzer zu umgehen. Wenn ich sie jedoch ausführe service publicapi stopoder systemctl stop publicapi mit dem Standardbenutzer, kann ich die Dienste beenden, wenn ich das Kennwort habe. Mein Ziel ist es jedoch, den Standardbenutzer daran zu hindern, Dienste überhaupt zu starten oder zu stoppen.

Bevor
quelle
1
Für den dritten Ansatz müssen Sie systemctl --user ...als Benutzer und techopsnicht als Root ausgeführt werden. Weder mein Vorschlag noch der von @PerlDuck gewähren sudoIhrem Standardbenutzer Rechte, sondern nur dem Techops- Benutzer.
Thomas
1
Ist der Standardbenutzer als sudo konfiguriert? In diesem Fall sollten Sie den Benutzer aus sekundären Gruppen entfernen und Ihre /etc/sudoersDatei überprüfen , ob für diesen Benutzer eine Referenz vorhanden ist.
Thomas
@ Thomas Ah, das war's. Es funktioniert jetzt wie erwartet. Vielen Dank.
Bevor

Antworten:

17

Um zu erreichen, dass der Benutzer techopsden Dienst publicapi.serviceohne Angabe eines Passworts steuern kann , haben Sie verschiedene Möglichkeiten. Welches für Sie geeignet ist, kann nicht beantwortet werden, da Sie selbst wählen müssen.


Der klassische sudoAnsatz wird vielleicht am häufigsten verwendet, da er schon lange existiert. Sie müssten zB die Datei wie folgt erstellen.
Beachten Sie, dass das Drop-In-Verzeichnis /etc/sudoers.dnur aktiv ist, wenn #includedir /etc/sudoers.des aktiviert ist /etc/sudoers. Dies sollte jedoch der Fall sein, wenn Sie eine moderne Ubuntu-Distribution verwenden. Wie rootausführen:

cat > /etc/sudoers.d/techops << SUDO
techops ALL= NOPASSWD: /bin/systemctl restart publicapi.service
techops ALL= NOPASSWD: /bin/systemctl stop publicapi.service
techops ALL= NOPASSWD: /bin/systemctl start publicapi.service
SUDO

Jetzt sollten Sie in der Lage sein, die systemctlBefehle als Benutzer auszuführen, techopsohne ein Kennwort anzugeben sudo, indem Sie den Befehlen voranstellen .

sudo systemctl start publicapi.service
sudo systemctl stop publicapi.service
sudo systemctl restart publicapi.service

Die zweite Methode wäre die Verwendung von PolKit (wurde von PolicyKit umbenannt ), damit der Benutzer Dienste techopssteuern kann systemd. Abhängig von der Version von politkönnen Sie normalen Benutzern die Kontrolle über systemd-Einheiten geben.
Um die Polkit- Version zu überprüfen , führen Sie einfach aus pkaction --version.

  • Mit Polkit Version 0.106 und höher können Benutzer bestimmte Systemeinheiten steuern.
    Dazu können Sie eine Regel erstellen als root:

    cat > /etc/polkit-1/rules.d/10-techops.rules << POLKIT
    polkit.addRule(function(action, subject) {
        if (action.id == "org.freedesktop.systemd1.manage-units" &&
            action.lookup("unit") == "publicapi.service" &&
            subject.user == "techops") {
            return polkit.Result.YES;
        }
    });
    POLKIT
    
  • mit polkit version 0.105 und niedriger : Sie können Benutzern erlauben, systemd-Einheiten zu steuern. Dies schließt leider alle systemd-Einheiten ein, und Sie möchten dies möglicherweise nicht tun. Ich bin mir nicht sicher, ob es eine Möglichkeit gibt, den Zugriff auf bestimmte Systemeinheiten mit Version 0.105 oder niedriger zu beschränken, aber möglicherweise kann dies jemand anderes klären.
    Um dies zu aktivieren, können Sie eine Datei erstellen als root:

    cat > /etc/polkit-1/localauthority/50-local.d/org.freedesktop.systemd1.pkla << POLKIT
    [Allow user techops to run systemctl commands]
    Identity=unix-user:techops
    Action=org.freedesktop.systemd1.manage-units
    ResultInactive=no
    ResultActive=no
    ResultAny=yes
    POLKIT
    

In beiden Fällen können Sie systemctl [start|stop|restart] publicapi.serviceals Benutzer techopsohne Angabe eines Kennworts ausgeführt werden. Im letzteren Fall (polkit <= 0,105) kann der Benutzer techopsjede Systemeinheit steuern.


Eine dritte Option wäre, den Dienst zu einem Benutzerdienst zu machen, der keine Konfigurationen benötigt sudooder benötigt polkit. Dies stellt alles unter die Kontrolle des Benutzers und funktioniert nur, wenn Ihr tatsächlicher Dienst, mit dem gestartet /home/techops/publicapi startwird, ohne rootBerechtigungen ausgeführt werden kann.

Zuerst müssen Sie das Verweilen für den Benutzer aktivieren techops. Dies ist erforderlich, um den Benutzerdienst beim Booten zu starten. Wie rootausführen:

loginctl enable-linger techops

Als nächstes müssen Sie die systemdGerätedatei in das techopsBenutzerverzeichnis verschieben. techopsFühren Sie als Benutzer die Befehle wie folgt aus.

mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/publicapi.service << UNIT
[Unit]
Description=public api startup script

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=-/etc/environment
WorkingDirectory=/home/techops
ExecStart=/home/techops/publicapi start
ExecStop=/home/techops/publicapi stop

[Install]
WantedBy=default.target
UNIT

Beachten Sie, dass das so sein WantedBymuss, default.targetwie es multi-user.targetim Benutzerkontext kein gibt .

Laden Sie nun die Konfiguration neu und aktivieren Sie den Dienst. techopsFühren Sie die Befehle erneut als Benutzer aus .

systemctl --user daemon-reload
systemctl --user enable publicapi.service
systemctl --user start publicapi.service

Im Allgemeinen sollten Sie Ihre systemd-Einheiten /etc/systemd/system/nicht direkt in platzieren /etc/systemd/system/multi-user.target.wants. Wenn Sie ausführen, wird systemctl enable publicapi.serviceeine symbolische Verknüpfung in etc/systemd/system/multi-user.target.wantsoder einem für diese Einheit angegebenen Ziel erstellt .

Wie bereits erwähnt, sollten Sie in Betracht ziehen User=techops, Ihrer Einheitendatei etwas hinzuzufügen , um den Prozess mit einem nicht privilegierten Benutzerkonto auszuführen , wenn der Dienst / Prozess selbst ohne Root-Rechte ausgeführt werden kann .

Thomas
quelle
Sehr gut. Sie haben sogar an das unterschiedliche WantedBy-Ziel für Benutzereinheiten gedacht. Offensichtlich ist dies nicht die erste Einheitendatei, die Sie geschrieben haben :-)
PerlDuck
Panzer @PerlDuck. = 0)
Thomas
Danke für deine Antwort. Dies beantwortet teilweise meine Frage, aber ich habe immer noch mein anfängliches Problem. (Ich habe die Frage aktualisiert)
Bevor
Entschuldigung, das .pklafunktioniert nicht. Dies benötigt einen [section]Eintrag. Antwort aktualisiert.
Thomas
5

Zunächst legen Sie keine Einheitendatei in das Verzeichnis /etc/systemd/system/multi-user.target.wants. Dieses Verzeichnis wird von systemdund den systemctlBefehlen verwaltet. Legen Sie /etc/systemd/systemstattdessen die Gerätedatei ein und aktivieren Sie sie mit

sudo systemctl enable publicapi.service

Dadurch wird unten ein Symlink erstellt multi-user.target.wants(oder wo immer, systemctlweiß es besser), um die Zeilen zu berücksichtigen

[Install]
WantedBy=multi-user.target

in der Einheit.

Erstellen Sie als Nächstes eine sudoersDatei /etc/sudoers.d:

sudo visudo -f /etc/sudoers.d/techops

mit folgendem Inhalt:

Cmnd_Alias HANDLE_PUBLICAPI = \
    /bin/systemctl start   publicapi.service \
    /bin/systemctl stop    publicapi.service \
    /bin/systemctl restart publicapi.service

techops ALL = (root) NOPASSWD: HANDLE_PUBLICAPI

Verwenden Sie keinen regulären Editor (z. B. sudo vim /etc/sudoers.d/techops), um diese Datei zu bearbeiten, da Sie sie nicht sudoerneut ausführen können, wenn Sie Syntaxfehler einfügen . visudoÜberprüfen Sie andererseits die Syntax der Datei, bevor Sie den Editor verlassen.

Jetzt kann der Benutzer techopsausführen

sudo systemctl start publicapi.service

und die anderen beiden ohne Angabe eines Passworts. Beachten Sie, dass Sie den Befehl und die Parameter genau wie in der sudoersDatei angegeben eingeben müssen (mit Ausnahme des /bin/systemctlTeils, der auf nur gekürzt werden kann systemctl).

Zum Beispiel würde sudo /bin/systemctl start publicapi(ohne .service) nach einem Passwort fragen.

PerlDuck
quelle