¿Reiniciar el servicio systemd solo como un usuario específico?

9

Creé algunos servicios systemd que básicamente funcionan:

ubicación:

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

contenido:

[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

Cuando intento reiniciar el servicio como usuario de techops en la línea de comando, obtengo el siguiente resultado:

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

Quiero que solo los técnicos puedan reiniciar los servicios y quiero que este mensaje no aparezca al iniciar sesión como técnicos. ¿Cómo puedo hacer eso?

Leí que hay diferentes enfoques con polkit-1 o sudoers, pero no estoy seguro.

[ACTUALIZACIÓN] 2019-01-27 4:40 pm
Gracias por esta respuesta integral a Thomas y Perlduck. Me ayudó a mejorar mi conocimiento de systemd.

De acuerdo con el enfoque para iniciar el servicio sin una solicitud de contraseña, y quiero disculparme por no haber enfatizado el problema real lo suficiente:

En realidad, lo más importante para mí es que ningún otro usuario que Techops debe detener o iniciar el servicio. Pero al menos con los dos primeros enfoques todavía puedo ejecutar service publicapi stopy recibo el mensaje ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===nuevamente. Cuando elijo el usuario predeterminado y conozco la contraseña, podría detener todos los servicios. Quiero negarle a este usuario que haga eso, incluso si tiene la contraseña . Información de fondo importante para comprender mejor por qué esta es la parte más importante para mí:
el usuario predeterminado es el único usuario que está expuesto a ssh, pero este usuario no puede hacer nada más (excepto cambiar a otros usuarios si tiene la contraseña de estos otros usuarios) . Pero por el momento, puede iniciar o detener los servicios, pero este usuario no debe hacerlo.
Si alguien obtiene la contraseña del usuario predeterminado e inicia sesión a través de ssh, entonces podría detener todos los servicios en este momento. Esto es lo que quise decir con "Quiero que solo los técnicos puedan reiniciar los servicios". Lo siento, no fui tan exacto en mi pregunta inicial. Pensé que suudir al usuario de Techops podría evitar este problema, pero no es así. El problema en sí mismo no es ejecutar el comando sin solicitud de contraseña. (Podría hacerlo fácilmente como usuario de techops cuando solo ejecuto /home/techops/publicapi start). El problema en sí mismo es impedir que el usuario predeterminado inicie estos servicios.

Y esperaba que cualquiera de las soluciones pudiera hacer eso.

Comencé con los enfoques de Thomas. El enfoque con sudo funciona cuando no quiero que me pidan la contraseña para los usuarios de techops cuando ejecuto los comandos como se explica, por ej.

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

El segundo enfoque aún no funciona para mí. No puedo iniciar el servicio sin solicitud de contraseña ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===y puedo iniciar sesión como usuario predeterminado cuando tengo la contraseña de este usuario.

Con el tercer enfoque, el servicio ya ni siquiera comienza en el proceso de arranque, así que no estoy seguro de si este enfoque es el adecuado para mí. Ni siquiera puedo hacerlo con lo systemctl enable publicapi.serviceque me lleva al siguiente error:

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

El error no ocurre cuando muevo todos los servicios nuevamente a / etc / systemd / system / y ejecuto systemctl enable publicapi.service. Luego, el servicio comienza nuevamente en el arranque.

Todos estos enfoques ayudarán más o menos a omitir la solicitud de contraseña para el usuario de techops, pero cuando ejecuto service publicapi stopo systemctl stop publicapi con el usuario predeterminado , puedo detener los servicios si tengo la contraseña. Pero mi objetivo es evitar que el usuario predeterminado inicie o detenga los servicios.

Bevor
fuente
1
Para el tercer enfoque, debe ejecutarse systemctl --user ...como usuario, techopsno como root. Ni mi sugerencia ni el de @PerlDuck da ningún sudoderecho a su defaultuser pero sólo en la TechOps usuario.
Thomas
1
¿El usuario predeterminado está configurado como sudo? En ese caso, debe eliminar al usuario de los grupos secundarios y verificar su /etc/sudoersarchivo si hay una referencia para ese usuario.
Thomas
@ Thomas Ah, eso es todo. Funciona como se esperaba ahora. Gracias.
Bevor

Respuestas:

17

Para lograr que el usuario techopspueda controlar el servicio publicapi.servicesin dar una contraseña, tiene diferentes posibilidades. No se puede responder cuál es el adecuado para usted, ya que debe elegirlo por su cuenta.


El sudoenfoque clásico es quizás el más utilizado, ya que está allí durante mucho tiempo. Tendría que crear, por ejemplo, el archivo de la siguiente manera.
Tenga en cuenta que el directorio desplegable /etc/sudoers.dsolo está activo cuando #includedir /etc/sudoers.destá configurado /etc/sudoers. Pero ese debería ser el caso si está utilizando una distribución moderna de Ubuntu. Como rootejecutar:

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

Ahora debería poder ejecutar los systemctlcomandos como usuario techopssin dar una contraseña anteponiendo sudolos comandos.

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

El segundo método sería usar PolKit (se renombró de PolicyKit ) para permitir que el usuario techopscontrole los systemdservicios. Dependiendo de la versión de polit, puede dar a los usuarios normales control sobre las unidades systemd.
Para verificar la versión de polkit , simplemente ejecute pkaction --version.

  • con polkit versión 0.106 y superior , puede permitir a los usuarios controlar unidades específicas del sistema.
    Para hacerlo, puede crear una regla como 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 versión 0.105 e inferior : puede permitir a los usuarios controlar las unidades systemd. Desafortunadamente, esto incluye todas las unidades systemd y es posible que no desee hacer esto. No estoy seguro de si hay una manera de limitar el acceso a unidades específicas del sistema con la versión 0.105 o inferior, pero tal vez alguien más pueda aclararlo.
    Para habilitar esto, puede crear un archivo como 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
    

En ambos casos, puede ejecutar systemctl [start|stop|restart] publicapi.servicecomo usuario techopssin dar una contraseña. En el último caso (polkit <= 0.105) el usuario techopspodría controlar cualquier unidad systemd.


Una tercera opción sería hacer del servicio un servicio de usuario, que no necesita sudoni polkitconfiguraciones. Esto pone todo bajo el control del usuario y solo funciona si su servicio real que se inició /home/techops/publicapi startpuede ejecutarse sin rootprivilegios.

Primero debe habilitar la demora para el usuario techops. Esto es necesario para iniciar el servicio de usuario en el arranque. Como rootejecutar:

loginctl enable-linger techops

A continuación, debe mover el systemdarchivo de la unidad al techopsdirectorio del usuario. Como usuario, techopsejecute los comandos de la siguiente manera.

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

Tenga en cuenta que WantedBytiene que ser default.targetcomo no hay multi-user.targeten el contexto del usuario.

Ahora vuelva a cargar la configuración y habilite el servicio. Nuevamente como usuario techopsejecuta los comandos.

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

En general, debe colocar sus unidades systemd /etc/systemd/system/no directamente en /etc/systemd/system/multi-user.target.wants. Cuando ejecute systemctl enable publicapi.service, se creará un enlace simbólico en etc/systemd/system/multi-user.target.wantso cualquier objetivo especificado para esa unidad.

Como ya se mencionó, si el servicio / proceso en sí puede ejecutarse sin privilegios de root, debe considerar agregarlo User=techopsa su archivo de unidad para ejecutar el proceso con una cuenta de usuario no privilegiada.

Thomas
fuente
Muy bien. Incluso pensó en el objetivo WantedBy diferente para las unidades de usuario. Obviamente, este no es el primer archivo de unidad que escribió :-)
PerlDuck
Tanques @PerlDuck. = 0)
Thomas
Gracias por su respuesta. Esto responde en parte a mi pregunta, pero todavía tengo mi problema inicial. (Actualicé la pregunta)
Bevor
Lo siento, por lo que .pklano funciona. Esto necesita una [section]entrada. Respuesta actualizada
Thomas
5

