it-swarm.com.de

Bewährte Methode, um den Linux-Dienst als anderen Benutzer auszuführen

Dienste werden standardmäßig als root zur Startzeit auf meiner RHEL-Box gestartet. Wenn ich mich recht erinnere, gilt dies auch für andere Linux-Distributionen, die die Init-Skripte in /etc/init.d verwenden.

Was ist Ihrer Meinung nach der beste Weg, stattdessen die Prozesse als (statische) Benutzer meiner Wahl auszuführen?

Die einzige Methode, die ich gefunden hatte, bestand darin, etwas zu verwenden:

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

Das scheint aber etwas unordentlich zu sein ...

Gibt es etwas Magie, die einen einfachen Mechanismus bietet, mit dem Dienste automatisch als andere Benutzer ohne Rootberechtigung gestartet werden können?

EDIT: Ich hätte sagen sollen, dass die Prozesse, die ich in dieser Instanz starte, entweder Python-Skripts oder Java-Programme sind. Ich möchte lieber keinen nativen Wrapper um sie herum schreiben, daher kann ich setuid () as Black leider nicht aufrufen.

134
James Brady

Unter Debian verwenden wir das Dienstprogramm start-stop-daemon, das pid-Dateien verarbeitet, den Benutzer ändert, den Dämon in den Hintergrund stellt und vieles mehr.

Ich bin nicht mit RedHat vertraut, aber das daemon-Dienstprogramm, das Sie bereits verwenden (das in /etc/init.d/functions, btw. Definiert ist) wird überall als Äquivalent zu start-stop-daemon erwähnt, sodass es entweder die Uid Ihres Programms oder die So wie Sie es tun, ist es bereits das Richtige.

Wenn Sie sich im Netz umsehen, gibt es mehrere vorgefertigte Wrapper, die Sie verwenden können. Einige sind möglicherweise bereits in RedHat verpackt. Sehen Sie sich zum Beispiel daemonize an.

67
user3850

Nachdem ich mir alle Vorschläge angeschaut habe, habe ich ein paar Dinge entdeckt, von denen ich hoffe, dass sie anderen in meiner Position nützlich sind:

  1. hop ist richtig, um mich zurückzuweisenat /etc/init.d/functions: Mit der daemon-Funktion können Sie bereits einen anderen Benutzer festlegen.

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

    Dies wird implementiert, indem der -Prozessaufruf später mit runuser - Umbrochen wird.

  2. Jonathan Leffler ist richtig: Es gibt setuid in Python:

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

    Ich glaube aber immer noch nicht, dass Sie von einer JVM aus eine JU-Datei setzen können.

  3. Weder su noch runuser Behandeln den Fall, in dem Sie Einen Befehl ausführen sollen, genau wie der Benutzer, den Sie. Z.B.:

    [[email protected]_Host]$ id
    uid=500(my_user) gid=500(my_user) groups=500(my_user)
    [[email protected]_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)
    

Um dieses Verhalten von su und runuser zu umgehen, habe ich mein Init-Skript folgendermaßen geändert:

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

Vielen Dank für Ihre Hilfe!

53
James Brady
  • Einige Daemons (z. B. Apache) tun dies selbst, indem sie setuid () aufrufen.
  • Sie können das Flag setuid-file verwenden, um den Prozess als anderer Benutzer auszuführen.
  • Natürlich funktioniert auch die von Ihnen erwähnte Lösung.

Wenn Sie Ihren eigenen Daemon schreiben möchten, empfehle ich, setuid () ..__ aufzurufen. Auf diese Weise kann Ihr Prozess

  1. Verwenden Sie die Root-Berechtigungen (z. B. offene Protokolldateien, PID-Dateien erstellen).
  2. Löschen Sie die Root-Berechtigungen zu einem bestimmten Zeitpunkt während des Startvorgangs.
5
Black

Nur um einige andere Dinge hinzuzufügen, auf die Sie achten sollten:

  • Sudo in einem init.d-Skript ist nicht gut, da es ein tty benötigt ("Sudo: Entschuldigung, Sie müssen ein tty haben, um Sudo auszuführen")
  • Wenn Sie eine Java-Anwendung dämonisieren, sollten Sie den Java-Service-Wrapper in Betracht ziehen (der einen Mechanismus zum Festlegen der Benutzer-ID bereitstellt).
  • Eine andere Alternative könnte sein: su --session-command = [cmd] [Benutzer]  
3
pdeschen

auf einer virtuellen CENTOS-Maschine (Red Hat) für den svn-Server: bearbeitet /etc/init.d/svnserver, um die PID in etwas zu ändern, das svn schreiben kann:

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

und hinzugefügte Option --user=svn:

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

Die ursprüngliche PID-Datei war /var/run/svnserve.pid. Der Dämon konnte nicht gestartet werden, da dort nur root schreiben konnte.

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

Einige Dinge, auf die Sie achten sollten:

  • Wie Sie bereits erwähnt haben, werden Sie zur Eingabe eines Kennworts aufgefordert, wenn Sie bereits der Zielbenutzer sind
  • Ebenso schlägt setuid (2) fehl, wenn Sie bereits Zielbenutzer sind (bei einigen Betriebssystemen).
  • setuid (2) installiert keine Berechtigungen oder Ressourcensteuerelemente, die in /etc/limits.conf (Linux) oder/etc/user_attr (Solaris) definiert sind.
  • Wenn Sie die setgid (2)/setuid (2) -Route gehen, vergessen Sie nicht, initgroups (3) anzurufen - mehr dazu hier

Im Allgemeinen verwende ich/sbin/su, um vor dem Starten von Daemons zum entsprechenden Benutzer zu wechseln.

2
claymation

Warum probieren Sie das Folgende nicht im Init-Skript:

setuid $USER application_name

Es hat für mich funktioniert.

2
cyberJar

Ich musste eine Spring-.jar-Anwendung als Dienst ausführen und fand einen einfachen Weg, dies als bestimmten Benutzer auszuführen:

Ich habe den Besitzer und die Gruppe meiner JAR-Datei in den Benutzer geändert, den ich als ..__ ausführen wollte. Dann wurde dieses Jar in init.d mit einem Link verknüpft und der Dienst gestartet.

So:

#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
0
Somaiah Kumbera