J'ai créé des services systemd qui fonctionnent essentiellement:
emplacement:
/etc/systemd/system/multi-user.target.wants/publicapi.service
contenu:
[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
Lorsque j'essaie de redémarrer le service en tant qu'utilisateur techops dans la ligne de commande, j'obtiens la sortie suivante:
==== 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):
Je souhaite que seuls les techops puissent redémarrer les services et je souhaite que cette invite n'apparaisse pas lors de la connexion en tant que techops. Comment puis je faire ça?
J'ai lu qu'il existe différentes approches avec polkit-1 ou sudoers, mais je ne suis pas sûr.
[MISE À JOUR] 27/01/2019 16h4
Merci pour cette réponse complète à Thomas et Perlduck. Cela m'a aidé à améliorer ma connaissance de systemd.
Selon l'approche de démarrage du service sans invite de mot de passe, et je tiens à m'excuser de ne pas avoir suffisamment souligné le vrai problème:
En fait, ce qui est le plus important pour moi, c'est qu'aucun autre utilisateur que techops ne devrait arrêter ou démarrer le service. Mais au moins avec les deux premières approches, je peux toujours exécuter service publicapi stop
et je reçois l'invite ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
encore. Lorsque je choisis l'utilisateur par défaut et que je connais le mot de passe, je pouvais arrêter tous les services. Je veux empêcher cet utilisateur de le faire, même s'il a le mot de passe. Informations générales importantes pour mieux comprendre pourquoi c'est la partie la plus importante pour moi:
L'utilisateur par défaut est le seul utilisateur exposé à ssh mais cet utilisateur ne peut rien faire d'autre (sauf changer pour d'autres utilisateurs si vous avez le mot de passe de ces autres utilisateurs). Mais pour le moment, il peut démarrer ou arrêter les services, mais cet utilisateur ne doit pas le faire.
Si quelqu'un obtient le mot de passe de l'utilisateur par défaut et se connecte via ssh, il peut arrêter tous les services pour le moment. C'est ce que je voulais dire par "Je veux que seuls les techops puissent redémarrer les services". Désolé, je n'étais pas aussi précis à ma question initiale. Je pensais que le sudoing de l'utilisateur techops contournerait peut-être ce problème, mais ce n'est pas le cas. Le problème lui-même n'est pas d'exécuter la commande sans invite de mot de passe. (Je pourrais facilement le faire en tant qu'utilisateur techops lorsque je viens d'exécuter /home/techops/publicapi start
). Le problème lui-même est d'empêcher l'utilisateur par défaut de démarrer ces services.
Et j'espérais que n'importe laquelle des solutions pourrait le faire.
J'ai commencé avec les approches de Thomas. L'approche avec Sudo fonctionne lorsque je ne veux pas qu'on me demande le mot de passe pour les techniciens utilisateur lorsque j'exécute les commandes comme expliqué, par ex.
Sudo systemctl start publicapi.service
Sudo systemctl stop publicapi.service
La deuxième approche ne fonctionne pas encore pour moi. Je ne peux pas démarrer le service sans invite de mot de passe ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
et je peux me connecter en tant qu'utilisateur par défaut lorsque j'ai le mot de passe de cet utilisateur.
Avec la troisième approche, le service ne démarre même plus au processus de démarrage, donc je ne sais pas si cette approche est la bonne pour moi. Je ne peux même pas le faire avec systemctl enable publicapi.service
ce qui m'amène à l'erreur suivante:
Failed to enable unit: Unit file mycuisine-publicapi.service does not exist.
L'erreur ne se produit pas lorsque je replace tous les services dans/etc/systemd/system/et exécute systemctl enable publicapi.service
. Ensuite, le service redémarre au démarrage.
Toutes ces approches aideront plus ou moins à contourner l'invite de mot de passe pour l'utilisateur techops mais lorsque j'exécute service publicapi stop
ou systemctl stop publicapi
avec defaultuser, je peux arrêter les services si j'ai le mot de passe. Mais mon objectif est d'empêcher l'utilisateur par défaut de démarrer ou d'arrêter les services.
Pour ce faire, l'utilisateur techops
peut contrôler le service publicapi.service
sans donner de mot de passe, vous avez différentes possibilités. Celui qui vous convient ne peut pas être répondu car vous devez choisir vous-même.
L'approche classique Sudo
est peut-être la plus utilisée, car elle existe depuis longtemps. Vous devez créer par exemple le fichier comme suit.
Notez que le répertoire de dépôt /etc/sudoers.d
n'est actif que lorsque #includedir /etc/sudoers.d
est défini dans /etc/sudoers
. Mais cela devrait être le cas si vous utilisez une distribution Ubuntu moderne. Comme root
exécutez:
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
Vous devriez maintenant pouvoir exécuter les commandes systemctl
en tant qu'utilisateur techops
sans donner de mot de passe en ajoutant Sudo
aux commandes.
Sudo systemctl start publicapi.service
Sudo systemctl stop publicapi.service
Sudo systemctl restart publicapi.service
La deuxième méthode consisterait à utiliser PolKit (a été renommé à partir de PolicyKit) pour permettre à l'utilisateur techops
de contrôler les services systemd
. Selon la version de polit
, vous pouvez donner aux utilisateurs normaux le contrôle des unités systemd.
Pour vérifier la version polkit, exécutez simplement pkaction --version
.
avec polkit version 0.106 et supérieure, vous pouvez permettre aux utilisateurs de contrôler des unités systemd spécifiques.
Pour ce faire, vous pouvez créer une règle sous la forme 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
avec polkit version 0.105 et inférieure: vous pouvez autoriser les utilisateurs à contrôler les unités systemd. Cela inclut malheureusement toutes les unités systemd et vous ne voudrez peut-être pas le faire. Je ne sais pas s'il existe un moyen de limiter l'accès à des unités systemd spécifiques avec la version 0.105 ou inférieure, mais peut-être que quelqu'un d'autre peut clarifier.
Pour activer cela, vous pouvez créer un fichier en tant que 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
Dans les deux cas, vous pouvez exécuter systemctl [start|stop|restart] publicapi.service
en tant qu'utilisateur techops
sans donner de mot de passe. Dans ce dernier cas (polkit <= 0.105), l'utilisateur techops
pouvait contrôler n'importe quelle unité systemd.
Une troisième option serait de faire du service un service utilisateur, qui n'a pas besoin de configurations Sudo
ou polkit
. Cela met tout sous le contrôle de l'utilisateur et ne fonctionne que si votre service réel démarré avec /home/techops/publicapi start
peut s'exécuter sans les privilèges root
.
Vous devez d'abord activer la persistance pour l'utilisateur techops
. Cela est nécessaire pour démarrer le service utilisateur au démarrage. Comme root
exécutez:
loginctl enable-linger techops
Ensuite, vous devez déplacer le fichier d'unité systemd
dans le répertoire utilisateur techops
. En tant qu'utilisateur techops
exécutez les commandes comme suit.
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
Notez que WantedBy
doit être default.target
car il n'y a pas de multi-user.target
dans le contexte utilisateur.
Rechargez maintenant la configuration et activez le service. De nouveau en tant qu'utilisateur techops
exécutez les commandes.
systemctl --user daemon-reload
systemctl --user enable publicapi.service
systemctl --user start publicapi.service
En général, vous devez placer vos unités systemd dans /etc/systemd/system/
pas directement dans /etc/systemd/system/multi-user.target.wants
. Lorsque vous exécutez systemctl enable publicapi.service
un lien symbolique sera créé dans etc/systemd/system/multi-user.target.wants
ou quelle que soit la cible spécifiée pour cette unité.
Comme déjà mentionné, si le service/processus lui-même peut être exécuté sans privilèges root, vous devriez envisager d'ajouter User=techops
à votre fichier d'unité pour exécuter le processus avec un compte d'utilisateur non privilégié.
Tout d'abord, vous ne mettez pas de fichier d'unité dans le répertoire /etc/systemd/system/multi-user.target.wants
. Ce répertoire est géré par systemd
et les commandes systemctl
. Placez le fichier d'unité dans /etc/systemd/system
à la place, puis activez-le avec
Sudo systemctl enable publicapi.service
Cela créera un lien symbolique sous multi-user.target.wants
(ou partout, systemctl
sait mieux) pour honorer les lignes
[Install]
WantedBy=multi-user.target
dans l'unité.
Ensuite, créez un fichier sudoers
sous /etc/sudoers.d
:
Sudo visudo -f /etc/sudoers.d/techops
avec le contenu suivant:
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
N'utilisez pas d'éditeur standard (par exemple Sudo vim /etc/sudoers.d/techops
) pour éditer ce fichier car si vous y insérez des erreurs de syntaxe, vous ne pourrez plus exécuter Sudo
. visudo
d'autre part vérifie la syntaxe du fichier avant de quitter l'éditeur.
Maintenant, l'utilisateur techops
peut exécuter
Sudo systemctl start publicapi.service
et les deux autres sans fournir de mot de passe. Notez que vous devez taper la commande et les paramètres exactement comme indiqué dans le fichier sudoers
(sauf pour le /bin/systemctl
partie qui peut être raccourcie à seulement systemctl
).
Par exemple, Sudo /bin/systemctl start publicapi
(sans .service
) demanderait un mot de passe.