Wie kann ich eine Datei NICHT modifizierbar machen?

35

Während ich angemeldet bin, kann ich Folgendes tun:

mkdir foo
touch foo/bar
chmod 400 foo/bar 
chmod 500 foo

Dann kann ich vim öffnen (nicht als root), bearbeiten bar, einen Schreibvorgang erzwingen w!, und die Datei wird geändert.

Wie kann ich verhindern, dass das Betriebssystem Dateien ändert?

UPDATE 02.03.2017

  1. chmod 500 fooist ein roter Hering: Die Schreibberechtigung für ein Verzeichnis hat nichts mit der Fähigkeit zu tun, den Inhalt einer Datei zu ändern - nur mit der Fähigkeit, Dateien zu erstellen und zu löschen.

  2. chmod 400 foo/barverhindert jedoch, dass der Inhalt der Datei geändert wird. Dies verhindert jedoch nicht, dass die Berechtigungen einer Datei geändert werden. Der Eigentümer einer Datei kann die Berechtigungen seiner Datei jederzeit ändern (vorausgesetzt, er kann auf die Datei zugreifen, dh die Berechtigung für alle Ahnenverzeichnisse ausführen). Tatsächlich zeigt strace (1), dass vim (7.4.576 Debian Jessie) dies tut - vim ruft chmod (2) auf, um vorübergehend die Schreibberechtigung für den Eigentümer der Datei hinzuzufügen, ändert die Datei und ruft dann chmod ( 2) erneut, um die Schreibberechtigung zu entfernen. Deshalb chattr +ifunktioniert using - nur root kann callen chattr -i. Theoretisch könnte vim (oder ein anderes Programm) mit chattr dasselbe tun wie mit chmod für eine unveränderliche Datei, wenn es als root ausgeführt wird.

user2141130
quelle
3
Ich glaube unter der Haube, vimist eigentlich das Ändern der Berechtigungen und dann das Zurücksetzen.
Jordanien
Laufen Sie nicht als root?
Alvin Wong
Alvin, ich mache das als Nicht-Root-Benutzer. Ich habe den Beitrag zur Klarstellung bearbeitet.
user2141130

Antworten:

49

Sie können das Attribut "unveränderlich" für die meisten Dateisysteme unter Linux festlegen.

chattr +i foo/bar

Um das unveränderliche Attribut zu entfernen, verwenden Sie -anstelle von +:

chattr -i foo/bar

Um die aktuellen Attribute für eine Datei anzuzeigen, können Sie lsattr verwenden:

lsattr foo/bar

Die Hilfeseite chattr (1) enthält eine Beschreibung aller verfügbaren Attribute. Hier ist die Beschreibung für i:

   A  file with the `i' attribute cannot be modified: it cannot be deleted
   or renamed, no link can be created to this file  and  no  data  can  be
   written  to  the  file.  Only the superuser or a process possessing the
   CAP_LINUX_IMMUTABLE capability can set or clear this attribute.
Jordanien
quelle
3
Unter Linux ist dieses unveränderliche Flag auf vielen Dateisystemen verfügbar, nicht nur auf ext2 / 3/4 (zumindest BTRFS, HFSplus, JFS, NILFS2, XFS, OCFS2, UBIFS, GFS2, REISERFS AFAICT von einem kurzen Blick durch den Code)
Stéphane Chazelas
@StephaneChazelas Ich habe gesehen, dass der chattrBefehl Teil des e2fsprogsPakets auf meinem System ist. Deshalb habe ich diese Aussage gemacht. Ich habe die Antwort basierend auf Ihrem Kommentar aktualisiert.
Jordanien
Es funktioniert nicht für Symlinks :-(. Diese Lösung wäre großartig, weil ich vermeiden möchte, dass der Symlink von jedem Benutzer, einschließlich root , versehentlich geändert werden kann.
natenho
Unveränderlich ist ein Inode-Flag korrekt, kein Xattr? ioctl flag um genau zu sein?
Ytpillai
1

Sie können:

  1. Ändern Sie den Dateieigentümer in rootoder in einen Dummy-Benutzer, der neu erstellt wurde
  2. Behalte die richtige Gruppe.
  3. Verwenden Sie chmod 440diese Option , um das Lesen nach Gruppe (die Sie sind) zuzulassen.

Wenn der richtige Benutzer nicht der einzige in dieser Gruppe ist, sollten Sie eine neue Gruppe erstellen und nur ihn hinzufügen und diese Gruppe dafür verwenden. Sie sind jedoch nicht der Eigentümer der Datei. Daher vikönnen Sie den Eigentümer der Datei nicht ändern.

yo '
quelle
3
Wenn Sie in das übergeordnete Verzeichnis schreiben können, kann vim die Datei löschen und eine neue erstellen (und genau das tun Sie, wenn Sie dies tun :w!). vim geht jedoch nicht so weit, die Berechtigungen des Verzeichnisses vorübergehend zu ändern. Daher sollte es sicher sein, das Verzeichnis nicht beschreibbar zu halten.
Stéphane Chazelas
0

So machen Sie einen gesamten Verzeichnisbaum schreibgeschützt:

cd <directory>
find ./ -print0 | sudo xargs -I {} -0 chattr +i {}

Um es wieder lesbar zu machen, wechseln Sie +izu -i.

Robin A. Meade
quelle