如何搜尋具有不可變屬性集的文件?
出於配置審計的原因,我希望能夠在我的 ext3 文件系統中搜尋具有不可變屬性集(通過
chattr +i
)的文件。我找不到find
執行此操作的任何選項或類似選項。在這一點上,恐怕我必須編寫自己的腳本來解析lsattr
每個目錄的輸出。是否有提供更好方法的標準實用程序?
它可以通過通過
lsattr
命令傳遞grep
命令來部分完成。lsattr -R | grep +i
但是,我相信當您提到搜尋可能涉及的整個
ext3
文件系統以及其他一些可能會報告您只想忽略的錯誤的目錄時。您可能可以將命令執行為,/proc``/dev
lsattr -R 2>/dev/null | grep -- "-i-"
您可能希望通過使用的 PCRE 工具來更明確地匹配“-i-” ,從而使其
grep
更加嚴格。grep
lsattr -R 2>/dev/null | grep -P "(?<=-)i(?=-)"
這將適用於以下情況:
$ lsattr -R 2>/dev/null afile | grep -P "(?<=-)i(?=-)" ----i--------e-- afile
但卻是不完美的。如果在不可變標誌周圍啟用了其他屬性,那麼我們將不匹配它們,這將被名稱恰好與上述模式匹配的文件所迷惑,例如:
$ lsattr -R 2>/dev/null afile* | grep -P "(?<=-)i(?=-)" ----i--------e-- afile -------------e-- afile-i-am
我們可以像這樣收緊模式:
$ lsattr -a -R 2>/dev/null afile* | grep -P "(?<=-)i(?=-).* " ----i--------e-- afile
但它仍然有點太脆弱,需要根據文件系統中的文件進行額外的調整。更不用說@StephaneChazeles在評論中提到,通過包含帶有文件名的換行符來繞過上述模式到
grep
.參考
https://groups.google.com/forum/#!topic/alt.os.linux/LkatROg2SlM
鑑於腳本的目的是審計,正確處理任意文件名尤其重要,例如包含換行符的名稱。
lsattr
這使得同時在多個文件上使用是不可能的,因為lsattr
在這種情況下,輸出可能是模棱兩可的。您可以一次遞歸
find
併呼叫lsattr
一個文件。不過會很慢。find / -xdev -exec sh -c ' for i do attrs=$(lsattr -d "$i"); attrs=${attrs%% *} case $attrs in *i*) printf "%s\0" "$i";; esac done' sh {} +
我建議使用不那麼古怪的語言,例如 Perl、Python 或 Ruby,並自己完成工作
lsattr
。lsattr
通過發出FS_IOC_GETFLAGS
ioctl 系統呼叫並檢索文件的inode 標誌來進行操作。這是一個 Python 概念驗證。#!/usr/bin/env python2 import array, fcntl, os, sys S_IFMT = 0o170000 S_IFDIR = 0o040000 S_IFREG = 0o100000 FS_IOC_GETFLAGS = 0x80086601 EXT3_IMMUTABLE_FL = 0x00000010 count = 0 def check(filename): mode = os.lstat(filename).st_mode if mode & S_IFMT not in [S_IFREG, S_IFDIR]: return fd = os.open(filename, os.O_RDONLY) a = array.array('L', [0]) fcntl.ioctl(fd, FS_IOC_GETFLAGS, a, True) if a[0] & EXT3_IMMUTABLE_FL: sys.stdout.write(filename + '\0') global count count += 1 os.close(fd) for x in sys.argv[1:]: for (dirpath, dirnames, filenames) in os.walk(x): for name in dirnames + filenames: check(os.path.join(dirpath, name)) if count != 0: exit(1)