Riavvio del servizio systemd solo come utente specifico?


9

Ho creato alcuni servizi systemd che sostanzialmente funzionano:

Posizione:

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

soddisfare:

[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

Quando provo a riavviare il servizio come utente techops nella riga di comando, ottengo il seguente output:

==== 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):

Voglio che solo i techops possano riavviare i servizi e voglio che questo prompt non appaia quando si accede come techops. Come lo posso fare?

Ho letto che esistono diversi approcci con polkit-1 o sudoers, ma non sono sicuro.

[AGGIORNAMENTO] 27-01-2019 16:40
Grazie per questa risposta esauriente a Thomas e Perlduck. Mi ha aiutato a migliorare la mia conoscenza di systemd.

Secondo l'approccio per avviare il servizio senza la richiesta di password, e desidero scusarmi per non aver sottolineato abbastanza il vero problema:

In realtà, ciò che è più importante per me è che nessun altro utente oltre a Techops dovrebbe interrompere o avviare il servizio. Ma almeno con i primi due approcci posso ancora eseguire service publicapi stope ricevo di ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===nuovo il prompt . Quando scelgo l'utente predefinito e conosco la password, potrei interrompere tutti i servizi. Voglio negare a questo utente di farlo, anche se ha la password . Informazioni di base importanti per capire meglio perché questa è la parte più importante per me:
l'utente predefinito è l'unico utente che è esposto a SSH ma questo utente non può fare nient'altro (tranne cambiare ad altri utenti se si dispone della password di questi altri utenti) . Ma al momento, può avviare o interrompere i servizi, ma questo utente non deve farlo.
Se qualcuno ottiene la password di defaultuser e accede tramite ssh, al momento potrebbe interrompere tutti i servizi. Questo è ciò che intendevo con "Voglio che solo i tecnici possano riavviare i servizi". Mi dispiace, non ero così preciso alla mia domanda iniziale. Ho pensato che il superamento dell'utente di techops avrebbe potuto aggirare questo problema, ma non è così. Il problema stesso non è quello di eseguire il comando senza la richiesta della password. (Potrei facilmente farlo come utente techops quando eseguo solo /home/techops/publicapi start). Il problema stesso è bloccare l'utente predefinito dall'avvio di questi servizi.

E speravo che una qualsiasi delle soluzioni potesse farlo.

Ho iniziato con gli approcci di Thomas. L'approccio con sudo funziona quando non voglio che mi venga chiesta la password per l'utente tecnico quando eseguo i comandi come spiegato, ad es.

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

Il secondo approccio non funziona ancora per me. Non riesco ad avviare il servizio senza la richiesta della password ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===e posso accedere come utente predefinito quando ho la password di questo utente.

Con il terzo approccio, il servizio non si avvia più nemmeno al processo di avvio, quindi non sono sicuro che questo approccio sia quello giusto per me. Non riesco nemmeno a farlo con ciò systemctl enable publicapi.serviceche mi porta al seguente errore:

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

L'errore non si verifica quando sposto nuovamente tutti i servizi in / etc / systemd / system / ed eseguo systemctl enable publicapi.service. Quindi il servizio si riavvia all'avvio.

Tutti questi approcci aiuteranno più o meno a bypassare la richiesta della password per l'utente techops ma quando corro service publicapi stopo systemctl stop publicapi con defaultuser, posso interrompere i servizi se ho la password. Ma il mio obiettivo è bloccare defaultuser dall'avvio o dall'arresto dei servizi.


1
Per il terzo approccio devi eseguire systemctl --user ...come utente techopsnon come root. Né il mio suggerimento né quello di @PerlDuck danno alcun sudodiritto all'utente predefinito, ma solo all'utente tecnico .
Thomas

1
L'utente predefinito è configurato come sudo? In tal caso, è necessario rimuovere l'utente dai gruppi secondari e controllare il /etc/sudoersfile se esiste un riferimento per quell'utente.
Thomas

@Thomas Ah, tutto qui. Funziona come previsto ora. Grazie.
Bevor

Risposte:


17

Per ottenere che l'utente techopspossa controllare il servizio publicapi.servicesenza fornire una password, hai diverse possibilità. Non è possibile rispondere a quale è adatto a te poiché devi scegliere da solo.


L' sudoapproccio classico è forse il più utilizzato, poiché esiste da molto tempo. Dovresti creare ad esempio il file come segue.
Si noti che la directory di destinazione /etc/sudoers.dè attiva solo quando #includedir /etc/sudoers.dè impostata /etc/sudoers. Ma questo dovrebbe essere il caso se stai usando una moderna distribuzione Ubuntu. Come rooteseguire:

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

