浅谈Linux的AppArmor
文章目录
本文通过“Web服务应该能访问哪些文件”的例子,浅谈 AppArmor。
为便于理解,下面只讨论普通文件访问。使用 AppArmor 的场景中,假设目标进程已经受到对应策略的约束,并运行在 enforce(强制执行)模式下,不展开安装步骤和完整策略配置。
What
先把最容易混淆的一点说清楚:
1 | Linux 文件权限允许访问 |
AppArmor 是 Linux 中的一种强制访问控制机制,可以通过 profile(安全策略),限制进程能够访问哪些资源、执行哪些操作。
可以把 profile 理解为给程序制定的一份“允许清单”:
1 | 这个程序: |
它还可以约束网络访问等行为,本文只用文件读写来说明。
所以:
不仅看“运行程序的用户有没有权限”,还要看“这个程序的安全策略是否允许”。
Why
一个程序正常工作,通常不需要用到运行用户的全部访问权限。
例如,Web 服务需要读取网页、写入日志,但不一定需要读取同一台机器上的内部报表。
如果仅按用户身份控制权限,而这个用户恰好也能读取报表,那么 Web 服务就可能拥有这项并不需要的访问能力。
一旦程序出现漏洞,这些多余的权限也可能被利用。
AppArmor 的做法是:
1 | 用户原本能够访问的资源 |
因此,它的目的可以概括为:
让程序只接触完成工作所需的资源,减少程序出问题后可能造成的影响。
它不是把程序中的漏洞修好了,而是在程序外面增加一道由内核执行的限制。
基础 Example
假设一个名为 demo-web 的 Web 服务,面对下面三个文件:
1 | /srv/site/index.html 网页文件 |
为突出 AppArmor 的作用,假设原有 Linux 文件权限允许该进程读取网页和报表,也允许读写日志;没有其他机制阻止这些访问。
下面只比较它对这三个文件的访问。
没有 AppArmor 限制
1 | demo-web |
程序不需要报表,不代表操作系统会自动禁止它读取报表。
使用 AppArmor 限制
为它设置策略:允许读取网页、读写日志,但不允许读取内部报表。
1 | demo-web + AppArmor profile |
即使有人利用 Web 服务的漏洞,让这个进程尝试读取报表,AppArmor 仍会按照策略拒绝这次访问。
区别就在于:
用户拥有的权限,不再全部成为这个程序可以使用的权限。
这里没有删除或隐藏报表,也没有修改报表原有的文件权限;只是额外限制了这个进程对它的访问。
How
只看三个关键点。
1. 用 profile 描述允许的访问
AppArmor 的文件访问规则主要通过路径和操作权限来描述。
例如,下面两行规则分别允许读取网页、读写日志:
1 | /srv/site/index.html r, |
其中:
1 | r:允许读取 |
在本例的 enforce 策略中,如果没有任何规则允许读取 internal.csv,这次读取就会被拒绝。
不需要把所有不允许读取的文件,逐个列成一份黑名单。
这里只展示规则片段,不是可以直接部署的完整 profile;程序启动和正常运行所需的其他访问规则已经省略。
2. 将策略交给内核执行
用户态工具负责将 profile 加载到内核,目标进程需要在对应 profile 的约束下运行。
AppArmor 通过 LSM(Linux Security Modules) 框架参与内核的安全检查。在打开文件等操作中,内核会根据进程的策略,检查它是否有权进行这次访问。
1 | 程序尝试打开一个文件 |
不是要求程序自己遵守约定,而是由内核执行限制。
需要注意,仅安装或启用 AppArmor,不等于所有进程都自动获得这些保护;还需要加载合适的策略,并让目标进程受到约束。
3. 与原有文件权限共同生效
AppArmor 不会替代原有的 Linux 文件权限,也不会让本来无权读取文件的用户,因为 profile 写了 r 就获得读取权限。
只看这两层检查,可以这样理解:
1 | 文件权限允许 + AppArmor 拒绝 → 仍然拒绝 |
两边都允许,才算通过这两层访问检查。
所以:
AppArmor 是进一步收紧访问范围,不是绕过原有权限。
记忆图
1 | demo-web 发起文件访问 |
上图只展示本文关注的两层权限检查。
可以简单记成:
1 | 用户权限:这个用户能访问什么? |
一句话概括:
在用户权限之外,再给程序划定访问范围:该读的可以读,不该碰的由内核拦住。
参考资料: