Les meilleures pratiques pour exécuter le service Linux en tant qu'utilisateur différent

StackOverflow https://stackoverflow.com/questions/394984

  •  23-08-2019
  •  | 
  •  

Question

Services par défaut à partir de root au démarrage sur ma boîte RHEL. Si je me souviens bien, la même chose est vraie pour d'autres distributions Linux qui utilisent les scripts d'initialisation dans /etc/init.d.

Que pensez-vous est la meilleure façon d'avoir lieu les processus exécutés comme (statique) utilisateur de mon choix?

La seule méthode que je suis arrivée à était d'utiliser quelque chose comme:

 su my_user -c 'daemon my_cmd &>/dev/null &'

Mais cela semble un peu en désordre ...

est-il un peu de magie nichés qui fournit un mécanisme simple pour démarrer automatiquement les services que les autres, les utilisateurs non root?

EDIT: Je aurais dû dire que les processus que je commence dans ce cas sont des scripts Python ou des programmes Java. Je préfère ne pas écrire un wrapper natif autour d'eux, donc, malheureusement, je ne peux pas appeler setuid () comme Noir suggère .

Était-ce utile?

La solution

Sur Debian, nous utilisons l'utilitaire start-stop-daemon, qui gère pid-fichiers, modifier l'utilisateur, mettre le démon en arrière-plan et bien plus encore.

Je ne suis pas familier avec RedHat, mais l'utilitaire daemon que vous utilisez déjà (qui est définie dans /etc/init.d/functions, btw.) Est mentionné partout comme l'équivalent start-stop-daemon, donc soit il peut aussi changer l'uid de votre programme , ou la façon dont vous le faites est déjà le bon.

Si vous regardez sur le net, il y a plusieurs emballages prêts à l'emploi que vous pouvez utiliser. Certains peuvent même être déjà emballés dans RedHat. Jetez un oeil à daemonize , par exemple.

Autres conseils

Après avoir examiné toutes les suggestions ici, je l'ai découvert quelques petites choses que je l'espère, seront utiles à d'autres dans ma position:

  1. hop est le droit de me pointer à /etc/init.d/functions: le fonction vous permet déjà daemon pour définir un autre utilisateur:

    daemon --user=my_user my_cmd &>/dev/null &
    

    Ceci est réalisé en enroulant le invocation de processus avec runuser - reviendrons plus tard.

  2. Jonathan Leffler a raison: il est setuid en Python:

    import os
    os.setuid(501) # UID of my_user is 501
    

    Je ne pense pas que vous pouvez toujours setuid à partir de l'intérieur d'une machine virtuelle Java, cependant.

  3. Ni su ni runuser gracieusement gérer le cas où vous demander d'exécuter une commande en tant qu'utilisateur vous sont déjà. Par exemple:.

    [my_user@my_host]$ id
    uid=500(my_user) gid=500(my_user) groups=500(my_user)
    [my_user@my_host]$ su my_user -c "id"
    Password: # don't want to be prompted!
    uid=500(my_user) gid=500(my_user) groups=500(my_user)
    

Pour contourner ce comportement de su et runuser, j'ai changé mon script d'initialisation à quelque chose comme:

if [[ "$USER" == "my_user" ]]
then
    daemon my_cmd &>/dev/null &
else
    daemon --user=my_user my_cmd &>/dev/null &
fi

Merci à tous pour votre aide!

  • Certains daemons (par exemple) apache font par eux-mêmes en appelant setuid ()
  • Vous pouvez utiliser le setuid fichier drapeau pour exécuter le processus en tant qu'utilisateur différent.
  • Bien sûr, la solution que vous avez mentionné fonctionne aussi bien.

Si vous avez l'intention d'écrire votre propre démon, je vous recommande d'appeler setuid (). De cette façon, votre processus peut

  1. utiliser ses privilèges root (par exemple, des fichiers journaux ouverts, créer des fichiers pid).
  2. Laissez tomber ses privilèges root à un certain point lors du démarrage.

Il suffit d'ajouter quelques autres choses à surveiller:

  • Sudo dans un script init.d est pas bon car il a besoin d'un téléscripteur ( "sudo: désolé, vous devez avoir un téléscripteur pour exécuter sudo")
  • Si vous daemonizing une application java, vous pouvez envisager Java service Wrapper (qui fournit un mécanisme pour régler l'ID utilisateur)
  • Une autre alternative pourrait être su de-commande = [cmd] [utilisateur]

sur CentOS (Red Hat) machine virtuelle pour le serveur svn: édité /etc/init.d/svnserver de changer le pid à quelque chose qui svn peut écrire:

pidfile=${PIDFILE-/home/svn/run/svnserve.pid}

et l'option ajoutée --user=svn:

daemon --pidfile=${pidfile} --user=svn $exec $args

Le pidfile original était /var/run/svnserve.pid. Le démon n'a pas commencé becaseu seul root peut y écrire.

 These all work:
/etc/init.d/svnserve start
/etc/init.d/svnserve stop
/etc/init.d/svnserve restart

Il y a des choses à surveiller:

  • Comme vous l'avez mentionné, su vous demandera un mot de passe si vous êtes déjà l'utilisateur cible
  • De même, setuid (2) échouera si vous êtes déjà l'utilisateur cible (sur certains systèmes d'exploitation)
  • setuid (2) ne pas installer des privilèges ou des contrôles de ressources définis dans /etc/limits.conf (Linux) ou / etc / user_attr (Solaris)
  • Si vous allez le GID (2) / setuid (2) la route, ne pas oublier d'appeler initgroups (3) - plus sur ce ici

J'utilise généralement / sbin / su passer à l'utilisateur approprié avant daemons à partir.

Pourquoi ne pas essayer ce qui suit dans le script d'initialisation:

setuid $USER application_name

Il a travaillé pour moi.

Je avais besoin pour exécuter un ressort .jar demande en tant que service, et a trouvé un moyen simple d'exécuter cela comme un utilisateur spécifique:

J'ai changé le propriétaire et le groupe de mon fichier jar à l'utilisateur que je voulais courir comme. Ensuite, ce lien symbolique pot dans init.d et démarré le service.

#chown myuser:myuser /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar

#ln -s /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar /etc/init.d/springApp

#service springApp start

#ps aux | grep java
myuser    9970  5.0  9.9 4071348 386132 ?      Sl   09:38   0:21 /bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -jar /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top