CalcGuide · 技术博客主页 / 一页纸学习计划
🟡

文件系统权限、强制访问控制与 systemd 沙箱:把好第二道门

分类:安全与可靠性 · 路径:docs/topics/permissions-and-mac/README.md

#linux#selinux#apparmor#capabilities#systemd

从 chmod/chown/ACL/SUID/Linux capabilities 到 SELinux/AppArmor 与 systemd 沙箱,把进门的活动范围压到最小

父主题

Linux 系统安全加固:从账号权限到纵深防御

子主题(0)

文件系统权限、强制访问控制与 systemd 沙箱:把好第二道门

0. 元信息

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 capabilities0.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 profile1 天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 027stat -c '%a %U %G' file 看到 750 / root / group
2. ACLgetfacl setfacl -m u:alice:rwx、mask、default ACL给一个目录加 alice 读写getfacl 看到 user:alice 段
3. 不可变位chattr +i(连 root 都改不了)、+a(仅追加)/etc/resolv.conf 设 +a 防 DNS 被改chattr +irm 失败;lsattr 看 +i
4. SUID / SGID / sticky八进制第 1 位、find -perm -4000/tmp 1777列 SUID 白名单;清理非必要 SUIDfind / -perm -4000 数量稳定;/tmp 1777
5. capabilitiesgetcap setcap cap_net_bind_service=+ep capsh --printnode 程序能绑 80 而非 rootgetcap $(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、MLSgetenforceseinfosesearch看到 system_u:object_r:bin_t:s0 标签
8. SELinux 操作semanage setsebool -P restorecon audit2allow给 nginx httpd_can_network_connect=1;修 AVCausearch -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 / sudosetcap 给解释器(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 -agetenforceaa-statuscapsh --print

任务当天交付自检命令
Day 1UNIX 权限:chmod 750/chmod 600 改一组脚本;umask 027 写入 /etc/profile.d/stat -c '%a %U %G' file 看矩阵权限矩阵表stat -c '%a %U %G %n' /etc/passwd /etc/shadowumaskchmod 750 验证
Day 2ACL:setfacl -m u:alice:rwx /srv/projgetfacl /srv/proj 看 user:alice;default ACL 给子目录继承ACL 演练记录getfacl /srv/projsetfacl -m d:u:alice:rwx /srv/proj/sub && getfacl /srv/proj/sub
Day 3不可变位:chattr +i /etc/resolv.confchattr +a /var/log/securelsattr /etc/ 看标志;rm 应失败chattr 演练lsattr /etc/resolv.conf /var/log/securerm /etc/resolv.conf 应 EACCES
Day 4SUID 审计:find / -perm -4000 -type f -ls > /root/suid.lst;对照白名单(passwd/su/sudo/ping/mount/umount/chsh/newgrp/pkexec);清非必要 SUID;写 notes/suid-whitelist.mdSUID 白名单清单find / -perm -4000 -type f | wc -lfind / -perm -4000 -type f -lsstat -c '%a' /usr/bin/passwd /usr/bin/su
Day 5capabilities: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 --printgetcap /usr/bin/nodesetcap -r /usr/bin/node && getcap 验证撤销
Day 6systemd 沙箱:写 /etc/systemd/system/myapp.serviceExecStart=/usr/bin/python3 -m http.server 8080 --directory /srv/myapp),加 PrivateTmp=yesPrivateDevices=yesProtectHome=yesProtectSystem=strictNoNewPrivileges=yesRestrictSUIDSGID=yesRestrictNamespaces=yesMemoryDenyWriteExecute=yesLockPersonality=yesRestrictAddressFamilies=AF_INET AF_INET6 AF_UNIXUMask=0077ReadWritePaths=/srv/myapp /var/log/myappSystemCallFilter=@system-serviceSystemCallArchitectures=nativeDynamicUser=yesStateDirectory=myappsystemd-analyze security myapp 看评分;journalctl -u myapp 启动正常myapp.service + systemd-analyze security 输出systemd-analyze security myappjournalctl -u myapp --since todaysystemctl 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 AVCdmesg | grep -i audit 看拒绝;用 audit2allow -M mypol(SELinux)或 aa-logprof(AppArmor)生成策略;semodule -i mypol.ppapparmor_parser -r 加载;再跑验证允许AVC 拒绝 + 策略加载证据getenforceausearch -m AVCaudit2why <avc>aa-status(AppArmor)

Day 7 拆解

步骤 A —— 最小可用(90 分钟)

  1. 在目标服务路径(如 /srv/myapp)建个测试目录,写入 index.html
  2. 启动一个 python3 简单 HTTP server:python3 -m http.server 8080 --directory /srv/myapp
  3. curl http://localhost:8080/ 看到 200;但 SELinux/AppArmor 状态查拒绝:
    • SELinux:sudo ausearch -m AVC -ts recenttype=AVC msg=audit(...): avc: denied { read } ...
    • AppArmor:sudo dmesg | grep -i 'apparmor.*DENIED'audit: type=1400 ... apparmor="DENIED"
  4. SELinux:sudo chcon -t httpd_sys_content_t /srv/myapp 后再 curl,应允许;
  5. AppArmor:aa-genprof /usr/bin/python3 跑 wizard,确认允许访问 /srv/myapp;写入 /etc/apparmor.d/usr.bin.python3sudo apparmor_parser -r /etc/apparmor.d/usr.bin.python3

步骤 B —— 持久化 + 边界(30~45 分钟)

  1. SELinux:用 semanage fcontext -a -t httpd_sys_content_t '/srv/myapp(/.*)?' + restorecon -Rv /srv/myapp 持久化(chcon 不持久);
  2. AppArmor:aa-enforce /usr/bin/python3 改强制模式;aa-status 看到 enforce
  3. 重启服务,第二次跑应仍允许;
  4. SELinux 切 permissive(sudo setenforce 0)验证 AVC 不再拒;切回 enforcing(sudo setenforce 1)验证策略生效;
  5. 故意访问 /etc/shadow:服务应被拒;ausearch 应记录新 AVC。

5. 阶段通用验收(每一阶段都通过)

  1. 能用 1 张表说出 CIS Benchmark 1.x 文件权限 / 5.x SSH / 6.x 服务配置 的核心控制项;
  2. 改完配置用 stat -c '%a %U %G'getcapsystemd-analyze securitygetenforceaa-statusausearch -m AVC 看证据,存进 notes/
  3. 制造 1 个对照实验:留 /usr/bin/python3 SUID → 用 python3 -c 'import os; os.setuid(0); os.system("/bin/bash")' 提权成功;移除 SUID → 失败;
  4. 至少 3 组自定义数据:故意跑 SUID shell wrapper、故意给解释器加 cap、故意开 ProtectSystem=strict 后服务写 /etc 失败;贴 journalctlausearch 输出;
  5. 记录变更:每改一个文件 / unit / SELinux 布尔 写一条(who/when/what/why/CIS 控制项号);
  6. 能修改已有 profile 或 service(删/加一条沙箱指令;删/加一条 SELinux 规则),而不是只照搬。

6. 最终验收(学完 9 阶段后)

7. 综合项目

首选:写一份 harden-mac.md —— 准备一台干净的 RHEL 9 或 Ubuntu 22.04 虚机,先基线(find / -perm -4000 | wc -lgetenforceaa-statussystemd-analyze security 全 unit 默认分),按 9 阶段顺序加固(UNIX → ACL → attr → SUID → caps → 沙箱 → MAC),用同一组命令对比前后

要求:

备选:在 Ubuntu 22.04 上为 nginx + 自写 myapp 各写一个 AppArmor profile,验证违反被拦;用 aa-logprof 从日志生成。

任何综合项目都必须包含:

  1. 需求与成功标准(含权限/MAC 目标和验证命令);
  2. 基线 vs 目标差距表;
  3. 配置按层(UNIX / ACL / attr / SUID / caps / 沙箱 / SELinux / AppArmor);
  4. 脚本化(scripts/harden-mac.sh + scripts/verify-mac.sh),幂等可重跑;
  5. 正常 + 异常验证(解释器 cap → 任意命令;沙箱开 → 写 /etc 被拦;MAC 开 → 违反被拦);
  6. 报告:基线、目标、结果、剩余项、复盘;
  7. README;
  8. 复盘记录。

本主题贡献(Loop 6-D · linux-hardening / permissions-and-mac)

本主题交付”UNIX 权限 + ACL + attr + SUID 收敛 + capability 收紧 + 沙箱 + MAC”七层加固脚本化包,故意给 Python 解释器加 cap_net_bind_service 看任意命令可执行,再收紧 + 沙箱开启验证拦截。

3 项核心职责

4 项交付物

  1. 基线 vs 目标差距表:含 UNIX 权限收紧目标、ACL 应用清单、attr 加锁清单、SUID 白名单、capability 收紧清单、沙箱策略、MAC 模式七项 + 验证命令(getfacl / lsattr / getcap -r / / aa-status / sestatus)。
  2. UNIX / ACL / attr / SUID 收敛脚本scripts/harden-mac.sh(幂等),含 SUID 白名单文件、attr 加锁清单、ACL 应用清单,故意解释器 cap 验证任意命令可执行后收紧。
  3. 沙箱配置(systemd unit override):每个服务一个 override.conf,含 ProtectSystem=strict / PrivateTmp=true / NoNewPrivileges=true / RestrictAddressFamilies= 等,故意开沙箱看写 /etc 被拦。
  4. MAC 策略落档(SELinux 或 AppArmor 二选一):SELinux enforcing + restorecon 跑全站,或 AppArmor 自写 nginx + myapp profile(用 aa-logprof 从日志生成),故意违反被拦验证。

3 个验收指标

8. 推荐开源资料(按角色分工,避免堆链接)

阶段角色资料链接用法
1~4DAC 权威 man pageman capabilities(7)man chattr(1)man lsattr(1)man find(1)https://man7.org/linux/man-pages/字段解释第一站;SUID 用 find -perm -4000
2POSIX ACLArch Wiki: POSIX ACLhttps://wiki.archlinux.org/title/ACLgetfacl/setfacl 示例
5Linux capabilitiesArch Wiki: Capabilitieshttps://wiki.archlinux.org/title/Capabilitiescapsh --print 起步;40+ cap 列表
6systemd 沙箱systemd.exec(5)systemd.resource-control(5)https://www.freedesktop.org/software/systemd/man/沙箱指令权威;按”进程/文件/网络”分组
6systemd 沙箱实战Red Hat Security Guide: Service Hardeninghttps://docs.redhat.com/en/documentation/systemd-analyze security 解读;组合指令
7~9SELinux 入门图解Red Hat《SELinux Coloring Book》https://docs.redhat.com/en/documentation/user/role/type 三元组可视化
7~9SELinux 主线Red Hat Enterprise Linux Security Guidehttps://docs.redhat.com/en/documentation/enforcing 模式 + 布尔 + semanage
8SELinux 操作Arch Wiki: SELinuxhttps://wiki.archlinux.org/title/SELinuxaudit2allow / restorecon / sealert
9AppArmorUbuntu AppArmor Wikihttps://ubuntu.com/server/docs/security-apparmoraa-genprof / aa-logprof 流程
9AppArmorArch Wiki: AppArmorhttps://wiki.archlinux.org/title/AppArmorprofile 语法;complain → enforce
全部合规基线CIS Benchmarks + ComplianceAsCode SSGhttps://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 验证 —— 默认读思路后自己写

默认使用顺序man page → 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 进一步提供:

这层失守,攻击者拿到一个普通账号就够提权拿到 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 BookSELinux 入门图解5
Red Hat Enterprise Linux Security GuideSELinux / systemd hardening5
Ubuntu AppArmor WikiAppArmor 入门 + profile4
systemd.resource-control(5) / systemd.exec(5)沙箱字段权威5
man find -permSUID 审计4
Hanno Böck, Linux Hardening in Hostile Networks攻击者视角4

9.3.2 备查

资料链接
Arch Wiki: POSIX ACLhttps://wiki.archlinux.org/title/ACL
Arch Wiki: Capabilitieshttps://wiki.archlinux.org/title/Capabilities
Arch Wiki: AppArmorhttps://wiki.archlinux.org/title/AppArmor
Arch Wiki: SELinuxhttps://wiki.archlinux.org/title/SELinux
SELinux Project Wikihttps://selinuxproject.org/
ComplianceAsCodehttps://github.com/ComplianceAsCode/content
systemd man pageshttps://www.freedesktop.org/software/systemd/man/systemd.html

9.3.3 必查 man pages

9.4 经典问题与经典案例

#问题为什么会重要最简答案 / 证据
1/usr/bin/python3 留 SUIDpython 提权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
4getcap /usr/bin/python3解释器 caps = 任意代码不给解释器加 caps
5chmod 777 /etc灾难CIS 要求 644 或 600
6umask 000默认文件全开/etc/profileumask 027
7/tmp 不设 sticky用户删别人文件chmod 1777 /tmp
8chattr +i /etc/resolv.conf 防 DNS 改但 resolvconf 仍要改+i 防手动改,resolvconf 走别路径
9AppArmor profile 拼错名profile 静默忽略aa-status 看到才生效
10SELinux setenforce 0 后忘改回MAC 长期关加 cron 监控;定期 getenforce
11restorecon 不跑改文件后标签错改完跑 restorecon -Rv /path
12audit2allow -M mypol 后忘 semodule -i规则没加载两步都做
13ProtectSystem=strict 后服务写 /etc业务依赖未发现改为 full 或加 ReadWritePaths=
14DynamicUser=yes 与 stateful service 不兼容state 写到 /var/lib 失败StateDirectory= / LogsDirectory=
15RestrictAddressFamilies 太严DNS 解析失败至少保留 AF_INET AF_INET6 AF_UNIX
16SystemCallFilter=~@clock 误把 clock 排除时间相关全挂@system-service 白名单
17chmod -R 777 修问题一切开门改前 getfacl 备份;改后 restorecon
18SUID 程序未打补丁已知提权 CVE跟 patch cadence
19mount 用了 nosuid/home 没分SUID 在 home 仍生效/home 单独分且 nosuid,nodev
20/dev/shm 留 world-writable共享内存攻击/etc/fstab mount options
21docker.sock 暴露docker 提权 rootroot 拥有 660;docker 组限定
22SUID binary 在用户可写目录用户替换二进制SUID 在系统只读目录;mount -o nosuid 应用于可写 fs
23关键 service 跑 root 还能写任意进程被入侵即 rootNoNewPrivileges=yes + ProtectSystem=strict
24没有 ReadWritePaths=service 全程只读显式加
25seccomp 没启用系统调用全集systemd 默认 + SystemCallFilter=
26SUID shell wrapper任何用户得 rootfind 找;删;chmod u-s
27AppArmor complain 模式不拦上线前改 enforce
28SELinux 用户未映射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 attachprofile 路径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 与 runtimeservice 需要 /tmpPrivateTmp=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
systemd255+systemd 项目活跃LGPL-2.1
POSIX ACL1003.1e draftIEEE / The Open Group事实标准公开
ComplianceAsCode SSG持续更新ComplianceAsCode/content活跃GPL-3.0+ / BSD

9.6.2 Scope

9.6.3 Structure

9.6.4 Ecosystem

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

10. 常见误区

11. 所有知识点分类(统一规则)

  1. 编程语言
  2. 数据结构与算法
  3. 计算机基础
  4. 工程技术
  5. Web 与后端
  6. 前端与客户端
  7. 数据与人工智能
  8. 项目与职业能力
  9. 安全与可靠性

本计划归属:安全与可靠性 主 + 工程技术 辅。


直接依赖(1)

查看知识图谱