Wie kann verhindert werden, dass sudo-Benutzer bestimmte Befehle ausführen?


29

Ich habe ein sehr sensibles Netzwerk-Setup und möchte es nicht vermasseln. Mein Netzwerk besteht aus einer Reihe von Benutzern mit Sudo-Rechten.

Ich möchte sie davon abhalten zu rennen

service NetworkManager restart
service network restart

befehle.

Kann ich das auf irgendeine Weise erreichen?


Welche Distribution benutzt du? Die Dienstnamen sind distro-spezifisch und ich kenne keine Distribution, die die Namen verwendet, die Sie dort haben. Meinen Sie networkingund network-manager? Warum haben Ihre Benutzer sudoZugriff? Sie sollten es nicht tun, es sei denn, Sie möchten, dass sie über vollständige Root-Berechtigungen verfügen.
Terdon

@terdon Ich habe es gelöst. Vielen Dank. Ich kann es nicht als Antwort posten, weil ich ein neuer Benutzer bin
shekhar

Ja, das kannst du, bitte tu es. Ich würde auch gerne die Antwort wissen, die Sie gefunden haben.
Terdon

@ Sicher, aber es heißt, ich muss 8 Stunden warten, um meine eigene Antwort zu veröffentlichen, weil ich nicht einmal 10 Ruf habe
Shekhar

1
Ah, ja, sorry, du musst in der Tat warten. Ich habe gerade upvoted, Sie haben den Repräsentanten jetzt :)
Terdon

Antworten:


47

Die Verwendung von CmndAlias ALLwird niemals sicher sein

Es gibt 1000 Möglichkeiten, service network restartohne es zu tun sudo service network restart. Hier ist ein Beispiel, was ein ungezogener Benutzer versuchen könnte:

$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax

Wenn Sie Benutzern den ALLBefehlsalias bereitstellen und dann versuchen, eine schwarze Liste zu erstellen, können sie sich immer daran orientieren. Blacklist Bash, und sie werden Python verwenden. Blacklist Python, und sie werden Perl verwenden. Blacklist Perl, und sie werden PHP verwenden. Niemand will das!

Wenn Sie nicht wirklich jemand etwas tun wollen, sollten Sie tun , wie Thomas sagt, und erstellen Sie eine weiße Liste von Dingen , die sie sind erlaubt zu tun.


Einrichten einer Whitelist mit einer Ausnahme

Ein Beispiel für eine kleine Whitelist mit einem Ausschluss befindet sich unten in man sudoers:

 pete           HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root

The user pete is allowed to change anyone's password except for root on the HPPA
machines.  Note that this assumes passwd(1) does not take multiple user names
on the command line.

(Tatsächlich ist dieses Beispiel auf der Manpage unsicher und kann ausgenutzt werden, um das root-Passwort zu ändern. Siehe die Kommentare unten für wie.)

Wir können versuchen, dies an Ihren Fall anzupassen, um der Stabgruppe alle serviceBefehle anzubieten , aber die Sie betreffenden Befehle ausschließenservice network :

%staff ALL =   /usr/sbin/service *,                            \
             ! /usr/sbin/service *network*,                    \
             ! /usr/sbin/service *NetworkManager*

(Die ALLin dieser Position bezieht sich auf die Host_Alias, nicht die Cmnd_Alias ​​- verwirrend, nicht wahr?)

Der Benutzer kann sudo bashoder sudo teeoder sudo wgetoder nicht ausführen sudo /path/to/malicious_script. Sie können weitere Administrationsbefehle für Ihre Benutzer auf die Positivliste setzen, wenn Sie vorsichtig sind. Sei einfach konkret!

Hinweis: Ich habe das *vor dem networkobigen Wort hinzugefügt , nur für den Fall, dass dem serviceTool in Zukunft jemals ein harmloses Flag hinzugefügt wird. Stellen wir uns vor, dass --verbosein Zukunft ein Flag hinzugefügt wurde, dann könnten die Benutzer Folgendes ausführen:

$ sudo service --verbose network restart

Wir müssen also *alle Flags vor dem Dienstnamen konsumieren. Der einzige Nachteil ist , dass diese andere Dienste blockieren könnten , die Sie eigentlich gar nicht genannt Benutzer ausgeführt wird , zB ein Dienst dagegen safe-networkoder network-monitorauch abgelehnt werden würde.


