Comment supprimer les privilèges root dans les scripts shell?

13

L'option "--up" dans OpenVPN est normalement utilisée pour le routage, etc. Et donc elle est traitée avant qu'OpenVPN ne baisse les privilèges root pour s'exécuter en tant que personne. Cependant, j'invoque des scripts shell qui doivent s'exécuter en tant qu'utilisateur non privilégié.

Comment je fais ça? J'ai étudié les privilèges de processus de suppression, en particulier les réponses de polynômes et de tylerl, mais je ne comprends pas comment les implémenter. Je travaille dans Centos 6.5 et suid est bloqué, à la fois comme "chmod u + s" et comme "setuid ()".

Il existe un plugin OpenVPN ("openvpn-down-root.so") qui permet aux scripts invoqués par l'option "--down" de s'exécuter en tant que root. Il pourrait y avoir un équivalent, tel que "openvpn-up-user.so", mais je ne l'ai pas trouvé.

Modifier0

Selon la réponse de Nikola Kotur, j'ai installé runit-rpm d'Ian Meyer . Bien que la commande chpst fonctionne dans le terminal, dans le script up, elle échoue avec "commande introuvable". Ce qui fonctionne est "sudo chpst" plus le réglage de l'affichage et de la langue appropriés. Veuillez consulter Pourquoi mon terminal ne produit-il pas correctement les caractères Unicode? Compte tenu de cela, le script up a besoin de ces quatre lignes:

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &

Modifier1

Selon le commentaire de 0xC0000022L, je trouve que "sudo -u user" fonctionne aussi bien que "sudo chpst -u user -U user":

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &

J'étudierai les sudoers de l'homme et je mettrai à jour si / quand je fais travailler sudo seul.

mirimir
la source
commentaire laissé par @ user66229: "Puis-je vous suggérer de surfer sur sourceforge.net/p/openvpn/mailman et de vous abonner aux listes que vous trouvez les plus appropriées."
slm
@ user66229 Merci. Mais je ne pense pas que ce soit une question spécifique à OpenVPN. Pourquoi croyez-vous que c'est le cas?
mirimir

Réponses:

7

J'utilise RunIt de » chpstoutil pour des tâches comme celui - ci. Par exemple, à partir du script up, appelez votre script non privilégié:

chpst -u nobody /path/to/script
Nikola Kotur
la source
Cool merci. Github.com/imeyer/runit-rpm est- il le meilleur moyen de lancer runit dans Centos 6.5? Même avec les dépôts Red Hat, je ne trouve pas de package.
mirimir
@mirimir, oui, j'utilise ce dépôt lorsque j'ai besoin de construire un package runit pour CentOS.
Nikola Kotur
10

Couvrir seulement runit et sudo manque beaucoup. Il existe en fait toute une famille de jeux d'outils comme runit et un large choix d'outils pour faire exactement cela, la tâche même pour laquelle ils ont été conçus:

  • Les daemontools de Daniel J. Bernstein, ont setuidgid:

    utilisateur setuidgid /home/user/unprivileged.sh
  • La liberté d'Adam Sampson a setuidgid:

    utilisateur setuidgid /home/user/unprivileged.sh
  • Daemontools-encore de Bruce Guenter a setuidgid:

    utilisateur setuidgid /home/user/unprivileged.sh
  • Le runit de Gerrit Pape a chpst:

    chpst -u user /home/user/unprivileged.sh
  • Le perp de Wayne Marshall a runuid:

    utilisateur runuid /home/user/unprivileged.sh
  • Le s6 de Laurent Bercot a s6-setuidgid:

    utilisateur s6-setuidgid /home/user/unprivileged.sh
  • mon nez a setuidgid:

    utilisateur setuidgid /home/user/unprivileged.sh

Ils ne se mêlent pas aux différentes tâches d' ajout de privilèges et ne tombent jamais dans un mode interactif.

Vos problèmes cloués ne sont guère plus que votre oubli d'avoir sbinaussi bien que bindans votre PATH, soit dit en passant.

Lectures complémentaires

JdeBP
la source
3

script qui abandonne les privilèges et exécute un autre script (mais ici je viens de le faire s'exécuter lui-même):

#!/bin/sh

id=`id -u`
safeuser="nobody"

if [ $id = "0" ]
then
         # we're root. dangerous!
        sudo -u $safeuser $0
else
    echo "I'm not root"
    id
fi

Exemple:

root@n3:/tmp/x# id
uid=0(root) gid=0(root) группы=0(root)
root@n3:/tmp/x# ./drop.sh
I'm not root
uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)
yaroslaff
la source
Bien que l'utilisation de "sudo -u user" fonctionne pour certaines commandes, elle ne fournit pas suffisamment d'environnement utilisateur pour mes besoins. Et tandis que "su -l user" fonctionne bien dans le terminal, il ne fait rien dans les scripts. Je suppose que c'est une caractéristique de sécurité. Il me semble donc qu'il me reste à installer runit.
mirimir
1
@mirimir: pourquoi? /etc/sudoerspermet d'être très précis quelles variables d'environnement peuvent être transmises au programme exécuté par sudoet ainsi de suite. man sudoers. Honnêtement, quiconque utilise sudosimplement pour sudo su -ou pour changer de contexte utilisateur n'a aucune idée de ce qui se cache derrière ce programme génial et combien vous pouvez verrouiller les choses pour des programmes individuels, des utilisateurs, des hôtes, etc.
0xC0000022L
@ 0xC0000022L Merci. J'ai jeté un nouveau coup d'œil à sudo. Et oui, "sudo -u user" plus l'affichage et la langue fonctionnent également.
mirimir
1
En parlant de dangereux - vous ne pouvez pas faire confiance $0; l'appelant peut $0littéralement définir ce qu'il veut. Et utilisez plus de citations.
Charles Duffy
2
... si ce script $0est /directory/name with spaces/script(et rappelez - vous, les utilisateurs peuvent créer des liens symboliques arbitraires dans des endroits dont ils sont propriétaires, même si elles ne sont pas utiliser exec -a somename yourscriptpour appeler yourscriptun $0de somename), vous obtiendrez sudo -u nobody /directory/name with spaces, avec withet spacespassé comme arguments séparés à votre commande .
Charles Duffy
1

Qu'en est-il de:

sudo -Eu <user> <command>

Vous vous êtes plaint de l'environnement dans un commentaire précédent, vous pouvez donc également comparer les différences entre les sorties:

sudo -u <user> printenv
sudo -Eu <user> printenv
thiagowfx
la source
1

Sous Linux, vous pouvez utiliser runuserou setprivsi une session PAM n'est pas requise (les deux depuis util-linux):

runuser -u USER [--] COMMAND [ARGUMENTS...]

setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...]  # Like su/runuser/sudo
setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...]  # Like daemontools setuid(8)

Depuis la supage de manuel:

su est principalement conçu pour les utilisateurs non privilégiés, la solution recommandée pour les utilisateurs privilégiés (par exemple, les scripts exécutés par root) est d'utiliser la commande runuser (1) non-set-user-ID qui ne nécessite pas d'authentification et de fournir une configuration PAM distincte. Si la session PAM n'est pas du tout requise, la solution recommandée consiste à utiliser la commande setpriv (1) .

dcoles
la source