Wie kann verhindert werden, dass chgrp "setuid bit" löscht?

8

Wir haben RH-basierte Linux-Images. auf die ich ein "spezielles Archiv" "anwenden" muss, um sie auf die neueste Entwicklungsversion unseres Produkts zu aktualisieren.

Die Person, die das Archiv erstellt hat, hat festgestellt, dass in unserem Basis-Image einige Berechtigungen falsch sind. Also wurde uns gesagt, wir sollen rennen

sudo chgrp -R nobody /whatever

Wir haben das gemacht; und später, wenn unsere Anwendung ausgeführt wird, traten dunkle Probleme auf.

Was ich später auf: der Aufruf an chgrp wird klar die setuid Bit Informationen über unsere Programme in / was auch immer.

Und das eigentliche Problem ist: Einige unserer Binärdateien müssen dieses Setuid-Bit gesetzt haben, um richtig zu funktionieren.

Lange Rede, kurzer Sinn: Gibt es eine Möglichkeit, diesen "chgrp" -Befehl auszuführen, ohne meine Setuid-Bits zu töten?

Ich habe gerade Folgendes auf meinem lokalen Ubuntu ausgeführt: was zum gleichen Ergebnis führt:

mkdir sticky
cd sticky/
touch blub
chmod 4755 blub 
ls -al blub 

-> zeigt mir den Dateinamen mit rotem Hintergrund -> also, yep, setuid

chgrp -R myuser .
ls -al blub 

-> zeigt mir den Dateinamen ohne roten Hintergrund -> setuid ist weg

GhostCat begrüßt Monica C.
quelle
1
Das 4XXXBit heißt setuid bit ( s) und ist nicht klebrig. Sticky ist das tbisschen und sein Zweck ist ein wenig anders: en.wikipedia.org/wiki/Sticky_bit
zuazo
2
(1) Sie setzen das setuidBit, nicht das stickyBit. (2) Löschen Sie das setuidBit nicht, wenn Sie ein Sicherheitsproblem haben chgrpoder dies chownwäre.
Satō Katsura
1
Dieses Verhalten ändert sich zwischen den Verteilungen. Wie hier erläutert , hängt die Änderung des Setuid-Bits vom zugrunde liegenden Syscall-Verhalten ab.
Zuazo
Danke an alle. Sie haben Recht, hier geht es um das Setuid-Bit! Danke für Ihre Hilfe. Und ich akzeptiere auch, dass dies "funktioniert wie geplant" ist. Jetzt muss ich nur noch den vernünftigsten Weg finden, um das zu tun, was getan werden muss, ohne diese Teile zu töten. Ich denke darüber nach, gefacl zu verwenden, um einen Text-Dump zu erstellen, die Text-Konfiguration zu überarbeiten und diesen dann anzuwenden. Das sollte mir die volle Kontrolle darüber geben, was passieren wird.
GhostCat begrüßt Monica C.

Antworten:

7

Wenn Sie Ihre implementieren möchten, chgrp -R nobody /whateverwährend Sie das setuid-Bit beibehalten, können Sie diese beiden findBefehle verwenden

find /whatever ! -type l -perm -04000 -exec chgrp nobody {} + \
                                      -exec chmod u+s {} +
find /whatever ! -type l ! -perm -04000 -exec chgrp nobody {} +

Die find ... -perm 04000Option nimmt Dateien mit gesetztem Setuid-Bit auf. Der erste Befehl wendet dann das chgrpund dann a chmodan, um das abgeschlagene Setuid-Bit wiederherzustellen. Die zweite gilt chgrpfür alle Dateien, die kein Setuid-Bit haben.

In jedem Fall möchten Sie keine Symlinks aufrufen chgrpoder aufrufen, chmodda dies sich stattdessen auf deren Ziele auswirken würde, daher die ! -type l.

Roaima
quelle
Beachten Sie, dass dadurch chgrpauch das Setgid-Bit (und die Funktionen unter Linux) gelöscht werden, das möglicherweise ebenfalls wiederhergestellt werden muss.
Stéphane Chazelas
@ StéphaneChazelas du hast recht, aber da niemand setgid erwähnt hat, habe ich mir keine Sorgen gemacht, eine Lösung dafür zu finden. Die Lösung ist jedoch trivial erweiterbar, mit einem drittenfind
Roaima
Nun, es kann kein dritter Fund sein, du müsstest die Fälle u + g, u alleine, g alleine abdecken. In jedem Fall sollten Sie dies in einem findAufruf tun können . Ich mag die langen Zeilen in SE nicht, wenn Sie den Text scrollen müssen. Mein Hinzufügen der! -Typ Ich habe es über den Rand gebracht
Stéphane Chazelas
Nun, der eine findAnsatz mit -exec +kann schwierig sein, wenn dies dazu führt, dass die chmod/ chgrps in mehrere Aufrufe aufgeteilt werden.
Stéphane Chazelas
1
Eigentlich denke ich find . ! -type l -exec chgrp nobody {} + \( -perms -6000 -exec chmod gu+s {} + -o -perms -4000 -exec chmod u+s {} + -o -perms -2000 -exec chmod g+s {} + \)sollte OK sein. Da die chgrpÜbereinstimmungen für mehr Dateien gelten, sollte dies für jede Datei vor dem chmods erfolgen.
Stéphane Chazelas
5