Ermöglichen Sie Benutzern das Bearbeiten einer Datei mit Gruppenberechtigungen

Im Folgenden finden Sie verschiedene Versuche, mit rnanoHilfe sudovon eine oder mehrere Dateien zu bearbeiten. Aber in Wirklichkeit sind sie komplexer und gefährlicher als sie sein sollten.

Eine viel einfachere und sicherere Lösung besteht darin, die Gruppenberechtigungen für die spezifischen Dateien zu ändern, für die Sie Bearbeitungsrechte öffnen möchten. Hier einige Beispiele:

### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project

### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website

Wenn Sie eine differenziertere Steuerung benötigen (z. B. Zugriff für nur 3 Benutzer, aber nicht alle Mitarbeiter), können Sie mit dem addgroupBefehl eine neue Gruppe erstellen und dieser nur wenige Benutzer hinzufügen.


Lassen Sie Benutzer eine Datei bearbeiten sudo

Der Rest dieser Antwort wurde zu einer Untersuchung darüber, wie einfach es ist, Lücken in Ihrer sudoKonfiguration zu hinterlassen, wenn Sie Ihren Benutzern Flexibilität bieten möchten. Folgendes würde ich nicht empfehlen!

Wenn Sie Ihren Benutzern den Zugriff zum Bearbeiten einer bestimmten Datei gewähren möchten, können Sie versuchen, Folgendes zu verwenden rnano:

%staff ALL = /bin/rnano /etc/nginx/sites-available/host

rnanoLässt sie nur die angegebene Datei bearbeiten. Dies ist wichtig, um zu verhindern, dass ein böswilliger Benutzer beispielsweise einen anderen Startdienst bearbeitet /etc/init.d/urandomund eine Zeile hinzufügt, die ausgeführt wird service network restart.

Leider habe ich keinen Weg gefunden, um rvimausreichend einzuschränken (der Benutzer kann noch jede Datei mit öffnen :e), so dass wir bei stecken bleiben nano.

Leider ist es viel schwieriger, Benutzern das Bearbeiten mehrerer Dateien zu ermöglichen ...


Lassen Sie die Benutzer mehrere Dateien bearbeiten (viel schwieriger als es sein sollte)

1. Unsichere Ansätze

Passen Sie auf Wildcards auf! Wenn Sie zu viel Flexibilität bieten (oder eine beliebige Flexibilität), kann dies ausgenutzt werden:

%staff ALL = /bin/rnano /etc/nginx/sites-available/*                # UNSAFE!

In diesem Fall kann ein böswilliger Benutzer ein beliebiges anderes Skript für den Upstart-Dienst bearbeiten und dann ausführen:

$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system

(Sudo verhindert .und ..erweitert den Befehl, aber leider nicht die Argumente.)

Ich hatte gehofft, dass so etwas funktioniert, aber es ist immer noch unsicher:

%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]*   # UNSAFE!

Da sudoderzeit nur Glob- Muster angeboten werden , *die zu nichts passen, handelt es sich nicht um einen regulären Ausdruck!

(Edit: Ich habe darüber nachgedacht, ob Sie in Ihrer Situation mit dem oben Gesagten durchkommen könnten , da sich keine Unterordner darunter befinden sites-available. Wir haben verlangt, dass ein Zeichen nach dem Ordner abgeglichen wird und /..nach einem Dateinamen fehlschlägt. Dies ist jedoch kein praktikable Lösung, da rnanomehrere Argumente akzeptiert werden. Und im Allgemeinen wäre dies in einem Ordner mit Unterordnern immer noch unsicher !)

Selbst wenn wir keine Unterordner haben und alle Zeilen ausschließen /../, die einen *Glob enthalten , kann die Regel, die einen Glob anbietet, dennoch ausgenutzt werden, da rnanomehrere Argumente akzeptiert werden (durchlaufen <C-X>, und das Leerzeichen wird vom *Glob gerne akzeptiert .

$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system

2. Schieben des Umschlags (auch letztendlich unsicher)

Was ist, wenn wir Zeilen ablehnen, die Leerzeichen enthalten, oder versuchen zu erreichen /..? Dann könnte eine endgültige praktikable Lösung sein:

# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.

%staff ALL =   /bin/rnano /etc/nginx/sites-available/*,    \
             ! /bin/rnano */..*,                           \
             ! /bin/rnano /etc/nginx/sites-available/,     \
             ! /bin/rnano */.,                             \
             ! /bin/rnano * *

# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.

Wir nehmen alles „unter“ dem Ordner , aber wir lehnen auch alle Anrufe an , rnanowenn /..oder /.oder weitergegeben werden, oder wenn der Ordner direkt angestrebt. (Technisch /.macht der /..Ausschluss den Ausschluss überflüssig, aber ich habe beide aus Gründen der Klarheit belassen.)

Ich habe den Ordner gefunden, und die /.Ausschlüsse wurden benötigt, da der Benutzer sonst auf den Ordner selbst abzielen könnte. Jetzt könnten Sie denken, rnanowürde blockieren, wenn auf einen Ordner verwiesen, aber Sie wären falsch. Tatsächlich startet meine Version (2.2.6-1ubuntu1) mit einer milden Warnung und einer leeren Datei, und <C-X>fordert mich dann auf , einen beliebigen Dateinamen einzugeben, unter dem ich speichern möchte. Dadurch wird ein neuer Angriffsvektor geöffnet! Nun, zumindest hat es sich geweigert, eine vorhandene Datei zu überschreiben (in dem einen Test, den ich durchgeführt habe). Wie auch immer, da es keine Möglichkeit gibt, Unterordner mit sudo auf die schwarze Liste zu setzen, müssen wir den Schluss ziehen, dass dieser Ansatz erneut unsicher ist. Sorry Benutzer!

Diese Entdeckung ließ mich an der Gründlichkeit des nano"eingeschränkten" Modus zweifeln . Sie sagen, eine Kette sei nur so stark wie ihr schwächstes Glied. Ich fange an, die Kombination von sudoschwarzer Magie zu spüren und bin rnanovielleicht nicht sicherer als eine Kette von Gänseblümchen.

3. Sichere, aber begrenzte Ansätze

Globs sind sehr eingeschränkt - sie lassen uns nicht mehrere Male mit einer Charakterklasse übereinstimmen. Sie können mehrere Dateibearbeitungen anbieten, wenn alle Dateinamen dieselbe Länge haben (in diesem Fall hostgefolgt von einer einzelnen Ziffer):

%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9]       # SAFE

Wenn Sie dem Benutzer jedoch den Zugriff zum Bearbeiten verschiedener Dateien gewähren möchten, müssen Sie möglicherweise jede einzelne Datei explizit angeben:

%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost    \
             /bin/rnano /etc/nginx/sites-available/coldhost   \    # SAFE
             /bin/rnano /etc/nginx/sites-available/wethost    \
             /bin/rnano /etc/nginx/sites-available/steves_dodgy_project

Seien Sie zu*keinem Zeitpunkt versucht , azu verwenden. Lesen Sie in den Abschnitten 1. und 2. nach, warum! Denken Sie daran: Ein kleiner Fehler kann das gesamte Superuser-Konto und das gesamte System gefährden.

4. Schreiben Sie Ihren eigenen Argumentationsprüfer (Sicherheit liegt jetzt in Ihrer Verantwortung)

Ich hoffe, dass sie in Zukunft die Unterstützung für reguläre Ausdrücke erweitern sudowerden. es könnte eine Menge Probleme lösen, wenn es richtig verwendet wird. Möglicherweise müssen wir aber auch die Eigenschaften von Argumenten überprüfen können (um nur Dateien, nur Ordner oder nur bestimmte Flags zuzulassen).

Es gibt jedoch eine Alternative, um in sudo Flexibilität zu schaffen. Übergeben Sie das Geld:

%staff ALL = /root/bin/staffedit *

Schreiben Sie dann ein eigenes staffeditSkript oder eine ausführbare Datei, um zu überprüfen, ob die vom Benutzer übergebenen Argumente zulässig sind, und führen Sie die Anforderung nur aus, wenn dies der Fall ist.