En primer lugar, no coloca un archivo de unidad en el directorio /etc/systemd/system/multi-user.target.wants. Este directorio es mantenido por systemdy los systemctlcomandos. Coloque el archivo de la unidad en su /etc/systemd/systemlugar y luego habilítelo con

sudo systemctl enable publicapi.service

Esto creará un enlace simbólico a continuación multi-user.target.wants(o donde sea, lo systemctlsepa mejor) para honrar las líneas

[Install]
WantedBy=multi-user.target

en la unidad

A continuación, cree un sudoersarchivo a continuación /etc/sudoers.d:

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

con el siguiente contenido:

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

No use un editor normal (p sudo vim /etc/sudoers.d/techops. Ej. ) Para editar ese archivo porque si le agrega errores de sintaxis, no podrá volver a ejecutarlo sudo. visudoPor otro lado, comprueba la sintaxis del archivo antes de abandonar el editor.

Ahora el usuario techopspuede ejecutar

sudo systemctl start publicapi.service

y los otros dos sin proporcionar una contraseña. Tenga en cuenta que debe escribir el comando y los parámetros exactamente como se indica en el sudoersarchivo (excepto la /bin/systemctlparte que se puede acortar a solo systemctl).

Por ejemplo, sudo /bin/systemctl start publicapi(sin .service) solicitaría una contraseña.

PerlDuck
fuente