Aus Gründen der Konfigurationsüberwachung möchte ich in der Lage sein, mein ext3-Dateisystem nach Dateien zu durchsuchen, für die das unveränderliche Attribut (über chattr +i
) festgelegt wurde. Ich kann keine Optionen für find
oder ähnliches finden, die dies tun. Zu diesem Zeitpunkt muss ich leider mein eigenes Skript schreiben, um die lsattr
Ausgabe für jedes Verzeichnis zu analysieren . Gibt es ein Standarddienstprogramm, das einen besseren Weg bietet?
17
Antworten:
Dies kann teilweise durch Weiterleiten des
grep
Befehls an denlsattr
Befehl erreicht werden.Aber ich glaube , wenn Sie die gesamte erwähnen
ext3
Dateisystem die Suche einbeziehen könnte/proc
,/dev
und einige andere Verzeichnisse , die , wenn die Berichte einige Fehler einfach ignorieren wollen. Sie können den Befehl wahrscheinlich wie folgt ausführen:Vielleicht möchten Sie das
grep
ein bisschen strenger machen, indem Sie diegrep
PCRE-Funktion von verwenden , um das "-i-" expliziter abzugleichen.Dies funktioniert dann für Situationen wie diese:
Ist aber unvollkommen. Wenn um das unveränderliche Flag herum zusätzliche Attribute aktiviert sind, werden diese nicht abgeglichen, und dies wird durch Dateien verfälscht, deren Namen ebenfalls mit dem obigen Muster übereinstimmen, z.
Wir können das Muster etwas enger fassen:
Aber es ist immer noch ein bisschen zu zerbrechlich und würde zusätzliche Anpassungen abhängig von den Dateien in Ihrem Dateisystem erfordern. Ganz zu schweigen von @StephaneChazeles , der in Kommentaren erwähnt hat, dass dies ziemlich einfach durch das Einfügen von Zeilenumbrüchen mit einem Dateinamen gespielt werden kann, um das obige Muster zu umgehen
grep
.Verweise
https://groups.google.com/forum/#!topic/alt.os.linux/LkatROg2SlM
quelle
-i-
im Namen enthalten sind (auf dem System, auf dem ich gerade angemeldet bin, befinden sich 34). Sie werden wahrscheinlich auch die-a
Option wollen+i
im ersten Beispiel stehen, nur aus Neugier ? Das funktioniert bei mir nicht. Das Greifen nach-i-
setzt außerdem voraus, dass die Attribute, die nebeni
(z. B.a
) angezeigt werden, nicht festgelegt sind.^....i
? Oder zumindest so etwas,^[^ ]*i
wenn sich diei
in einer anderen Position als der fünften befinden kann.Da der Zweck des Skripts die Prüfung ist, ist es besonders wichtig, mit beliebigen Dateinamen richtig umzugehen, z. B. mit Namen, die Zeilenumbrüche enthalten. Dies macht es unmöglich,
lsattr
mehrere Dateien gleichzeitig zu verwenden, da die Ausgabe vonlsattr
in diesem Fall mehrdeutig sein kann.Sie können jeweils eine Datei
find
abrufenlsattr
. Es wird allerdings ziemlich langsam.Ich empfehle, eine weniger launische Sprache wie Perl, Python oder Ruby zu verwenden und die Arbeit
lsattr
selbst zu erledigen.lsattr
führt einenFS_IOC_GETFLAGS
ioctl-Syscall aus und ruft die Inode-Flags der Datei ab . Hier ist ein Python Proof-of-Concept.quelle
FS_IOC_GETFLAGS
ist0x80046601
.FS_IOC_GETFLAGS
abhängig vonsizeof(long)
. Siehe zB den folgenden Befehl bash , um herauszufinden , was das Makro erweitert , um in C:gcc -E - <<< $'#include <linux/fs.h>\nFS_IOC_GETFLAGS' | tail -n1
. Ich habe daraus folgenden Ausdruck bekommen:,(((2U) << (((0 +8)+8)+14)) | ((('f')) << (0 +8)) | (((1)) << 0) | ((((sizeof(long)))) << ((0 +8)+8)))
der sich vereinfacht(2U << 30) | ('f' << 8) | 1 | (sizeof(long) << 16)
.Um mit beliebigen Dateinamen (einschließlich solcher mit Zeilenvorschubzeichen) umzugehen, besteht der übliche Trick darin, Dateien darin zu finden,
.//.
anstatt.
. Da//
dies normalerweise beim Durchlaufen des Verzeichnisbaums nicht der Fall sein kann, sind Sie sicher, dass a//
den Beginn eines neuen Dateinamens in derfind
(oder hierlsattr -R
) Ausgabe signalisiert .Beachten Sie, dass die Ausgabe weiterhin durch Zeilenumbrüche getrennt ist. Wenn Sie es nachbearbeiten müssen, müssen Sie es anpassen. Zum Beispiel könnten Sie ein hinzufügen
-v ORS='\0'
, um es GNUs zuzuführenxargs -r0
.Beachten Sie auch, dass
lsattr -R
(mindestens 1.42.13) die Flags von Dateien, deren Pfad größer als PATH_MAX ist (normalerweise 4096), nicht gemeldet werden können. Daher kann jemand eine solche unveränderliche Datei ausblenden, indem er das übergeordnete Verzeichnis (oder eine der Pfadkomponenten, zu denen sie führen) verschiebt es, außer sich selbst als unveränderlich) in ein sehr tiefes Verzeichnis.Ein Workaround wäre zu verwenden
find
mit-execdir
:Nun, mit
-print0
, das ist nachbearbeitbar, aber wenn Sie irgendetwas mit diesen Pfaden machen wollen, beachten Sie, dass jeder Systemaufruf auf Dateipfaden, die größer als PATH_MAX sind , immer noch fehlschlagen würde und Verzeichniskomponenten in dem Intervall umbenannt werden könnten.Wenn wir einen zuverlässigen Bericht über einen Verzeichnisbaum erhalten möchten, der möglicherweise von anderen beschrieben werden
lsattr
kann, müssen wir noch einige weitere Probleme erwähnen, die mit dem Befehl selbst verbunden sind:lsattr -R .
der Verzeichnisbaum durchquert wird, unterliegt den Wettkampfbedingungen. Man kann es zu Verzeichnissen außerhalb des Verzeichnisbaums bringen, an den weitergeleitet wird,.
indem man im richtigen Moment einige Verzeichnisse durch Symlinks ersetzt.lsattr -d file
eine Rennbedingung. Diese Attribute gelten nur für reguläre Dateien oder Verzeichnisse. Solsattr
funktioniert einlstat()
erstes zu prüfen, ob die Datei der richtigen Arten ist und dann nichtopen()
gefolgt ,ioctl()
die Attribute abzurufen. Aber es ruftopen()
ohneO_NOFOLLOW
(noch O_NOCTTY) auf. Jemand könnte durchfile
einen Symlink zum/dev/watchdog
Beispiel zwischenlstat()
und ersetzenopen()
und einen Neustart des Systems veranlassen. Es sollte alsoopen(O_PATH|O_NOFOLLOW)
gefolgt werdenfstat()
,openat()
undioctl()
hier um die Rennbedingungen zu umgehen.quelle
Vielen Dank an Ramesh, slm und Stéphane, die mich in die richtige Richtung gelenkt haben (mir hat der
-R
Schalter gefehltlsattr
). Leider hat bisher keine der Antworten für mich richtig funktioniert.Ich habe mir folgendes ausgedacht:
Dies schützt vor Zeilenumbrüchen, die verwendet werden, um eine Datei unveränderlich erscheinen zu lassen, wenn dies nicht der Fall ist. Es schützt nicht vor Dateien, die unveränderlich sind und deren Dateinamen Zeilenumbrüche enthalten. Da eine solche Datei jedoch von root auf diese Weise erstellt werden müsste, kann ich mir sicher sein, dass solche Dateien in meinem Dateisystem für meinen Anwendungsfall nicht vorhanden sind. (Diese Methode ist nicht für die Erkennung von Eindringlingen geeignet, wenn der Root-Benutzer möglicherweise kompromittiert wird. In diesem Fall wird jedoch nicht das
lsattr
Dienstprogramm des gleichen Systems verwendet, das auch demselben Root-Benutzer gehört.)quelle
Die Verwendung von
find -exec
ist zu langsam, die Analyse der Ausgabe vonlsattr
ist unzuverlässig, ähnlich wie bei derls
Verwendung von Python. In der Antwort von Gilles muss die Konstante ausgewählt werden,ioctl
je nachdem, ob der Python-Interpreter 32- oder 64-Bit ist.Das Problem ist mehr oder weniger auf niedriger Ebene, also lasst uns auf niedriger Ebene gehen: C ++ ist nicht so schlecht als Skriptsprache :) Als Bonus hat es Zugriff auf System-C-Header mit der vollen Leistung des C-Präprozessors.
Das folgende Programm sucht nach unveränderlichen Dateien, die sich innerhalb eines Dateisystems befinden, dh niemals Mount-Punkte überschreiten. Entfernen Sie die
FTW_MOUNT
Markierung imnftw
Aufruf , um den sichtbaren Baum zu durchsuchen und die Einhängepunkte nach Bedarf zu kreuzen . Es folgen auch keine Symlinks. Entfernen Sie die Markierung, um ihnen zu folgenFTW_PHYS
.quelle
Warum nicht einfach awk verwenden, um nur das 'i' im ersten Feld der Ausgabe abzugleichen, anstatt die Ausgabe an grep weiterzuleiten?
Tatsächlich führe ich dies täglich über cron aus, um das Verzeichnis / etc auf Hunderten von Servern zu scannen und die Ausgabe an syslog zu senden. Ich kann dann einen täglichen Bericht über Splunk erstellen:
quelle
/etc
. Beide Befehle finden jedoch fälschlicherweise eine nicht unveränderliche Datei, die mittouch `"echo -e "bogus\n---------i---e-- changeable"`"
touch "`echo -e 'bogus\n---------i---e-- changeable'`"
Ganz einfach, gehen Sie in den verdächtigen Ordner und führen Sie den Befehl aus:
quelle