acl不支持“只读不删”语义,需分离控制:父目录禁写(r-x)且文件本体可读(r--),配合默认acl、sticky bit、others禁用等加固;验证时检查acl无w/delete_child,测试rm应报错。

ACL 本身不直接支持“只读不删”这种权限语义,因为“删”和“读”依赖的是完全不同的权限路径:读取文件内容取决于文件自身的 r 权限;而删除操作实际是修改父目录的结构(移除目录项),取决于父目录是否授予用户 w 权限(或 ACL 中的 delete_child)。真正实现“能看不能删”,关键在于分离控制——让目标用户对文件有读权,但对其所在目录无写权。
核心配置:父目录禁写 + 文件本体可读
以敏感目录 /data/conf/ 为例,希望用户 auditor 可查看其中所有配置文件,但无法删除任何一项:
- 移除
auditor对父目录的写权限(即禁止delete_child):setfacl -m u:auditor:r-x /data/conf
注意:不要用-wx显式拒绝,而是明确只赋r-x,更清晰可控。 - 确保每个敏感文件(如
/data/conf/db.yml)对auditor开放读权限:setfacl -m u:auditor:r-- /data/conf/db.yml - 若该目录下文件会动态新增,需设置默认 ACL,使新文件自动继承只读权限:
setfacl -d -m u:auditor:r-- /data/conf
这样新创建的文件默认获得r--,但因父目录无w,仍无法被删除。
加固策略:sticky bit + 权限最小化
仅靠 ACL 不足以应对所有场景,建议叠加以下措施:
- 在父目录启用 sticky bit:
chmod +t /data/conf
这能防止非属主用户删除他人创建的文件,进一步约束删除行为。 - 禁用
others访问,避免路径猜解后直读:setfacl -m o::--- /data/conf
同时对每个文件也执行:setfacl -m o::--- /data/conf/*.yml - 确认目录基础权限足够严格,例如设为
750或755,但必须确保组和其他用户不含w;若auditor不在属组中,750更安全。
验证与避坑要点
执行后务必验证,常见问题多源于权限叠加逻辑被忽略:
- 检查父目录 ACL:
getfacl /data/conf | grep auditor→ 应显示user:auditor:r-x,不可出现w或delete_child - 检查文件 ACL:
getfacl /data/conf/db.yml | grep auditor→ 应为user:auditor:r-- - 测试删除:
切换至auditor用户,执行rm /data/conf/db.yml,应提示Permission denied - 警惕编辑器行为:vim/nano 等可能先删后写,导致看似“删了”;此时应改用追加模式(如
:set nowritebackup)或限制其仅用cat/less查看。
替代增强方案(按需选用)
当 ACL 配置复杂或需更高保障时,可组合使用:
-
chattr +a:对日志类只追加文件,允许
auditor读+追加,但禁止删除/截断:sudo chattr +a /data/conf/access.log -
专用只读挂载:将敏感目录 bind-mount 为只读视图供审计用户访问:
sudo mount --bind /data/conf /mnt/audit-ro && sudo mount -o remount,ro /mnt/audit-ro - SELinux 类型强制:在支持的系统上,为该目录打标并定义策略,彻底阻断 delete 系统调用,不受用户身份影响。











