文件系统权限、强制访问控制与 systemd 沙箱:把好第二道门
0. 元信息
- 主题路径:
docs/topics/linux-hardening/subtopics/permissions-and-mac/ - 父主题:
linux-hardening - 主分类:安全与可靠性
- 辅助分类:工程技术
- 适合对象:理解
chmod 755、跑过基本 systemd service、知道”root 啥都能干”的运维 / 后端 / 安全工程师 - 建议周期:1.5~2 周(每周 8~10 小时,含 SELinux / AppArmor 实验)
- 前置知识:
linux-dev-env;identity-and-ssh - 最终目标:能清理 SUID/SGID 残留并维护白名单,能用 Linux capabilities 让非 root 进程绑 80,能用 SELinux/AppArmor 限制一个服务只读指定目录并验证违规访问被拦截,能用 systemd sandboxing 指令给一个自写服务加 10+ 条沙箱并保持功能正常
1. 学习路线
UNIX 权限(rwx 八进制、属主、umask)
→ ACL(getfacl / setfacl)
→ 不可变位(chattr +i / +a)
→ SUID / SGID / sticky bit(4 位八进制)
→ Linux capabilities(cap_net_bind_service 等)
→ systemd 沙箱指令(PrivateTmp / PrivateDevices / ProtectHome / ProtectSystem / NoNewPrivileges / DynamicUser / SystemCallFilter)
→ SELinux 概念(user/role/type、policy、enforcing/permissive)
→ SELinux 操作(semanage、setsebool、restorecon、audit2allow)
→ SELinux CIL 写自定义 policy
→ AppArmor 概念(profile、mode、include、hat)
→ AppArmor 写 profile(aa-genprof / aa-logprof)
按”先说是什么,再说怎么挡”的顺序:先 UNIX 权限基线;再 capabilities 拆 root;再 MAC(SELinux/AppArmor)做标签级隔离;最后 systemd 沙箱做进程级隔离。
2. 阶段周数分配(1.5~2 周,建议 2 周)
| 阶段 | 1.5 周速通 | 2 周稳推 | 备注 |
|---|---|---|---|
| 1. UNIX 权限(rwx / umask / chown) | 0.5 天 | 1 天 | 关键文件 600/400 |
| 2. POSIX ACL(getfacl / setfacl) | 0.5 天 | 0.5 天 | 含 default ACL |
| 3. 不可变位(chattr +i / +a) | 0.5 天 | 0.5 天 | /etc/resolv.conf /etc/hosts |
| 4. SUID / SGID / sticky 审计 | 0.5 天 | 1 天 | 白名单制;找可疑项 |
| 5. Linux capabilities | 0.5 天 | 1 天 | cap_net_bind_service 替代 root |
| 6. systemd 沙箱(10+ 条指令) | 1 天 | 1.5 天 | systemd-analyze security ≤ 3 |
| 7. SELinux 概念与切换 | 0.5 天 | 0.5 天 | enforcing / permissive / targeted |
| 8. SELinux 操作(semanage / audit2allow) | 1 天 | 1 天 | 修 AVC;写布尔 |
| 9. SELinux CIL + AppArmor profile | 1 天 | 1.5 天 | 自写限制 myapp 读 /srv/myapp |
每天 1.5 小时;1.5 周速通每天 2 小时能跑完,但 SELinux CIL 与 AppArmor profile 容易踩拼写错。建议 2 周:SELinux CIL 与 AppArmor 各留 1.5 天写 profile。
3. 九阶段表
| 阶段 | 核心知识 | 实践产出 | 可观察学会标准 |
|---|---|---|---|
| 1. UNIX 权限 | rwx 三类、八进制、umask、chown、chgrp | 给一个脚本 750;umask 027 | stat -c '%a %U %G' file 看到 750 / root / group |
| 2. ACL | getfacl setfacl -m u:alice:rwx、mask、default ACL | 给一个目录加 alice 读写 | getfacl 看到 user:alice 段 |
| 3. 不可变位 | chattr +i(连 root 都改不了)、+a(仅追加) | 把 /etc/resolv.conf 设 +a 防 DNS 被改 | chattr +i 后 rm 失败;lsattr 看 +i |
| 4. SUID / SGID / sticky | 八进制第 1 位、find -perm -4000、/tmp 1777 | 列 SUID 白名单;清理非必要 SUID | find / -perm -4000 数量稳定;/tmp 1777 |
| 5. capabilities | getcap setcap cap_net_bind_service=+ep capsh --print | 让 node 程序能绑 80 而非 root | getcap $(which node) 看到 cap_net_bind_service |
| 6. systemd 沙箱 | PrivateTmp PrivateDevices ProtectHome ProtectSystem=strict NoNewPrivileges RestrictSUIDSGID RestrictNamespaces DynamicUser MemoryDenyWriteExecute LockPersonality RestrictAddressFamilies SystemCallFilter=@system-service | 写一个 myapp.service 加 10+ 条沙箱;systemd-analyze security 看评分 | 评分从 9.x 降到 ≤ 3;服务仍能跑;journalctl -u 没权限错误 |
| 7. SELinux 概念 | user/role/type、enforcing / permissive、policy module、targeted、MLS | getenforce、seinfo、sesearch | 看到 system_u:object_r:bin_t:s0 标签 |
| 8. SELinux 操作 | semanage setsebool -P restorecon audit2allow | 给 nginx httpd_can_network_connect=1;修 AVC | ausearch -m AVC 看到拒绝;加布尔后允许 |
| 9. SELinux CIL + AppArmor | 写 CIL policy;写 AppArmor profile;aa-genprof | 限定 myapp 只能读 /srv/myapp;违规被拦 | 用 runcon 或 service 启动时违反 profile → kernel log audit: type=1400 |
关键陷阱:SUID 清理过度清掉 passwd / ping / sudo;setcap 给解释器(python/node)等于无限制;systemd 沙箱加 ProtectSystem=strict 后服务写 /etc 失败但日志不说为什么;SELinux 改 permissive 后忘改回;AppArmor profile 拼写错 profile 名被忽略。
4. 第一周任务(每天 1.5~2 小时)
Day 1 约定:用一台 Ubuntu 22.04 + AppArmor 或 RHEL 9.x + SELinux 虚机/容器;先建快照。统一记录
lsb_release -a、getenforce或aa-status、capsh --print。
| 日 | 任务 | 当天交付 | 自检命令 |
|---|---|---|---|
| Day 1 | UNIX 权限:chmod 750/chmod 600 改一组脚本;umask 027 写入 /etc/profile.d/;stat -c '%a %U %G' file 看矩阵 | 权限矩阵表 | stat -c '%a %U %G %n' /etc/passwd /etc/shadow、umask、chmod 750 验证 |
| Day 2 | ACL:setfacl -m u:alice:rwx /srv/proj;getfacl /srv/proj 看 user:alice;default ACL 给子目录继承 | ACL 演练记录 | getfacl /srv/proj、setfacl -m d:u:alice:rwx /srv/proj/sub && getfacl /srv/proj/sub |
| Day 3 | 不可变位:chattr +i /etc/resolv.conf、chattr +a /var/log/secure;lsattr /etc/ 看标志;rm 应失败 | chattr 演练 | lsattr /etc/resolv.conf /var/log/secure、rm /etc/resolv.conf 应 EACCES |
| Day 4 | SUID 审计:find / -perm -4000 -type f -ls > /root/suid.lst;对照白名单(passwd/su/sudo/ping/mount/umount/chsh/newgrp/pkexec);清非必要 SUID;写 notes/suid-whitelist.md | SUID 白名单清单 | find / -perm -4000 -type f | wc -l、find / -perm -4000 -type f -ls、stat -c '%a' /usr/bin/passwd /usr/bin/su |
| Day 5 | capabilities:setcap cap_net_bind_service=+ep /usr/bin/node;写一段 node require('net').createServer().listen(80);getcap /usr/bin/node 看到 cap_net_bind_service;验证非 root 可绑 80;删 cap 后再试应失败 | capabilities 验证记录 | capsh --print、getcap /usr/bin/node、setcap -r /usr/bin/node && getcap 验证撤销 |
| Day 6 | systemd 沙箱:写 /etc/systemd/system/myapp.service(ExecStart=/usr/bin/python3 -m http.server 8080 --directory /srv/myapp),加 PrivateTmp=yes、PrivateDevices=yes、ProtectHome=yes、ProtectSystem=strict、NoNewPrivileges=yes、RestrictSUIDSGID=yes、RestrictNamespaces=yes、MemoryDenyWriteExecute=yes、LockPersonality=yes、RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX、UMask=0077、ReadWritePaths=/srv/myapp /var/log/myapp、SystemCallFilter=@system-service、SystemCallArchitectures=native、DynamicUser=yes、StateDirectory=myapp;systemd-analyze security myapp 看评分;journalctl -u myapp 启动正常 | myapp.service + systemd-analyze security 输出 | systemd-analyze security myapp、journalctl -u myapp --since today、systemctl status myapp |
| Day 7 | 项目(MAC 入门):启用 SELinux enforcing(setenforce 1)或 AppArmor enforce;故意跑一个未受限服务触发 AVC:python3 -m http.server 8080 把目录挂在 /srv/myapp;改 /srv/myapp 标签:chcon -t httpd_sys_content_t /srv/myapp(SELinux)或给 AppArmor 写最小 profile;用 ausearch -m AVC 或 dmesg | grep -i audit 看拒绝;用 audit2allow -M mypol(SELinux)或 aa-logprof(AppArmor)生成策略;semodule -i mypol.pp 或 apparmor_parser -r 加载;再跑验证允许 | AVC 拒绝 + 策略加载证据 | getenforce、ausearch -m AVC、audit2why <avc>、aa-status(AppArmor) |
Day 7 拆解
步骤 A —— 最小可用(90 分钟)
- 在目标服务路径(如
/srv/myapp)建个测试目录,写入index.html; - 启动一个 python3 简单 HTTP server:
python3 -m http.server 8080 --directory /srv/myapp; curl http://localhost:8080/看到 200;但 SELinux/AppArmor 状态查拒绝:- SELinux:
sudo ausearch -m AVC -ts recent看type=AVC msg=audit(...): avc: denied { read } ...; - AppArmor:
sudo dmesg | grep -i 'apparmor.*DENIED'看audit: type=1400 ... apparmor="DENIED";
- SELinux:
- SELinux:
sudo chcon -t httpd_sys_content_t /srv/myapp后再curl,应允许; - AppArmor:
aa-genprof /usr/bin/python3跑 wizard,确认允许访问/srv/myapp;写入/etc/apparmor.d/usr.bin.python3,sudo apparmor_parser -r /etc/apparmor.d/usr.bin.python3。
步骤 B —— 持久化 + 边界(30~45 分钟)
- SELinux:用
semanage fcontext -a -t httpd_sys_content_t '/srv/myapp(/.*)?'+restorecon -Rv /srv/myapp持久化(chcon不持久); - AppArmor:
aa-enforce /usr/bin/python3改强制模式;aa-status看到enforce; - 重启服务,第二次跑应仍允许;
- SELinux 切 permissive(
sudo setenforce 0)验证 AVC 不再拒;切回 enforcing(sudo setenforce 1)验证策略生效; - 故意访问
/etc/shadow:服务应被拒;ausearch应记录新 AVC。
5. 阶段通用验收(每一阶段都通过)
- 能用 1 张表说出 CIS Benchmark 1.x 文件权限 / 5.x SSH / 6.x 服务配置 的核心控制项;
- 改完配置用
stat -c '%a %U %G'、getcap、systemd-analyze security、getenforce、aa-status、ausearch -m AVC看证据,存进notes/; - 制造 1 个对照实验:留
/usr/bin/python3SUID → 用python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'提权成功;移除 SUID → 失败; - 至少 3 组自定义数据:故意跑 SUID shell wrapper、故意给解释器加 cap、故意开
ProtectSystem=strict后服务写/etc失败;贴journalctl与ausearch输出; - 记录变更:每改一个文件 / unit / SELinux 布尔 写一条(who/when/what/why/CIS 控制项号);
- 能修改已有 profile 或 service(删/加一条沙箱指令;删/加一条 SELinux 规则),而不是只照搬。
6. 最终验收(学完 9 阶段后)
- 独立完成:清理 SUID/SGID 残留并维护白名单;用 Linux capabilities 让非 root 绑 80;用 SELinux/AppArmor 限制一个服务只读指定目录并验证违规访问被拦;用 systemd sandboxing 给一个自写服务加 10+ 条沙箱并保持功能正常;
- 完成至少 30 条权限层加固项:SUID 白名单 ≤ 20 项;systemd 服务
systemd-analyze security总分 ≤ 30(单项 ≤ 4);SELinuxgetenforce = Enforcing;ausearch -m AVC --start today在服务正常路径下无新 AVC; - 完成 1 个综合项目:在一台 RHEL/Ubuntu 上为”自写 myapp + redis + nginx”三个服务分别加 systemd 沙箱 + SELinux/AppArmor profile;跑
systemd-analyze security+ausearch验证;能在 30 分钟内回滚到默认; - 用 15 分钟讲清”DAC → ACL → attr → SUID → caps → MAC → namespace / seccomp”七层防御各堵哪类威胁,SUID 与 capabilities 的本质区别,
ProtectSystem=strict与ReadWritePaths怎么配合。
7. 综合项目
首选:写一份 harden-mac.md —— 准备一台干净的 RHEL 9 或 Ubuntu 22.04 虚机,先基线(find / -perm -4000 | wc -l、getenforce、aa-status、systemd-analyze security 全 unit 默认分),按 9 阶段顺序加固(UNIX → ACL → attr → SUID → caps → 沙箱 → MAC),用同一组命令对比前后。
要求:
- 准备
notes/baseline-before.md与notes/baseline-after.md; - 逐项改:SUID 清理、capabilities 加、
myapp.service加沙箱、SELinux/AppArmor profile; - 持久化:
/etc/systemd/system/myapp.service、/etc/apparmor.d/usr.bin.python3或 SELinux CIL/var/lib/selinux/myapp.pp; - 验证:
systemd-analyze security myapp总分 ≤ 30;ausearch -m AVC --start today无新拒绝;SUID 数量从基线降至少 30%; - 输出
notes/retrospective.md:哪些被坑过(解释器 cap、沙箱过严、profile 拼写错、restorecon 漏跑)。
备选:在 Ubuntu 22.04 上为 nginx + 自写 myapp 各写一个 AppArmor profile,验证违反被拦;用 aa-logprof 从日志生成。
任何综合项目都必须包含:
- 需求与成功标准(含权限/MAC 目标和验证命令);
- 基线 vs 目标差距表;
- 配置按层(UNIX / ACL / attr / SUID / caps / 沙箱 / SELinux / AppArmor);
- 脚本化(
scripts/harden-mac.sh+scripts/verify-mac.sh),幂等可重跑; - 正常 + 异常验证(解释器 cap → 任意命令;沙箱开 → 写
/etc被拦;MAC 开 → 违反被拦); - 报告:基线、目标、结果、剩余项、复盘;
- README;
- 复盘记录。
本主题贡献(Loop 6-D · linux-hardening / permissions-and-mac)
本主题交付”UNIX 权限 + ACL + attr + SUID 收敛 + capability 收紧 + 沙箱 + MAC”七层加固脚本化包,故意给 Python 解释器加 cap_net_bind_service 看任意命令可执行,再收紧 + 沙箱开启验证拦截。
3 项核心职责
- UNIX / ACL / attr / SUID:用
chmod/chown/setfacl收紧权限;用chattr +i给关键配置(/etc/passwd//etc/shadow//etc/sudoers)加不可改;用find / -perm -4000收敛 SUID / SGID(白名单之外清零)。 - capability + 沙箱:用
getcap -r /审计文件 capability,给解释器(python / perl / node)收紧(禁cap_net_bind_service等任意 cap);配 systemdProtectSystem=strict/PrivateTmp=true/NoNewPrivileges=true给服务套沙箱。 - MAC(SELinux / AppArmor):RHEL / CentOS 走 SELinux enforcing(
/etc/selinux/config+restorecon),Ubuntu / Debian 走 AppArmor enforce(aa-enforce+ 自写 profile),故意违反看被拦。
4 项交付物
- 基线 vs 目标差距表:含 UNIX 权限收紧目标、ACL 应用清单、attr 加锁清单、SUID 白名单、capability 收紧清单、沙箱策略、MAC 模式七项 + 验证命令(
getfacl/lsattr/getcap -r //aa-status/sestatus)。 - UNIX / ACL / attr / SUID 收敛脚本:
scripts/harden-mac.sh(幂等),含 SUID 白名单文件、attr 加锁清单、ACL 应用清单,故意解释器 cap 验证任意命令可执行后收紧。 - 沙箱配置(systemd unit override):每个服务一个
override.conf,含ProtectSystem=strict/PrivateTmp=true/NoNewPrivileges=true/RestrictAddressFamilies=等,故意开沙箱看写/etc被拦。 - MAC 策略落档(SELinux 或 AppArmor 二选一):SELinux enforcing +
restorecon跑全站,或 AppArmor 自写 nginx + myapp profile(用aa-logprof从日志生成),故意违反被拦验证。
3 个验收指标
find / -perm -4000输出收敛到白名单(≤ 5 条且全在白名单文件);getcap -r /无解释器类 cap。- 沙箱:服务运行时
cat /proc/<pid>/status | grep -E 'Seccomp|NoNewPrivs'显示开启;写/etc被Read-only file system拦截。 - MAC:SELinux
sestatus显示Current mode: enforcing且restorecon跑通;AppArmoraa-status显示 enforce profile ≥ 3 个,故意违反被audit: type=1400命中。
8. 推荐开源资料(按角色分工,避免堆链接)
| 阶段 | 角色 | 资料 | 链接 | 用法 |
|---|---|---|---|---|
| 1~4 | DAC 权威 man page | man capabilities(7)、man chattr(1)、man lsattr(1)、man find(1) | https://man7.org/linux/man-pages/ | 字段解释第一站;SUID 用 find -perm -4000 |
| 2 | POSIX ACL | Arch Wiki: POSIX ACL | https://wiki.archlinux.org/title/ACL | getfacl/setfacl 示例 |
| 5 | Linux capabilities | Arch Wiki: Capabilities | https://wiki.archlinux.org/title/Capabilities | capsh --print 起步;40+ cap 列表 |
| 6 | systemd 沙箱 | systemd.exec(5)、systemd.resource-control(5) | https://www.freedesktop.org/software/systemd/man/ | 沙箱指令权威;按”进程/文件/网络”分组 |
| 6 | systemd 沙箱实战 | Red Hat Security Guide: Service Hardening | https://docs.redhat.com/en/documentation/ | systemd-analyze security 解读;组合指令 |
| 7~9 | SELinux 入门图解 | Red Hat《SELinux Coloring Book》 | https://docs.redhat.com/en/documentation/ | user/role/type 三元组可视化 |
| 7~9 | SELinux 主线 | Red Hat Enterprise Linux Security Guide | https://docs.redhat.com/en/documentation/ | enforcing 模式 + 布尔 + semanage |
| 8 | SELinux 操作 | Arch Wiki: SELinux | https://wiki.archlinux.org/title/SELinux | audit2allow / restorecon / sealert |
| 9 | AppArmor | Ubuntu AppArmor Wiki | https://ubuntu.com/server/docs/security-apparmor | aa-genprof / aa-logprof 流程 |
| 9 | AppArmor | Arch Wiki: AppArmor | https://wiki.archlinux.org/title/AppArmor | profile 语法;complain → enforce |
| 全部 | 合规基线 | CIS Benchmarks + ComplianceAsCode SSG | https://www.cisecurity.org/ · https://github.com/ComplianceAsCode/content | 注册下载;profile 与 OVAL |
| 全部 | 攻击者视角 | Hanno Böck《Linux Hardening in Hostile Networks》 | https://michael-wolf.de/ | SUID 与 caps 的滥用模式 |
许可证提示:CIS Benchmarks 注册免费账号下载;systemd man pages LGPL-2.1;Linux-PAM/auditd 都是 BSD/GPL 双许可;SELinux/AppArmor GPL-2.0;ComplianceAsCode SSG 是 GPL-3.0+ / BSD。复制 CIS 控制点脚本到生产前先在 staging 验证 —— 默认读思路后自己写。
默认使用顺序:
manpage → Arch Wiki / Red Hat Security Guide → CIS / ComplianceAsCode profile → 实操(audit2allow/aa-logprof/systemd-analyze security)→ 复盘到notes/retrospective.md。
9. 学习资料汇聚(v0.3 自包含)
本节由本计划生成。
9.1 背景与动机
账号层决定了”谁能进”,但进到系统后能做什么由权限模型决定。传统 UNIX DAC(自主访问控制)由属主决定,灵活但粗:要么全开要么全关。Linux 进一步提供:
- ACL:在 owner/group/other 之外加更细的 ACL 项;
- 不可变位:连 root 都不能改(适合配置 / 二进制);
- SUID/SGID:让普通用户跑特定特权操作(设计粗糙,常被滥用);
- Linux capabilities:把 root 拆成 40+ 细粒度能力;
- MAC(SELinux / AppArmor):在内核层强制访问控制,进程能读什么标签由策略决定,与属主无关;
- systemd 沙箱:在内核层为单个 service 隔离命名空间、文件系统、网络。
这层失守,攻击者拿到一个普通账号就够提权拿到 root(SUID / cap / 通配符写入)。
9.2 概念地图
flowchart TB
DAC[UNIX 权限 rwx]
ACL[POSIX ACL]
Attr[chattr +i / +a]
SUID[SUID / SGID / sticky]
Caps[Linux capabilities]
Seccomp[seccomp / SystemCallFilter]
Namespaces[Mount / PID / Network NS]
MAC[MAC]
SELinux[SELinux]
AppArmor[AppArmor]
Sysd[systemd 沙箱]
Files[文件系统] --> DAC
DAC --> ACL
DAC --> Attr
DAC --> SUID
DAC --> Caps
Caps --> Sysd
SUID --> MAC
Sysd --> Seccomp
Sysd --> Namespaces
MAC --> SELinux
MAC --> AppArmor
Sysd --> MAC
9.3 基础知识讲解
9.3.1 主推
| 资料 | 角色 | 评分 |
|---|---|---|
man capabilities(7) | capabilities 权威 | 5 |
man chattr / lsattr | 不可变位 | 4 |
| Red Hat SELinux Coloring Book | SELinux 入门图解 | 5 |
| Red Hat Enterprise Linux Security Guide | SELinux / systemd hardening | 5 |
| Ubuntu AppArmor Wiki | AppArmor 入门 + profile | 4 |
systemd.resource-control(5) / systemd.exec(5) | 沙箱字段权威 | 5 |
man find -perm | SUID 审计 | 4 |
| Hanno Böck, Linux Hardening in Hostile Networks | 攻击者视角 | 4 |
9.3.2 备查
| 资料 | 链接 |
|---|---|
| Arch Wiki: POSIX ACL | https://wiki.archlinux.org/title/ACL |
| Arch Wiki: Capabilities | https://wiki.archlinux.org/title/Capabilities |
| Arch Wiki: AppArmor | https://wiki.archlinux.org/title/AppArmor |
| Arch Wiki: SELinux | https://wiki.archlinux.org/title/SELinux |
| SELinux Project Wiki | https://selinuxproject.org/ |
| ComplianceAsCode | https://github.com/ComplianceAsCode/content |
| systemd man pages | https://www.freedesktop.org/software/systemd/man/systemd.html |
9.3.3 必查 man pages
chmod(1)chown(1)chgrp(1)umask(2)getfacl(1)setfacl(1)acl(5)chattr(1)lsattr(1)find(1)-perm-user-groupgetcap(8)setcap(8)capsh(1)capabilities(7)systemctl(1)systemd-analyze(1)systemd.exec(5)systemd.service(5)systemd.unit(5)getenforce(8)setenforce(8)semanage(8)setsebool(8)restorecon(8)audit2allow(1)audit2why(1)seinfo(8)sesearch(8)aa-status(8)aa-genprof(8)aa-logprof(8)apparmor.d(5)
9.4 经典问题与经典案例
| # | 问题 | 为什么会重要 | 最简答案 / 证据 |
|---|---|---|---|
| 1 | /usr/bin/python3 留 SUID | python 提权 | find / -perm -4000 审计;chmod u-s |
| 2 | /usr/sbin/su 被清 SUID | 失去 su 功能 | 保留 SUID |
| 3 | 服务用 root 绑 80 | 攻击面大 | setcap cap_net_bind_service=+ep /usr/bin/node |
| 4 | getcap /usr/bin/python3 | 解释器 caps = 任意代码 | 不给解释器加 caps |
| 5 | chmod 777 /etc | 灾难 | CIS 要求 644 或 600 |
| 6 | umask 000 | 默认文件全开 | /etc/profile 改 umask 027 |
| 7 | /tmp 不设 sticky | 用户删别人文件 | chmod 1777 /tmp |
| 8 | chattr +i /etc/resolv.conf 防 DNS 改 | 但 resolvconf 仍要改 | 用 +i 防手动改,resolvconf 走别路径 |
| 9 | AppArmor profile 拼错名 | profile 静默忽略 | aa-status 看到才生效 |
| 10 | SELinux setenforce 0 后忘改回 | MAC 长期关 | 加 cron 监控;定期 getenforce |
| 11 | restorecon 不跑 | 改文件后标签错 | 改完跑 restorecon -Rv /path |
| 12 | audit2allow -M mypol 后忘 semodule -i | 规则没加载 | 两步都做 |
| 13 | ProtectSystem=strict 后服务写 /etc 挂 | 业务依赖未发现 | 改为 full 或加 ReadWritePaths= |
| 14 | DynamicUser=yes 与 stateful service 不兼容 | state 写到 /var/lib 失败 | 加 StateDirectory= / LogsDirectory= |
| 15 | RestrictAddressFamilies 太严 | DNS 解析失败 | 至少保留 AF_INET AF_INET6 AF_UNIX |
| 16 | SystemCallFilter=~@clock 误把 clock 排除 | 时间相关全挂 | 用 @system-service 白名单 |
| 17 | chmod -R 777 修问题 | 一切开门 | 改前 getfacl 备份;改后 restorecon |
| 18 | SUID 程序未打补丁 | 已知提权 CVE | 跟 patch cadence |
| 19 | mount 用了 nosuid 但 /home 没分 | SUID 在 home 仍生效 | /home 单独分且 nosuid,nodev |
| 20 | /dev/shm 留 world-writable | 共享内存攻击 | 改 /etc/fstab mount options |
| 21 | docker.sock 暴露 | docker 提权 root | root 拥有 660;docker 组限定 |
| 22 | SUID binary 在用户可写目录 | 用户替换二进制 | SUID 在系统只读目录;mount -o nosuid 应用于可写 fs |
| 23 | 关键 service 跑 root 还能写任意 | 进程被入侵即 root | 加 NoNewPrivileges=yes + ProtectSystem=strict |
| 24 | 没有 ReadWritePaths= | service 全程只读 | 显式加 |
| 25 | seccomp 没启用 | 系统调用全集 | systemd 默认 + SystemCallFilter= |
| 26 | SUID shell wrapper | 任何用户得 root | find 找;删;chmod u-s |
| 27 | AppArmor complain 模式 | 不拦 | 上线前改 enforce |
| 28 | SELinux 用户未映射 | sshd 拒绝登录 | semanage login -a -s user_u alice |
9.5 学习难点
概念难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| SUID vs capability | 都能提权 | 看 getcap vs find -perm |
| SELinux type enforcement | 类型矩阵 | sesearch --allow -s httpd_t -t var_log_t |
| AppArmor path vs attach | profile 路径 | aa-status 看 attach 情况 |
| systemd sandbox 多指令 | 一次记不全 | 按”进程/文件/网络”分组记忆 |
DynamicUser 行为 | 每次启动 UID 变 | 必须用 StateDirectory= |
思维难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| 删 SUID 但服务挂 | 删错 | 白名单制;改前 vm snapshot |
| SELinux 改 permissive 想”先放过” | 长期开 | 用 audit2allow 解决;临时也加 cron 提醒 |
| 加沙箱后服务挂 | 多条同时生效 | 一次加一条;systemd-analyze verify |
工程难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| 给 100 个 service 写沙箱 | 重复劳动 | Ansible 模板 + role |
| 第三方软件 SELinux 模块缺失 | AVC 一堆 | audit2allow -M 生成;提交上游 |
ProtectSystem=strict 与 runtime | service 需要 /tmp | 加 PrivateTmp=yes + RuntimeDirectory= |
9.6 技术标准与接口
9.6.1 Entity
| 名称 | 版本 | 组织 | 状态 | 许可证 |
|---|---|---|---|---|
| Linux capabilities(7) | 5.x 内核 | kernel.org | 主流 | GPL-2.0 |
| SELinux | 主流 | NSA / Red Hat | 活跃 | GPL-2.0 |
| SELinux CIL | 主流 | NSA / Red Hat | 活跃 | 公开 |
| AppArmor | 主流 | Canonical / SUSE | 活跃 | GPL-2.0 |
| systemd | 255+ | systemd 项目 | 活跃 | LGPL-2.1 |
| POSIX ACL | 1003.1e draft | IEEE / The Open Group | 事实标准 | 公开 |
| ComplianceAsCode SSG | 持续更新 | ComplianceAsCode/content | 活跃 | GPL-3.0+ / BSD |
9.6.2 Scope
- capabilities:把 root 拆分为细粒度能力;与 SUID 并存。
- SELinux:type-based MAC;RHEL/CentOS/Fedora 默认。
- AppArmor:path-based MAC;Ubuntu/SUSE 默认。
- systemd 沙箱:per-service 命名空间/seccomp/cgroup。
- CIS 1.x / 6.x:文件系统权限、SUID、Service 配置。
- 这些层不替代上层账号 / 网络 / 审计。
9.6.3 Structure
- capabilities 关键:
CAP_NET_BIND_SERVICECAP_NET_RAWCAP_SYS_ADMINCAP_DAC_OVERRIDECAP_CHOWNCAP_SYS_PTRACECAP_SYS_RESOURCE。 - SELinux 关键:
getenforcesemanage fcontextsemanage booleansetsebool -Prestoreconaudit2allow -M <name>semodule -i。 - AppArmor 关键:
/etc/apparmor.d/<profile>aa-complainaa-enforceaa-logprofaa-genprof。 - systemd 沙箱关键指令(10+):
PrivateTmp=yes/PrivateDevices=yes/PrivateNetwork=yes/PrivateUsers=yesProtectHome=yes/ProtectSystem=strict/ProtectKernelTunables=yes/ProtectKernelModules=yes/ProtectControlGroups=yesReadWritePaths=/ReadOnlyPaths=/InaccessiblePaths=NoNewPrivileges=yesRestrictSUIDSGID=yes/RestrictNamespaces=yes/RestrictRealtime=yesLockPersonality=yes/MemoryDenyWriteExecute=yes/RestrictAddressFamilies=SystemCallFilter=@system-service/SystemCallArchitectures=nativeDynamicUser=yes/StateDirectory=/LogsDirectory=/CacheDirectory=UMask=0077
9.6.4 Ecosystem
- 工具:
systemd-analyze security <unit>、audit2why、aa-notify、sealert。 - 策略仓库:ComplianceAsCode(SSG)、Ubuntu AppArmor profile 集合、SUSE AppArmor。
- 集成:podman/docker 使用 SELinux/AppArmor 标签(
--security-opt label=type:container_t)。 - 事实标准:targeted policy(SELinux 默认)、complain→enforce 流程(AppArmor)。
9.6.5 Depth Tiers
| 层级 | 能力 |
|---|---|
| L0 | 知道 rwx / SUID / root |
| L1 | 看得懂一段 chmod / getcap 输出 |
| L2 | 能写 systemd unit 加 5+ 沙箱;用 SELinux 布尔修常见 AVC |
| L3 | 能解释 SUID 提权、SELinux type enforcement、systemd namespace 行为;为服务写 CIL / AppArmor profile |
| L4 | 能为多服务设计统一沙箱基线;为新软件写完整 policy 并贡献上游 |
本计划目标:L3。
9.6.6 Source
- kernel.org capabilities(7):https://www.kernel.org/doc/man-pages/
- SELinux:https://selinuxproject.org/
- AppArmor:https://gitlab.com/apparmor/apparmor/-/wikis/Documentation
- systemd:https://www.freedesktop.org/software/systemd/man/systemd.html
- Red Hat Security Guide:https://docs.redhat.com/en/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening
- 引用版本快照日期:2026-07-30。
10. 常见误区
- 误把
/usr/bin/python3SUID 当合理配置;解释器 caps/suid = 任意代码; chmod 777修”权限不足”问题;setenforce 0后不写复盘,长期 permissive;- AppArmor complain 模式上线;
restorecon不跑,标签错乱;audit2allow -M mypol跑完不semodule -i,规则没加载;ProtectSystem=strict后业务挂,没查journalctl;DynamicUser=yes与 stateful service 一起用;RestrictAddressFamilies=AF_UNIX后 DNS 解析失败;SystemCallFilter=~@clock误伤时间服务;- 信任 owner 写权限 = 没设 ACL;
nosuid没用到/home//tmp//dev/shm;chattr +i加到需要写的文件上导致 cron 挂;- SUID binary 已知 CVE 没打补丁;
- AppArmor profile 名错不生效,自以为加固了;
setcap cap_net_bind_service=+eip(i表示 inherit)误加给 wrapper script。
11. 所有知识点分类(统一规则)
- 编程语言
- 数据结构与算法
- 计算机基础
- 工程技术
- Web 与后端
- 前端与客户端
- 数据与人工智能
- 项目与职业能力
- 安全与可靠性
本计划归属:安全与可靠性 主 + 工程技术 辅。