Exécution de tâches nouvelles en tant qu'utilisateurs non privilégiés


142

Quelle est la manière canonique de faire en sorte qu'un travail parvenu modifie son ID utilisateur et exécute le script en tant qu'utilisateur non privilégié?

Évidemment, on peut utiliser suou sudo, mais cela semble hacky (et peut générer des lignes de journal inutiles).

Réponses:


108

Avec upstart v1.4, setuid et setgid sont supportés de manière native dans le fichier de configuration.


7
Voir le livre de cuisine pour plus de précisions à ce sujet: upstart.ubuntu.com/cookbook/#run-a-job-as-a-different-user
Jason Navarrete

10
En d'autres termes, il est pris en charge dans Precise (12.04) et plus récent.
Edward Anderson

8
En d'autres termes, n'est pas pris en charge dans centos 6
socketpair

5
Pour mémoire, initctl --versionpour trouver votre version actuelle d’upstart.
Mahn

4
Chose embarrassante, la distribution Amazon Linux sur AWS utilise la version récente de RHEL 6 (0.6.5 !!!!), de sorte que toute personne utilisant cette version devra utiliser la solution 'su'.
Asfand Qazi

86

En posant sur la chaîne #upstart sur freenode, la question officielle est la suivante:

La prochaine version d'Upstart aura un support natif pour cela, mais pour l'instant, vous pouvez utiliser quelque chose comme:

exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters...]

7
C’est la seule réponse qui fonctionne sur Amazon Linue EC2 (j’ai essayé toutes les variantes de sudo et de su, y compris --session-command, -c, ad nauseum); aucun d'entre eux n'a permis d'arrêter le processus une fois démarré; Merci beaucoup pour cela.
Kato

C'est une magie de coquille fantaisie, +1.
Steve Kehlet

6
Cela n'a pas fonctionné pour moi sur CentOS 6 (Upstart 0.6.5). Il y a une série de fourches (4 profondes je pense) initiées par sucela qui signifie que expect forkmême expect daemonne saisit pas le PID final.
Mark Lakata

2
Je l'ai utilisé sur Amazon Linux (Upstart 0.6.5) pour démarrer un processus Jenkins (qui ne se démonème pas, heureusement) et cela a fonctionné! J'ai dû le modifier un peu pour rediriger la sortie standard vers un fichier journal et définir des variables d'environnement, mais cela a fonctionné! Ma version ressemble à:exec su -s /bin/sh -c 'HOME=/foo/bar exec "$0" "$@" &>/var/log/foobar.log' username -- /path/to/command [parameters...]
Asfand Qazi

17

Que diriez-vous d'utiliser start-stop-daemon?

exec start-stop-daemon --start --chuid daemonuser --exec /bin/server_cmd

Du livre de cuisine Upstart :

La méthode recommandée pour les systèmes Debian et Ubuntu consiste à utiliser l'utilitaire d'assistance start-stop-daemon. […] start-stop-daemonN'impose pas de limites au processus démarré par PAM ("Pluggable Authentication Module").

Remarque: start-stop-daemonnon pris en charge par RHEL.


2
Vous pouvez également utiliser le groupe, si vous en avez besoin. Avec --chuid daemonuser: daemongroup
Evgeny

13

Il existe plusieurs façons de le faire, toutes avec une sémantique légèrement différente, en particulier en ce qui concerne l'appartenance à un groupe:

  • setuidgid vous mettra dans le groupe que vous spécifiez.

    • Les outils originaux de daemontools setuidgidne vous placeront que dans ce groupe, vous ne pourrez donc pas accéder aux fichiers appartenant aux autres groupes dont vous êtes membre.
    • Les outils setuidgidfrom daemontools-encore et setuidgidfrom the nosh ont tous deux une option -s(aka --supplementary) qui vous placera dans ce groupe et vous placera également dans tous les groupes supplémentaires de l'utilisateur que vous spécifiez.
  • Utiliser newgrpune fois que vous êtes devenu l'utilisateur le moins privilégié ajoutera un seul groupe à votre groupe, mais créera également un nouveau sous-shell, ce qui rendra l'utilisation du script difficile.

  • start-stop-daemon préserve votre appartenance à un groupe et fait beaucoup plus que simplement setuid / setgid.

  • chpst -u username:group1:group2:group3... commandnamevous permettra de spécifier exactement les appartenances à un groupe à adopter, mais (dans Ubuntu ), il est uniquement fourni avec le runitpaquet, qui est une alternative à upstart.

  • su -c commandname usernamerécupère tous les membres du groupe de noms d'utilisateur, comme c'est le cas sudo -u username commandname, de sorte qu'ils sont probablement la voie la moins étonnée.



