如何监控无权限用户对文件的访问尝试
检测无权限文件访问的解决方案
问题背景
用inotify编写了文件系统监控脚本,当文件被访问时触发grant.py,但inotify无法检测用户尝试打开无权限文件的操作,需要实现该检测功能并作为守护进程运行。现有脚本仅能检测用户拥有权限的文件访问行为:
import inotify.adapters import os # path to the lock file lock_file_path = "./lockfile.txt" # path to the Unlock.py script unlock_script_path = "./grant.py" def is_file_locked(file_path): # check if the file is listed in the lock file with open(lock_file_path, "r") as lock_file: locked_files = lock_file.read().splitlines() return file_path in locked_files def on_write_event(event): # check if the written file is locked full_file_path = os.path.abspath(os.path.join(path,filename)) print(full_file_path) if is_file_locked(full_file_path): # run the Unlock.py script os.system(f"python3 {unlock_script_path}") # create the inotify event listener notifier = inotify.adapters.Inotify() notifier.add_watch("./test",mask=inotify.constants.IN_OPEN) # listen for the WRITE event for event in notifier.event_gen(yield_nones=False): (_, type_names, path, filename) = event print('-') if "IN_OPEN" in type_names: on_write_event(event)
核心原因
inotify依赖内核发送的文件系统事件,当用户无权限打开文件时,内核不会触发IN_OPEN事件,因此inotify无法捕获这类操作。要检测无权限访问尝试,需要借助auditd系统审计工具,它能记录所有权限检查相关的系统调用。
实现步骤
1. 安装auditd
根据系统包管理器安装:
- Debian/Ubuntu:
sudo apt-get install auditd - RHEL/CentOS:
sudo yum install auditd
2. 添加审计规则
为需要监控的文件/目录添加审计规则,记录读权限拒绝事件:
# 监控单个文件 sudo auditctl -w /path/to/your/locked/file -p r -k file_access_denied # 监控目录下所有文件 sudo auditctl -w /path/to/your/test/dir -p r -k file_access_denied
-w:指定要监控的路径-p r:监控读操作-k:为事件添加标签,方便后续过滤
3. 编写监控审计日志的Python脚本
audit日志默认路径为/var/log/audit/audit.log,脚本需要实时监控该日志,解析出权限拒绝事件,触发grant.py:
import os import time from subprocess import Popen, PIPE import threading import inotify.adapters lock_file_path = "./lockfile.txt" unlock_script_path = "./grant.py" audit_log_path = "/var/log/audit/audit.log" def is_file_locked(file_path): if not os.path.exists(lock_file_path): return False with open(lock_file_path, "r") as lock_file: locked_files = lock_file.read().splitlines() # 匹配绝对路径 return os.path.abspath(file_path) in locked_files def monitor_audit_log(): # 用tail -f实时监控日志 proc = Popen(["tail", "-F", audit_log_path], stdout=PIPE, stderr=PIPE, text=True) for line in proc.stdout: # 过滤权限拒绝且带有指定标签的事件 if "denied" in line and "file_access_denied" in line: # 提取被访问的文件路径 for part in line.split(): if part.startswith("path="): file_path = part.split("=")[1].strip('"') if is_file_locked(file_path): print(f"Detected unauthorized access attempt to locked file: {file_path}") os.system(f"python3 {unlock_script_path}") break def monitor_inotify(): # 处理有权限的文件访问事件 notifier = inotify.adapters.Inotify() notifier.add_watch("./test", mask=inotify.constants.IN_OPEN) for event in notifier.event_gen(yield_nones=False): _, type_names, path, filename = event if "IN_OPEN" in type_names: full_file_path = os.path.abspath(os.path.join(path, filename)) print(f"Detected authorized access to: {full_file_path}") if is_file_locked(full_file_path): os.system(f"python3 {unlock_script_path}") if __name__ == "__main__": # 启动两个监控线程 audit_thread = threading.Thread(target=monitor_audit_log, daemon=True) audit_thread.start() inotify_thread = threading.Thread(target=monitor_inotify, daemon=True) inotify_thread.start() # 保持主进程运行 while True: time.sleep(3600)
4. 设置脚本为守护进程
可以用systemd将脚本配置为守护进程:
- 创建
file-monitor.service文件:
[Unit] Description=File Access Monitor Service After=auditd.service [Service] User=root ExecStart=/usr/bin/python3 /path/to/your/monitor_script.py Restart=always [Install] WantedBy=multi-user.target
- 启用并启动服务:
sudo systemctl daemon-reload sudo systemctl enable file-monitor.service sudo systemctl start file-monitor.service
注意事项
- auditd需要root权限运行,因此监控脚本也需要以root身份执行
- 定期清理audit日志,避免日志文件过大:
sudo auditctl -k file_access_denied -D可以删除指定标签的规则,sudo service auditd rotate可以轮转日志 - 确保
grant.py能正确处理权限授予逻辑,避免安全风险
内容的提问来源于stack exchange,提问作者Nehal Hosalikar
相关产品推荐
相关产品推荐

