acl无法防止并发写入时被非关联用户读取,真正起效的是目录权限(chmod 300)、default acl(禁止新文件默认可读)、umask 0077及进程隔离协同实现“写出来就不让读”。

ACL 本身不能直接防止“并发写入阶段被非关联用户读取”,因为 ACL 是文件/目录级的访问控制机制,不提供写入过程中的临时隔离或原子性保护。真正起作用的是目录权限 + default ACL + umask + 进程隔离四者协同,而非单纯靠 ACL 实现“写时不可读”。
核心思路:让新写入的文件从诞生起就不可读
大文件分片写入时,每个线程(或进程)独立创建自己的分片文件(如 part_001.bin、part_002.bin)。若这些文件一落地就具备读权限(如默认 644),即使目录不可列(chmod 300),只要攻击者猜中文件名,仍可 cat /backup/part_001.bin 读取中间态数据。因此关键不是“写入时锁住”,而是“写出来就不让读”。
- 备份目录设为
chmod 300 /backup(即-wx------):确保只有属主能进入、创建、删除,但无法ls,也阻断了普通用户遍历发现文件名的可能 - 启用 default ACL 强制新文件无读权限:
setfacl -d -m u::---,g::---,o::--- /backupsetfacl -d -m u:backupd:rw- /backup
这样 backupd 用户创建的任何文件,默认权限交集为 600(属主可读写,其余全无) - 运行备份进程的用户(如
backupd)必须使用umask 0077启动,确保即使 default ACL 未生效,文件也不会意外带读位
分片拼接前必须清空并重置目标文件权限
合并操作(如 cat part_*.bin > final.dat)通常由同一用户执行,但 final.dat 是新文件,会继承父目录 default ACL 和当前 umask。若不干预,它可能被赋予 600 —— 这虽安全,但若后续需交付给其他系统读取,就得显式改权。更稳妥的做法是:
- 拼接前用
truncate -s 0 final.dat或>清空,并确认其属主为backupd - 拼接完成后立即执行:
chmod 400 final.dat(只读,仅属主)或chmod 440 final.dat(加属组可读),按需而定 - 避免在拼接过程中开放临时读权限(如先 chmod 644 再 cat),这会留下极短但可利用的时间窗口
ACL 不解决的问题,得靠流程和权限收口
ACL 可以精细授权特定用户对某个分片文件的读写,但它无法阻止以下情况:
- 属主用户(如 backupd)的 shell 被劫持后主动
cat分片 - 运维人员误将 backupd 的 SSH 密钥泄露,导致他人以该身份登录
- 分片路径被日志、监控脚本意外记录并外泄
所以生产环境还需配套措施:
- backupd 用户禁用交互式登录(
/sbin/nologin)、不配密码、仅通过 sudo 或 systemd service 启动任务 - 所有分片写入路径不硬编码在脚本里,而由 runtime 注入(如通过环境变量或 secret manager)
- 启用 auditd 监控对
/backup下文件的 open/read 系统调用,异常行为实时告警