Ora dovresti essere in grado di eseguire i systemctlcomandi come utente techopssenza fornire una password anteponendo sudoai comandi.

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

Il secondo metodo sarebbe utilizzare PolKit (è stato rinominato da PolicyKit ) per consentire all'utente techopsdi controllare i systemdservizi. A seconda della versione di polit, è possibile fornire agli utenti normali il controllo sulle unità di sistema.
Per verificare la versione di Polkit , basta eseguire pkaction --version.

  • con la versione 0.106 di polkit e successive , è possibile consentire agli utenti di controllare specifiche unità di sistema.
    Per fare ciò, è possibile creare una regola come 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
    
  • con Polkit versione 0.105 e precedenti : è possibile consentire agli utenti di controllare le unità di sistema. Questo sfortunatamente include tutte le unità di sistema e potresti non volerlo fare. Non sono sicuro se esiste un modo per limitare l'accesso a unità di sistema specifiche con la versione 0.105 o precedente, ma forse qualcun altro può chiarire.
    Per abilitarlo, è possibile creare un file come 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 entrambi i casi è possibile eseguire systemctl [start|stop|restart] publicapi.servicecome utente techopssenza fornire una password. In quest'ultimo caso (polkit <= 0.105) l'utente techopspuò controllare qualsiasi unità systemd.


Una terza opzione sarebbe quella di rendere il servizio un servizio utente, che non necessita sudoo polkitconfigurazioni. Ciò mette tutto sotto il controllo dell'utente e funziona solo se il servizio effettivo che viene avviato /home/techops/publicapi startpuò essere eseguito senza rootprivilegi.

Per prima cosa devi abilitare la permanenza per l'utente techops. Ciò è necessario per avviare il servizio utente all'avvio. Come rooteseguire:

loginctl enable-linger techops

Successivamente devi spostare il systemdfile dell'unità nella techopsdirectory dell'utente. Come utente techopseseguire i comandi come segue.

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

Si noti che WantedBydeve essere default.targetcome non esiste multi-user.targetnel contesto dell'utente.

Ora ricaricare la configurazione e abilitare il servizio. Ancora una volta mentre l'utente techopsesegue i comandi.

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

In generale dovresti posizionare le tue unità di sistema /etc/systemd/system/non direttamente dentro /etc/systemd/system/multi-user.target.wants. Quando si esegue, systemctl enable publicapi.serviceverrà creato un collegamento simbolico etc/systemd/system/multi-user.target.wantso qualsiasi destinazione specificata per quell'unità.

Come già accennato, se il servizio / processo stesso può essere eseguito senza i privilegi di root, è consigliabile aggiungere User=techopsal file dell'unità per eseguire il processo con un account utente non privilegiato.


Molto bene. Hai persino pensato al diverso target WantedBy per le unità utente. Ovviamente, questo non è il primo file di unità che hai scritto :-)
PerlDuck,

Tanks @PerlDuck. = 0)
Thomas,

Grazie per la tua risposta. Questo in parte risponde alla mia domanda, ma ho ancora il mio problema iniziale. (Ho aggiornato la domanda)
Bevor

Ci dispiace, per .pklanon aver funzionato. Questo ha bisogno di una [section]voce. Risposta aggiornata.
Thomas

5

Prima di tutto, non inserire un file di unità nella directory /etc/systemd/system/multi-user.target.wants. Questa directory è gestita da systemde dai systemctlcomandi. Inserire invece il file dell'unità /etc/systemd/systeme quindi abilitarlo con

sudo systemctl enable publicapi.service

Questo creerà un link simbolico di seguito multi-user.target.wants(o ovunque, lo systemctlsa meglio) per onorare le linee

[Install]
WantedBy=multi-user.target

nell'unità.

Quindi, crea un sudoersfile qui sotto /etc/sudoers.d:

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

con il seguente contenuto:

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

Non utilizzare un normale editor (ad es. sudo vim /etc/sudoers.d/techops) Per modificare quel file perché se si inseriscono errori di sintassi non sarà possibile eseguirlo sudonuovamente. visudod'altra parte controlla la sintassi del file prima di uscire dall'editor.

Ora l'utente techopspuò eseguire

sudo systemctl start publicapi.service

e gli altri due senza fornire una password. Si noti che è necessario digitare il comando e i parametri esattamente come indicato nel sudoersfile (ad eccezione della /bin/systemctlparte che può essere abbreviata in appena systemctl).

Ad esempio, sudo /bin/systemctl start publicapi(senza .service) chiedere una password.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.