5
Diese Antwort hat lange gedauert, aber schließlich glaube ich zu verstehen, wie sudo funktioniert. Ich habe in der Vergangenheit bei verschiedenen Gelegenheiten aufgegeben und festgestellt, dass es ALL=(ALL:ALL) ALLzu wenig Semantik gibt, aber ich bin immer davon ausgegangen, dass es irgendwo einen anständigen Argumentationsprüfer gibt ... ich habe mich geirrt. Es ist wirklich sehr begrenzt. Sogar der in der Manpage angebotene passwd-Root-Ausschluss kann mit einem einfachen Befehlszeilenargument aufgehoben werden sudo passwd -q root. Nun, die Autoren von sudo listen [einige Alternativen] (sudo.ws/sudo/other.html) auf ihrer Website auf. Ich hoffe, sie werden in Zukunft RegExp-Unterstützung hinzufügen.
Joeytwiddle

Verwenden Sie rnanoin Ihrer Beschreibung hier speziell , weil es sich um eine Version von Nano handelt, der eine Funktion zum Speichern unter fehlt? Ich bin mit dem Programm nicht vertraut.
Shadur

Ja. Wenn uns die Sicherheit am Herzen liegt, sollte der Editor nur die eine angegebene Datei bearbeiten und keine Shell öffnen können. Für Infos $ man nanodann/-R<Enter>
joeytwiddle

Korrektur: Um die pete Beispiel zu brechen, die -qmüssen kommen danach: sudo passwd root -q. Das Petebeispiel kann durch Ausschließen gehärtet werden *root*.
Joeytwiddle

Erwägen Sie die Verwendung sudoeditvon, um die Dateimodifikation mit sicher zu aktivieren sudo.
Totor

5

Öffnen Sie zunächst die sudoers-Datei mit sudo visudo. Das Hinzufügen von user ALL=!/usr/sbin/serviceWillen, IIRC, verbietet dasservice Befehl für den Benutzer nicht zugelassen user.

Quellen: http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell


Dadurch werden auch andere Dienste nicht mehr ausgeführt, und das möchte ich nicht. Danke für die Antwort. :)
Shekhar

Ihre Antwort hat mir zwar nicht genau geholfen, aber es hat geholfen, eine Lösung zu finden. Vielen Dank. Aber du weißt, dass ich nicht genug Ansehen habe, um dich zu stimmen oder meine funktionierende Antwort zu posten. Ich werde mich sicher bedanken, wenn ich es bin. Vielen Dank.
Shekhar

2
Ja, aber trotzdem, wie andere gesagt haben, muss man sehr vorsichtig damit sein. Es gibt viele Möglichkeiten, um Zugriff zu erhalten. Jeder Befehl, der eine Shell erzeugen könnte, und so weiter. Es ist einfacher, herauszufinden, welche Befehle sie wirklich benötigen und zuzulassen, anstatt zu versuchen, alle "verbotenen" auszuschließen.
Bonsi Scott

3
Whitelists sind in vielen Szenarien nicht erreichbar. Das eigentliche Ziel ist vielleicht nicht, sie daran zu hindern , etwas zu tun, sondern sie daran zu hindern , versehentlich etwas Schlechtes zu tun, ohne sie anderweitig einzuschränken. Schwarze Listen sind in diesen Fällen gut. Sie können festlegen, wie ein vernünftiger Benutzer die Aufgabe ausführen würde. Eine schwarze Liste über sudo ist jedoch möglicherweise nicht ausreichend - die Benutzer können und tun dies mit 'sudo bash'. Ein Ansatz wäre, den Befehl 'service' zu beenden und sie in den Fällen, in denen Sie nicht möchten, dass sie ihn verwenden, zu informieren. Aber Sie werden niemals alle guten Aktionen in einer Whitelist oder alle schlechten in einer Blacklist auflisten.
Bob Kerns

1
Ich stimme dir zu, Bob. Um Flexibilität zu ermöglichen, ohne vollständigen Zugriff zuzulassen, müssen Sie häufig Ihre eigene Lösung als Hilfsskript erstellen und nur dieses Skript auf die Whitelist setzen. sudo-Whitelists tun möglicherweise das, was Sie benötigen, sind jedoch häufig entweder zu begrenzt oder zu einfach auszunutzen.
Joeytwiddle

5

Ich habe die Lösung gefunden.

Ich habe das Terminal geöffnet und mit in den Root-Benutzer su -gewechselt visudo, dann habe ich zum Bearbeiten getippt .

dann habe ich am ende zeilen wie geschrieben

user ALL=!/etc/init.d/NetworkManager restart
user ALL=!/etc/init.d/network restart

Dann habe ich gespeichert & geschlossen und auch neu gestartet.

