Wie lösche ich Root-Rechte in Shell-Skripten?

13

Die Option "--up" in OpenVPN wird normalerweise für das Routing usw. verwendet. Daher wird sie verarbeitet, bevor OpenVPN die Root-Rechte verliert, um als "nobody" ausgeführt zu werden. Ich rufe jedoch Shell-Skripte auf, die als nicht privilegierter Benutzer ausgeführt werden müssen.

Wie mache ich das? Ich habe Drop Process Privileges studiert , insbesondere die Antworten von Polynomen und TylerLer, aber ich verstehe nicht, wie man sie implementiert. Ich arbeite in Centos 6.5 und suid ist blockiert, sowohl als "chmod u + s" als auch als "setuid ()".

Es gibt ein OpenVPN-Plugin ("openvpn-down-root.so"), mit dem von der Option "--down" aufgerufene Skripts als Root ausgeführt werden können. Es könnte ein Äquivalent geben, wie "openvpn-up-user.so", aber ich habe es nicht gefunden.

Edit0

Per Nikola Koturs Antwort habe ich Ian Meyers Runit-RPM installiert . Obwohl der Befehl chpst im Terminal funktioniert, schlägt er im Skript up mit "Befehl nicht gefunden" fehl. Was funktioniert, ist "sudo chpst" und das Einstellen der richtigen Anzeige und Sprache. Weitere Informationen finden Sie unter Warum gibt mein Terminal Unicode-Zeichen nicht ordnungsgemäß aus? Vorausgesetzt, das up-Skript benötigt diese vier Zeilen:

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 &

Edit1

Per 0xC0000022L's Kommentar stelle ich fest, dass "sudo -u user" genauso funktioniert wie "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 &

Ich werde Man Sudoer studieren und aktualisieren, wenn ich Sudo alleine zum Arbeiten bringe.

Mirimir
quelle
Kommentar hinterlassen von @ user66229: "Darf ich vorschlagen, dass Sie zu sourceforge.net/p/openvpn/mailman surfen und die für Sie am besten geeigneten Listen abonnieren."
slm
@ user66229 Vielen Dank. Aber ich glaube nicht, dass dies eine OpenVPN-spezifische Frage ist. Warum glaubst du, dass es ist?
Mirimir

Antworten:

7

Ich benutze runit ‚s chpstWerkzeug für Aufgaben wie diese. Rufen Sie beispielsweise über das Skript up Ihr ​​nichtprivilegiertes Skript auf:

chpst -u nobody /path/to/script
Nikola Kotur
quelle
Cool Danke. Ist github.com/imeyer/runit-rpm der beste Weg, um mit Centos 6.5 zu arbeiten? Selbst mit Red Hat Repos finde ich kein Paket.
Mirimir
@mirimir, ja, ich benutze dieses Repo, wenn ich ein Runit-Paket für CentOS erstellen muss.
Nikola Kotur
10

Nur runit und sudo abzudecken, vermisst viel. Tatsächlich gibt es eine ganze Familie von Werkzeugsätzen wie runit und eine große Auswahl an Werkzeugen, um genau das zu tun, genau für die Aufgabe, für die sie entwickelt wurden:

  • Daniel J. Bernsteins Daemontools, hat setuidgid:

    setuidgid user /home/user/unprivileged.sh
  • Adam Sampson's freedt hat setuidgid:

    setuidgid user /home/user/unprivileged.sh
  • Bruce Guenters Daemontools-Zugabe hat setuidgid:

    setuidgid user /home/user/unprivileged.sh
  • Gerrit Papes Runit hat chpst:

    chpst -u user /home/user/unprivileged.sh
  • Wayne Marshalls Täter hat runuid:

    runuid user /home/user/unprivileged.sh
  • Laurent Bercots s6 hat s6-setuidgid:

    s6-setuidgid user /home/user/unprivileged.sh
  • mein nosh hat setuidgid:

    setuidgid user /home/user/unprivileged.sh

Sie mischen sich nicht in die unterschiedliche Aufgabe des Hinzufügens von Berechtigungen und fallen niemals in einen interaktiven Modus.

Ihr gehefteten-on - Probleme sind nicht viel mehr als Ihr Vergessen zu haben sbinsowie binin den PATH, nebenbei bemerkt .

Weitere Lektüre

JdeBP
quelle
3

Skript, das Privilegien verwirft und ein anderes Skript ausführt (aber hier habe ich es gerade so gemacht, dass es sich selbst ausführt):

#!/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

Beispiel:

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
quelle
Während die Verwendung von "sudo -u user" für einige Befehle funktioniert, bietet sie nicht genügend Benutzerumgebung für meine Zwecke. Und während "su -l user" im Terminal einwandfrei funktioniert, tut es in Skripten nichts. Ich nehme an, das ist ein Sicherheitsmerkmal. Es scheint also, dass ich mit der Installation von runit fertig bin.
Mirimir
1
@mirimir: warum? /etc/sudoerserlaubt es sehr genau zu bestimmen, welche Umgebungsvariablen an das Programm übermittelt werden können, das von sudound so weiter ausgeführt wird. man sudoers. Ehrlich gesagt, wer sudonur für sudo su -oder zum Wechseln des Benutzerkontexts verwendet, hat keine Ahnung, was hinter diesem großartigen Programm steckt und wie viel Sie für einzelne Programme, Benutzer, Hosts usw.
sperren können.
@ 0xC0000022L Danke. Ich sah mir sudo noch einmal an. Und ja, "sudo -u user" plus Anzeige und Sprache funktioniert auch.
Mirimir
1
Apropos gefährlich - man kann nicht vertrauen $0; Der Aufrufer kann ein Skript $0auf buchstäblich alles einstellen , was er möchte. Und verwenden Sie mehr Anführungszeichen.
Charles Duffy
2
... wenn Ihr Skript $0ist /directory/name with spaces/script(und denken Sie daran, Benutzer beliebige Symlinks an Standorten erstellen können sie besitzen, auch wenn sie nicht verwenden , exec -a somename yourscriptrufen yourscriptmit einem $0von somename), dann bekommen Sie würden sudo -u nobody /directory/name with spaces, mit withund spacesals separate Argumente auf Ihren Befehl übergeben .
Charles Duffy
1

Wie wäre es mit:

sudo -Eu <user> <command>

Sie haben sich in einem vorherigen Kommentar über die Umgebung beschwert, sodass Sie möglicherweise auch die Unterschiede zwischen den Ausgaben vergleichen:

sudo -u <user> printenv
sudo -Eu <user> printenv
thiagowfx
quelle
1

Unter Linux können Sie verwenden runuseroder setprivwenn eine PAM-Sitzung nicht erforderlich ist (beides von 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)

Von der suManpage:

su ist hauptsächlich für nichtprivilegierte Benutzer gedacht. Die empfohlene Lösung für privilegierte Benutzer (z. B. von root ausgeführte Skripte) besteht darin, einen Runuser (1) zu verwenden , der keine Authentifizierung erfordert und eine separate PAM-Konfiguration bereitstellt. Wenn die PAM-Sitzung überhaupt nicht erforderlich ist, empfiehlt es sich, den Befehl setpriv (1) zu verwenden .

dcoles
quelle