Z przyczyn związanych z inspekcją konfiguracji chcę móc przeszukiwać mój system plików ext3 w poszukiwaniu plików, które mają niezmienny atrybut (via chattr +i
). Nie mogę znaleźć żadnych opcji find
podobnych lub podobnych. W tym momencie obawiam się, że będę musiał napisać własny skrypt, aby przeanalizować lsattr
dane wyjściowe dla każdego katalogu. Czy istnieje standardowe narzędzie, które zapewnia lepszy sposób?
17
Odpowiedzi:
Można to częściowo osiągnąć poprzez przekazanie
grep
polecenia dolsattr
polecenia.Uważam jednak, kiedy można wymienić cały
ext3
system plików poszukiwanie może wiązać/proc
,/dev
i kilka innych katalogów, które jeśli raportach jakiś błąd po prostu chcesz ignorować. Prawdopodobnie możesz uruchomić polecenie jakoByć może zechcesz
grep
nieco bardziej zaostrzyć, używając funkcjigrep
PCRE w celu wyraźniejszego dopasowania do „-i-”.Będzie to wtedy działać w takich sytuacjach:
Ale jest niedoskonały. Jeśli wokół niezmiennej flagi są włączone dodatkowe atrybuty, nie dopasujemy ich, a to zostanie oszukane przez pliki, których nazwy również pasują do powyższego wzorca, takie jak:
Możemy zaostrzyć wzór bardziej w ten sposób:
Ale wciąż jest zbyt delikatny i wymagałby dodatkowych poprawek w zależności od plików w systemie plików. Nie wspominając już o tym, jak @StephaneChazeles wspomniał w komentarzach, że można w to dość łatwo grać, włączając nowe linie z nazwą pliku, aby pominąć powyższy wzorzec
grep
.Bibliografia
https://groups.google.com/forum/#!topic/alt.os.linux/LkatROg2SlM
źródło
-i-
w nazwie (w systemie, na którym aktualnie jestem zalogowany, jest 34). Prawdopodobnie będziesz również chciał-a
opcję+i
ma być ten pierwszy przykład? To nie działa dla mnie. Ponadto grepping dla-i-
zakłada, że atrybuty, które pojawiają się oboki
(takie jaka
) są nieustawione.^....i
? Lub przynajmniej coś takiego,^[^ ]*i
jeślii
może być w innej pozycji niż piąta.Biorąc pod uwagę, że celem skryptu jest kontrola, szczególnie ważne jest prawidłowe postępowanie z dowolnymi nazwami plików, np. Z nazwami zawierającymi znaki nowej linii. Uniemożliwia to jednoczesne używanie
lsattr
wielu plików, ponieważlsattr
w takim przypadku wynik może być niejednoznaczny.Możesz powtarzać się
find
i wywoływaćlsattr
jeden plik naraz. Ale będzie dość wolno.Polecam używanie mniej zepsutego języka, takiego jak Perl, Python lub Ruby i
lsattr
samodzielne wykonywanie pracy .lsattr
działa poprzez wydanieFS_IOC_GETFLAGS
wywołania systemowego ioctl i pobranie flag i-węzłów pliku . Oto dowód koncepcji Pythona.źródło
FS_IOC_GETFLAGS
to0x80046601
.FS_IOC_GETFLAGS
zależy odsizeof(long)
. Patrz na przykład następujące polecenie bash, aby dowiedzieć się, co makro rozwija się w katalogu C:gcc -E - <<< $'#include <linux/fs.h>\nFS_IOC_GETFLAGS' | tail -n1
. Otrzymałem z niego następujące wyrażenie(((2U) << (((0 +8)+8)+14)) | ((('f')) << (0 +8)) | (((1)) << 0) | ((((sizeof(long)))) << ((0 +8)+8)))
:, które upraszcza(2U << 30) | ('f' << 8) | 1 | (sizeof(long) << 16)
.Aby poradzić sobie z dowolnymi nazwami plików (w tym zawierającymi znaki nowego wiersza), zwykłą sztuczką jest znajdowanie plików w środku
.//.
zamiast.
. Ponieważ//
normalnie nie może się zdarzyć podczas przeglądania drzewa katalogów, masz pewność, że//
sygnał wyjściowyfind
(lub tutajlsattr -R
) sygnalizuje początek nowej nazwy pliku .Zauważ, że wyjście nadal będzie oddzielone znakiem nowej linii. Jeśli musisz go przetworzyć później, musisz go dostosować. Na przykład, możesz dodać a,
-v ORS='\0'
aby móc karmić go GNUxargs -r0
.Zauważ również, że
lsattr -R
(przynajmniej 1.42.13) nie może zgłosić flag plików, których ścieżka jest większa niż PATH_MAX (zwykle 4096), więc ktoś może ukryć taki niezmienny plik, przenosząc jego katalog nadrzędny (lub dowolny ze składników ścieżki, które prowadzą do z wyjątkiem siebie, ponieważ jest niezmienny) do bardzo głębokiego katalogu.Obejściem byłoby użycie
find
z-execdir
:Teraz, z
-print0
, to jest przetwarzalne, ale jeśli zamierzasz cokolwiek zrobić z tymi ścieżkami, zwróć uwagę, że każde wywołanie systemowe na ścieżkach plików większych niż PATH_MAX nadal nie powiedzie się, a komponenty katalogu mogą zostać zmienione w przedziale czasowym.Jeśli mamy uzyskać rzetelny raport o drzewie katalogów, który może zostać zapisany przez innych, istnieje kilka innych problemów związanych z samym
lsattr
poleceniem, o których powinniśmy wspomnieć:lsattr -R .
przechodzenia przez drzewo katalogów, podlega warunkom wyścigu. Można sprawić, że zejdzie do katalogów spoza drzewa katalogów kierowanych do.
, zastępując niektóre katalogi dowiązaniami symbolicznymi w odpowiednim momencie.lsattr -d file
ma nawet warunki wyścigowe. Te atrybuty mają zastosowanie tylko do zwykłych plików lub katalogów. Taklsattr
robilstat()
najpierw sprawdzić, czy plik ma odpowiednich typów i wtedy nieopen()
następujeioctl()
do pobierania atrybutów. Ale wywołujeopen()
bezO_NOFOLLOW
(ani O_NOCTTY). Ktoś mógłby zastąpićfile
w jego miejsce linku do/dev/watchdog
na przykład pomiędzylstat()
aopen()
i spowodować, że system restartu. Powinno toopen(O_PATH|O_NOFOLLOW)
nastąpićfstat()
,openat()
aioctl()
tutaj, aby uniknąć warunków wyścigu.źródło
Dzięki Ramesh, slm i Stéphane za skierowanie mnie we właściwym kierunku (brakowało mi
-R
przełącznikalsattr
). Niestety, żadna z dotychczasowych odpowiedzi nie działała poprawnie dla mnie.Wymyśliłem następujące:
Chroni to przed użyciem nowego wiersza, aby plik wyglądał na niezmienny, gdy tak nie jest. Robi nie chronią przed plików, które są ustawione jako niezmienne i mają nowe linie w ich nazwach. Ale ponieważ taki plik musiałby zostać utworzony w ten sposób przez root, mogę być pewien, że takie pliki nie istnieją w moim systemie plików dla mojego przypadku użycia. (Ta metoda nie jest odpowiednia do wykrywania włamań w przypadkach, w których użytkownik root może zostać narażony na szwank, ale wtedy nie używa tego samego
lsattr
narzędzia systemowego, które jest również własnością tego samego użytkownika root).źródło
Używanie
find -exec
jest zbyt wolne, przetwarzanie parsowanialsattr
jest niewiarygodne podobniels
jak w przypadku używania Pythona, tak jak w odpowiedzi Gillesa, wymaga wybrania stałejioctl
zależnej od tego, czy interpreter Pythona jest 32- czy 64-bitowy ...Problem jest mniej więcej na niskim poziomie, więc zejdźmy na niższy poziom: C ++ nie jest taki zły jak język skryptowy :) Jako bonus, ma dostęp do nagłówków systemu C z pełną mocą preprocesora C.
Poniższy program wyszukuje niezmienne pliki, pozostając w jednym systemie plików, tzn. Nigdy nie przekracza punktów montowania. Aby przeszukać widoczne drzewo, w razie potrzeby przekraczając punkty montowania, usuń
FTW_MOUNT
flagę wnftw
wywołaniu. Również nie podąża za dowiązaniami symbolicznymi. Aby to zrobić, usuńFTW_PHYS
flagę.źródło
Zamiast przesyłać dane wyjściowe do grep, dlaczego nie użyć awk, aby dopasować tylko „i” w pierwszym polu wyniku?
W rzeczywistości uruchamiam to codziennie przez cron, aby skanować katalog / etc na setkach serwerów i wysyłać dane wyjściowe do syslog. Następnie mogę wygenerować codzienny raport za pośrednictwem Splunk:
źródło
/etc
. Ale oba polecenia niepoprawnie znajdują niezmienny plik utworzony przy pomocytouch `"echo -e "bogus\n---------i---e-- changeable"`"
touch "`echo -e 'bogus\n---------i---e-- changeable'`"
Bardzo proste, przejdź do podejrzanego folderu i uruchom polecenie:
źródło