4

Sur une instance Ubuntu 10.10 sur Amazon EC2, j'ai eu plus de chance avec la start-stop-daemoncommande.

J'ai également eu du mal avec certaines des autres strophes avancées . J'appelle une application python avec un virtualenvparamètre spécifique et certains paramètres de mon programme exécuté.

Ce qui suit est ce qui a fonctionné pour moi.

script
  export PYTHONPATH=.:/home/ubuntu/.local/lib/python2.7/site-packages/:/home/ubuntu/python/lib/python2.7/site-packages/
  exec start-stop-daemon --start  --chuid ubuntu --exec /home/ubuntu/python_envs/MyProj/bin/python /home/ubuntu/www/MyProj/MyProj.py -- --config-file-dir=/home/ubuntu/www/MyProj/config/ >> /home/ubuntu/startup.log 2>&1 &
end script

Il PYTHONPATHconsiste à installer certains packages à partir de la source dans le chemin du module PYTHON lors de l’exécution de cette tâche. Je devais tout faire de manière absolue parce que la chdirstrophe ne semblait pas fonctionner.


J'ai également eu des problèmes avec les variables env utilisées avec exec start-stop-daemon .
Thomas Bratt

3

J'utilisais CentOS 6 et je ne pouvais pas utiliser le hack recommandé (pour Upstart 0.6.5), ni le truc "su" car le nombre de fourches impliquées (4 je pense) n'était pas suivi par "expect fork" 'ou' attendons le démon '.

J'ai finalement juste fait

chown user:group executable
chmod +s executable

(c.-à-d. définir le bit setuid et changer la propriété).

Ce n'est peut-être pas la méthode la plus sûre, mais dans le cas d'un projet interne de R & D, peu importait.


Si vous deviez faire un chmod 1700ou au moins un coup chmod u+sx,go-xau lieu de juste +s, cela serait considéré comme "assez sûr". :)
dannysauer

0

Il y a une troisième possibilité en fonction de ce que vous essayez d'accomplir. Vous pourrez peut-être relâcher les contrôles d’accès sur les fichiers / périphériques en question . Cela peut permettre à un utilisateur non privilégié de monter ou d'accéder à des éléments auxquels il ne serait normalement pas autorisé. Veillez simplement à ne pas donner les clés du royaume dans le processus.

Vous pouvez également modifier le délai d'expiration du cache de mot de passe sudo . Mais je ne le recommande pas, sauf si votre machine est physiquement sécurisée (vous pensez qu'il est peu probable qu'un passant tente d'obtenir un accès sudo).

Il y a une bonne raison qu'il ya très peu de moyens d'effectuer des actions privilégiées et qu'ils exécutent inutiles nécessaires l' exploitation forestière. Des restrictions lâches constitueraient un risque pour la sécurité de votre système, et l'absence de journalisation signifierait qu'il est impossible de savoir ce qui s'est passé lorsque vous avez été compromis.

Si la taille de vos fichiers journaux pose problème, il est probable que quelque chose ne va pas. Sudo génère une seule ligne par utilisation dans des conditions normales.


0

Dans CentOS 6, jusqu'à 0.6.5, voici ce qui a fonctionné pour moi.

script

    exec su user_name << EOF
        exec /path/to/command [parameters...]
EOF

end script

ou :

script

    exec su user_name << EOF
       ..... what you want to do ....
EOF

end script

Quand utiliser

exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters...]

le processus de travail ne peut pas être arrêté par initclt stop. Je pense que la raison est:

1. the job forked and the main process is not tracked.
2. the main process changed its process group,because of `su -c`
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.