跳转至

保护机制与系统安全

保护机制规定合法主体怎样访问系统对象;安全则要在错误、漏洞和主动攻击下维持期望属性。二者关系像“门锁的结构”和“整栋建筑的安全”:门锁重要,但身份管理、钥匙发放、审计、窗户和应急响应同样重要。

从威胁模型开始

安全设计不能只说“防黑客”,应明确:

  • 保护哪些资产?
  • 攻击者拥有什么初始权限和能力?
  • 哪些组件被信任?
  • 允许损失什么,不能损失什么?
  • 可用性和性能约束是什么?

常见目标:

  • 机密性:未授权主体不能读取信息。
  • 完整性:未授权主体不能修改信息或执行流。
  • 可用性:授权用户能在需要时获得服务。

备份帮助恢复完整性和可用性,但不能阻止已泄露密钥破坏机密性;加密保护静态数据,也不能防止已获得解密权限的进程读取。

保护域与访问控制矩阵

把行看作主体/保护域,列看作客体,单元格记录允许操作:

主体 配置文件 日志文件 网络端口
Web 服务 监听 443
运维工具 读写 管理端口
普通用户 读自己的

完整矩阵通常稀疏,不会真的存成大二维数组。两种主要分解:

ACL

围绕对象记录“谁可以做什么”。回答“谁能访问这个文件”方便,但撤销某主体在全系统的权限需要遍历许多对象。

Capability

围绕主体记录“它持有哪些对象能力”。传递 capability 可委托权限,适合最小权限和组件化系统;需要防伪造、控制传播与撤销。

文件描述符具有 capability 风格:获得 fd 后可按其打开模式访问对象,即使原路径后来不可见。Unix 文件模式位则更接近简化 ACL。

自主访问控制与强制访问控制

  • DAC:对象所有者可决定授权,如传统用户/组/其他权限。
  • MAC:系统策略基于标签和规则强制限制,即使对象所有者也不能随意绕过。

DAC 灵活,容易因过度授权和所有者误操作扩大权限;MAC 能建立更强边界,但策略设计、部署和调试成本更高。实际系统常组合二者。

最小权限例子

一个只需读取静态网页并监听高位端口的服务,不应以全能管理员运行。可拆分为:

启动器:执行少量特权初始化
  -> 降低身份/丢弃能力
工作进程:只读内容目录、写专用日志、监听指定 socket
  -> 系统调用过滤与资源限制

若解析器出现内存漏洞,攻击者获得的只是受限工作进程权限,而不是整台机器。

最小权限的难点是准确发现依赖。权限过少导致功能失败,团队可能粗暴地改成全权限;更好的做法是用审计和测试逐项建立最小集合。

认证、授权与审计

  • 认证:你是谁?
  • 授权:这个身份能做什么?
  • 审计:谁在何时尝试或完成了什么?

认证成功不代表授权所有操作。审计日志也不能只记录成功登录,还要记录权限变更、敏感访问和失败尝试,并保护日志免受被审计者篡改。

凭据可包括密码、密钥、令牌和硬件认证器。密码存储应使用带盐、专用于密码的慢哈希,而不是可逆明文或普通快速哈希。

用户身份、组与特权拆分

传统超级用户模型简单,但一个进程只需绑定端口却获得所有特权,违反最小权限。细粒度 capability 把特权拆成若干能力,使进程只保留所需项。

设置用户 ID 程序允许执行时获得文件所有者的有效身份,能提供受控特权操作,也是高风险边界:参数、环境、路径、文件描述符和错误处理都必须严格验证。优先用更小的专用服务或能力拆分降低攻击面。

系统调用过滤与沙箱

若进程只需读取已有 fd 和进行纯计算,可以限制其可调用系统调用集合。沙箱还可组合:

  • 独立用户和文件系统视图。
  • 页表隔离和不可执行内存。
  • 资源限制与 cgroup。
  • 系统调用参数过滤。
  • MAC 标签和网络策略。

沙箱不是自动安全。过滤规则过宽、内核漏洞、共享宿主资源和错误挂载都可能成为逃逸路径。

常见漏洞缓解

不可执行页

数据页不可执行,阻止直接跳到注入数据。攻击者仍可能复用已有代码,因此需要其他措施。

地址随机化

随机化代码、库、堆和栈位置,增加预测地址难度。信息泄漏可能绕过。

栈保护与控制流保护

栈 canary 检测部分返回地址覆盖,控制流完整性限制间接跳转目标。它们降低利用成功率,但不能修复越界访问或逻辑漏洞本身。

安全语言与边界检查

内存安全语言消除大量释放后使用和越界写类别,但 FFI、不安全代码、逻辑授权错误和资源耗尽仍需处理。

防御应分层,不能依赖单个缓解“兜底”。

TOCTOU

“检查后使用”之间若对象可被替换,就出现竞态:

检查 /path/to/file 安全
攻击者替换路径组件
以特权打开同一路径

解决思路是对稳定对象引用操作,而不是再次解析不可信名字,例如先打开目录获得 fd,再用相对接口和禁止跟随符号链接的标志逐级操作。核心是缩小检查与使用之间的可变命名窗口。

引导与代码信任链

安全启动验证固件加载的下一阶段,再逐级验证引导程序和内核。它帮助防止离线替换启动代码,但不能保证已签名软件没有漏洞,也不能代替运行时权限和更新机制。

签名回答“这段代码来自被信任签名者且未被修改”,不直接回答“代码行为没有错误”。

侧信道

即使页表禁止直接读取,攻击者仍可能从缓存时序、分支预测、共享资源竞争和功耗等间接推断秘密。隔离共享微架构资源、常数时间实现和减少共驻可缓解,但常有性能代价。

侧信道说明保护不只存在于 ISA 可见权限,微架构状态也可能成为信息通道。

可用性与资源控制

安全也包括防止资源耗尽:

  • 进程数、打开文件数和内存上限。
  • CPU、I/O 和网络带宽份额。
  • 有界请求队列和超时。
  • 速率限制和故障隔离。

只限制内存却不限制 CPU 或进程创建,攻击者仍能让系统不可用。资源限制应覆盖主要共享瓶颈,并为关键控制路径预留容量。

更新与响应

没有永远无漏洞的系统。安全工程还需要:

  • 资产和版本清单。
  • 及时补丁与回滚方案。
  • 密钥轮换与权限撤销。
  • 日志、告警和取证证据。
  • 备份与恢复演练。

无法安全更新的设备会把已知漏洞固化到生命周期中。可维护性本身是安全属性。

权衡

  • 更细权限减少破坏范围,却增加策略和运维复杂度。
  • 更强隔离减少共享攻击面,却增加内存与边界切换成本。
  • 详细审计帮助追责,却增加存储、隐私和敏感日志保护问题。
  • 快速自动更新缩短漏洞窗口,却需处理兼容和回滚。

安全选择必须基于威胁模型,不应把“开启最多选项”当作完整方案。

自测

  1. ACL 与 capability 分别按什么方向组织权限?
  2. 认证成功为什么不表示可以读取任意文件?
  3. ASLR 和不可执行页为什么都不是漏洞修复?
  4. 安全启动能证明什么,不能证明什么?
  5. 最小权限怎样降低解析器漏洞的影响范围?
参考思路

ACL 围绕对象列主体权限,capability 围绕主体持有对象权利。授权是独立判断。缓解措施提高利用难度但越界根因仍在。安全启动验证加载链来源与完整性,不证明代码无漏洞。受限进程被攻破后可访问资源更少。