Das Löschen von SUID- und SGID-Bits auf chgrp(oder chown) ist durchaus sinnvoll. Es ist eine Sicherheitsmaßnahme, um Sicherheitsprobleme zu vermeiden. Für SGID (auf ausführbaren Dateien, nehme ich an) bedeutet , dieses Programm mit der effektiven Gruppe des Gruppenbesitzers auszuführen .

Wenn Sie den Gruppeneigentümer ändern, ist dies in Bezug auf Sicherheit und Zugriffskontrolle etwas völlig anderes, dh anstatt mit einer effektiven Gruppe ausgeführt zu werden, wird uvwdas Programm jetzt mit einer effektiven Gruppe ausgeführt xyz.

Daher müssen Sie das SUID- oder SGID-Bit bei einem Eigentümerwechsel explizit wiederherstellen.

Nachtrag: Zu der Behauptung, dass chgrp (oder chown) nur SGID (bzw. SUID) löschen sollte.

Durch Ändern chownoder chgrpÄndern ändern Sie die Sicherheitseinstellung für eine ausführbare Datei. Dies ist ein ausreichender Grund, um alle Attribute zur Erhöhung von Berechtigungen zu löschen. Die Leistungsfähigkeit von Unix beruht auf konzeptioneller Einfachheit, und die Unix-Sicherheit ist bereits recht schwierig. Zu diesem Zweck ist das Entfernen von SUID und SGID bei jedem Eigentümerwechsel lediglich ein Sicherheitsnetz - schließlich gab es in der Geschichte von Unix / Linux einige Sicherheitslücken aufgrund fehlgeleiteter SUID- oder SGID-Einstellungen.

Es gibt also keinen tieferen Grund, warum sich Unix so verhält, es ist nur eine konservative Designentscheidung.

Gegenmodus
quelle
1
Dies erklärt perfekt, warum das Ändern des Besitzers das SUID-Bit löscht und das Ändern der Gruppe das SGID-Bit löscht. Die Frage bezieht sich jedoch auf das SUID-Bit während einer Gruppenänderungsoperation, die sich nicht auf den Benutzer auswirkt, unter dem SUID ausgeführt wird. Es muss also eine andere Erklärung geben.
Ben Voigt
1
@ BenVoigt: es erklärt es ziemlich gut. Sowohl chown als auch chgrp rufen den syscall chown () auf, der suid und sgid für reguläre Dateien löscht, egal was passiert.
Joshua
1
@ Joshua: Das ist eine Beschreibung. Die Erklärung lautet: "Um den Fall zu vermeiden, dass uvwdas Programm jetzt nicht mit einer effektiven Gruppe ausgeführt wird xyz, sondern mit einer effektiven Gruppe ", gilt dies jedoch nicht für den diskutierten Fall.
Ben Voigt
Es tut. Durch Ändern chownoder chgrpÄndern ändern Sie die Sicherheitseinstellung. Dies ist ein ausreichender Grund, um Attribute zur Erhöhung von Berechtigungen zu löschen. Die Chancen stehen gut, dass dies sonst die Unachtsamen trifft.
Gegenmodus
4

Das Löschen der setuid, setgidBit (zumindest unter Linux) auf nicht-Verzeichnissen wird vom Kernel auf dem getan chown()Systemaufruf durch getan chgrp, nicht von chgrpselbst. Die einzige Möglichkeit besteht darin, es anschließend wiederherzustellen.

Außerdem werden die Sicherheitsfunktionen gelöscht.

Also, unter GNU Linux:

chown_preserve_sec() (
  newowner=${1?}; shift
  for file do
    perms=$(stat -Lc %a -- "$file") || continue
    cap=$(getfattr -m '^security\.capability$' --dump -- "$file") || continue
    chown -- "$newowner" "$file" || continue
    [ -z "$cap" ] || printf '%s\n' "$cap" | setfattr --restore=-
    chmod -- "$perms" "$file"
  done
)

Und laufe (as root):

chown_preseve_sec :newgroup file1 file2...

um die Gruppe zu ändern, während versucht wird, die Berechtigungen beizubehalten.

Rekursiv könnten Sie tun:

# save permissions (and ACLs). Remove the "# owner" and "# group" lines
# to prevent them being restored!
perms=$(getfacl -RPn . | grep -vE '^# (owner|group): ')
# save capabilities
cap=$(getfattr -Rhm '^security\.capability$' --dump .)

chgrp -RP nobody .

# restore permissions, ACLs and capabilities
printf '%s\n' "$perms" | setfacl --restore=-
[ -z  "$cap" ] || printf '%s\n' "$cap" | setfattr -h --restore=-

(Das alles setzt voraus, dass nichts gleichzeitig die Dateien durcheinander bringt).

Stéphane Chazelas
quelle
1

Wie bei der Verwaltung üblich, gibt es viele Möglichkeiten.

Die Lösung, die ich eingeführt habe, sieht folgendermaßen aus:

cd /home/me
getfacl -R /whatever > whatever-permissions.org 2> /dev/null

# A) change lines starting with      # group: root
# to                                 # group: whatineed
sed 's/^# group: root/# group: whatineed/g' whatever-permissions.org > whatever-permissions.new

# B) change lines with               group::x.y
# to                                 group::xwy
# (where x, y mean: whatever was there before)
sed 's/^group::\(.\).\(.\)/group::\1w\2/g' whatever-permissions.new > whatever-permissions.new

cd /
setfacl --restore /home/me/whatever-permissions.new
GhostCat begrüßt Monica C.
quelle