Wenn ich schreibe als service network restartoder service NetworkManager restartdann ist es mir nicht erlaubt und ich gebe einen Fehler wie

Sorry user is not allowed to execute '/sbin/service NetowkrManager restart' as root on localhost.localdomain

und ähnlich für service network restartBefehl auch.


12
Das funktioniert für unerfahrene und nicht böswillige Benutzer, aber es ist leicht, Sudo-Beschränkungen zu umgehen (z . B. sudo cp -p /etc/init.d/network /etc/init.d/network-not-in-sudound dann sudo /etc/init.d/network-not-in-sudo restart). Aus diesem Grund ist es weitaus sicherer, Einschlüsse anstelle von Ausschlüssen in der sudoers-Datei zu erstellen, z. B. anzugeben, mit welchen Diensten sie interagieren dürfen.
Thomas

Alles, was "Neustart des Dienstnetzwerks" bewirkt, können Sie mit anderen Befehlen ausführen, z. B. den Befehlen im Skript "network init.d". Ich werde nicht einmal versuchen, sie hier aufzulisten. Wenn Sie beispielsweise Änderungen des Schnittstellenstatus tatsächlich verhindern möchten, scheint mir eine SELinux-Richtlinie der richtige Weg zu sein. Es ist ein komplexes Thema, aber wenn eine Whitelist zu restriktiv oder lästig ist und eine schwarze Liste nicht ausreicht, ist es wahrscheinlich die beste Option. Es ist im Kernel implementiert und ermöglicht es Ihnen, den Zugriff auf Netzwerkschnittstellen (und andere Ressourcen) auch auf Benutzer mit Sudo-Rechten zu beschränken.
Bob Kerns

Wenn es mit SELinux möglich ist, würde es mehr freuen. @ BobKerns Danke. Ich werde es so versuchen.
Shekhar

3

Die wirkliche Antwort darauf ist, dass Sie dies nicht wirklich verhindern können. Mit den in den anderen Antworten beschriebenen Methoden können Sie möglicherweise verhindern, dass jemand, der nicht böswillig ist, diesen Befehl versehentlich ausführt. Wenn jemand ihn jedoch wirklich ausführen möchte und auf der Liste der Sudoer steht, kann er ihn ausführen. Sie könnten beispielsweise Folgendes tun:

joe@box:~$ sudo bash root@box:~# service network restart

Oder ein anderer lustiger Befehl, mit dem die Einschränkungen in der sudoers-Datei umgangen werden können:

sudo visudo

Kurz gesagt, wenn Sie sudo können und nicht nur bestimmte Befehle ausführen können, können Sie so ziemlich alles tun, was Sie wollen. Selbst wenn Sie sie auf einen bestimmten Befehlssatz beschränken, müssen Sie sicherstellen, dass es dem Benutzer nicht möglich ist, einen anderen Befehl, den er ausführen möchte, auf denselben Namen zu kopieren, für den er die Berechtigung zum Ausführen hatte ( B. durch Überschreiben des Befehls, zu dessen Ausführung sie berechtigt sind.)


Ja. Man sollte Befehle vermeiden, die eine Shell von innen erzeugen können.
Bonsi Scott

1
Das Problem ist, dass Sie keine Befehle schützen möchten, sondern den Status von Kernelobjekten wie Routing-Tabellen, Schnittstellen usw. - unabhängig davon, welcher Befehl (oder welcher Systemaufruf) verwendet wird. Und Sie möchten es vor einigen, aber nicht allen Root-Benutzern schützen. SELinux ist auf diese Art von Szenario ausgelegt. Zunächst möchte ich jedoch untersuchen, warum alle diese Benutzer sudo-Zugriff haben. Wenn sie nur ein paar bestimmte Dinge erledigen müssen, sind Whitelisting-Vorgänge in sudoers möglicherweise alles, was Sie brauchen.
Bob Kerns

2

Verwenden Sie firejail, um Benutzer mit Sandboxen einzuschränken.

https://github.com/netblue30/firejail/

Setzen Sie firejail für jeden Benutzer, den Sie einschränken möchten, als Shell anstelle von bash in / etc / passwd. Es ist sehr einfach zu bedienen und hat eine gute Dokumentation.

Beispiel:

user:x:1000:1000:user:/home/user:/usr/bin/firejail
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.