Skip to content

28.4 强制访问控制框架(MAC 框架)

28.4.1 概述

FreeBSD 的强制访问控制(Mandatory Access Control,MAC)框架允许通过可加载安全策略模块对系统安全施加精细控制。MAC 可加载访问控制模块以执行安全策略。部分模块为系统子集提供保护,强化特定服务;其他模块则跨所有主体与客体提供全面的标签化安全。所谓“强制”(Mandatory),指控制权由管理员与操作系统掌握,而默认的自主访问控制(Discretionary Access Control,DAC)则由用户自行决定。

MAC 策略 不能覆盖 传统 Unix 安全机制(文件权限和超级用户检查),仅在 DAC 基础之上施加额外限制。换言之,即使用 MAC 配置为允许访问,DAC 一旦拒绝,操作仍会失败。MAC 策略可限制 root 权限,此为其与 DAC 的关键区别之一。

sh
访问请求

  先检查 DAC(自主访问控制)

DAC 规则

   ├── 拒绝 ──► 访问失败(MAC 无法覆盖)

 允许

MAC 规则(强制访问控制)

   ├── 拒绝 ──► 访问失败

 允许

访问成功

MAC 框架于 FreeBSD 5.0 首次引入,属 TrustedBSD 项目组成部分,由 Robert Watson 设计、Network Associates Laboratories(NAI Labs)安全研究部门实现,系 DARPA/SPAWAR 合同 N66001-01-C-8035(“CBOSS”)的一部分,隶属 DARPA CHATS 研究计划。

MAC 框架设计参考 IEEE POSIX.1e 草案 17(曾称 POSIX.1e),该草案旨在为操作系统定义安全扩展,包含访问控制列表(ACL)、审计和强制访问控制。POSIX.1e 最终未成正式标准,FreeBSD 的 MAC 实现是 TrustedBSD 项目按实际需求独立演进的结果,不完全等同于任何已批准的国际或行业标准。

MAC 配置不当可能造成无法访问系统、影响用户正常操作或无法启动 Xorg。此外,不应仅依赖 MAC 保护系统。MAC 框架仅增强现有安全策略,如果没有健全的安全实践和定期安全检查,系统始终存在安全隐患。

本章示例仅供演示,不应 在生产系统上实施。任何安全策略的实施均需充分理解、恰当设计和全面测试。

本节虽涉及 MAC 框架广泛的安全问题,但不涉及新 MAC 安全策略模块的开发。MAC 框架中的许多策略模块具有特定特征,也可用于测试目的。

28.4.2 标准合规

FreeBSD 的 MAC 实现与以下标准及草案相关:

  • IEEE POSIX.1e 草案 17:mac(3) 用户空间 API 以及 maclabel(7) 标签格式均基于此草案。API 与 POSIX 草案仅有弱相似性,因为 POSIX API 无法表达灵活且可扩展的访问控制所需的某些概念。
  • 文件系统访问控制列表:POSIX.1e 草案中定义的 ACL 机制由 FreeBSD 通过 getfacl(1)/setfacl(1) 命令独立实现,不属于 MAC 框架。
  • 标签语义:三种标签化策略(Biba、MLS、LOMAC)的语义分别遵循各自的安全模型理论,这些模型来源于经典的军事安全策略和商用完整性策略研究。

28.4.3 关键术语

在涉及 MAC 框架时,使用以下关键术语:

  • 区间(compartment):需划分或隔离的程序和数据组,用户须经明确授权方可访问系统特定组件。区间代表工作组、部门、项目或主题等分组,使得按需知密安全策略可行。
  • 完整性(integrity):可赋予数据的信任级别。数据完整性越高,对其的信任度越高。
  • 级别(level):安全属性的增高或降低设置。级别提高即安全性提升。
  • 标签(label):可应用于文件、目录等系统对象的安全属性,可比作机密性印章。标签应用于文件时,用于描述其安全属性,仅允许相似安全设置的文件、用户和资源访问。标签值的含义和解释取决于策略配置:某些策略将标签视为客体完整性或机密性的代表,另一些策略以标签持有访问规则。
  • 多标签(multilabel):此属性是文件系统选项,可在单用户模式下用 tunefs(8) 设置,引导过程用 fstab(5) 设置,或在创建新文件系统时设置。此选项允许管理员对不同客体应用不同 MAC 标签,仅适用于支持标签化的安全策略模块。
  • 单标签(single label):整个文件系统以一标签对数据流实施访问控制的策略。未设 multilabel 时,所有文件遵循相同标签设置。
  • 客体(object):在 主体 指导下信息流经的实体,包含目录、文件、字段、屏幕、键盘、内存、磁存储、打印机等数据存储或传输设备。客体即数据容器或系统资源,对客体的访问即对其数据的访问。
  • 主体(subject):导致信息在 客体 间流动的活动实体,如用户、用户进程或系统进程。FreeBSD 中几乎总是一个线程,在进程中代表用户执行操作。
  • 策略(policy):定义目标实现方式的一组规则,通常记录某类对象的处理方式。本章视策略为控制数据和信息流、定义访问权限的规则集。
  • 高水位线(high-watermark):允许提高安全级别以访问更高级别信息的策略,进程完成后大多恢复原始级别。目前 FreeBSD MAC 框架不包含此类策略。
  • 低水位线(low-watermark):允许降低安全级别以访问较低安全信息的策略,进程完成后大多恢复用户原始级别。FreeBSD 中仅 mac_lomac(4) 使用此策略。
  • 敏感性(sensitivity):多用于多级安全(Multilevel Security, MLS)讨论。敏感性级别描述数据的重要性或保密程度,级别越高,数据保密性或机密性越重要。

28.4.4 理解 MAC 标签

MAC 标签是可应用于系统中主体和客体的安全属性。设置标签时管理员需要理解其含义,以防止系统出现意外或非预期行为。客体可用属性取决于已加载策略模块,各模块以不同方式解释属性。

客体上的安全标签被策略用作访问控制决策的一部分。部分策略中标签包含决策全部信息,另一些策略中标签可能作为更大规则集的一部分处理。

标签策略分单标签和多标签两类。系统默认使用单标签。管理员应了解各自优缺点,以实施匹配系统安全模型的策略。

单标签策略在系统中强制执行一组访问权限,管理开销较低,但也降低了标签化策略的灵活性,因此仅允许每个主体或客体使用一个标签。不过许多环境中单标签已足够。

单标签策略某种程度上类似 DAC,因为 root 配置策略将用户置于适当类别和访问级别。显著区别在于许多策略模块也可以限制 root。对客体的基本控制下放至组,但 root 可随时撤销或修改设置。

在适当情形下可向 tunefs(8) 传递 multilabel 为 UFS 文件系统设置多标签策略。多标签策略允许每个主体或客体拥有独立 MAC 标签。单标签或多标签的决策仅对实现标签化功能的策略必需,如 bibalomacmls。部分策略(如 seeotheruidsportaclpartition)完全不使用标签。multilabel 功能原生支持于 UFS2 文件系统,需在单用户模式下运行 tunefs -l enable 启用。ZFS 文件系统的 MAC 标签支持因实现方式不同而有所差异。

因为文件系统中一切均有标签——包括目录、文件,甚至设备节点——在分区上使用多标签策略并建立多标签安全模型可能增加管理开销。

以下命令将在指定的 UFS 文件系统上设置多标签 multilabel。此命令应在单用户模式下执行,且对交换文件系统不是必需的:

sh
# 必须在单用户模式下执行下条命令
# tunefs -l enable /
tunefs: multilabel remains unchanged as enabled

注意

如果未在单用户模式下执行上述命令,将始终显示错误信息“tunefs: / is not clean - run fsck.”

某些用户在根分区上设置 multilabel 标志时曾遇到问题(如标签配置不生效、系统无法正常启动等),具体故障排除步骤见本节末尾“MAC 框架故障排除”。

由于多标签策略按文件系统设置,如果文件系统布局得当,可能不需要多标签策略。以 FreeBSD Web 服务器 MAC 安全模型设计为例:此计算机默认文件系统中一切使用单标签 biba/high。如果 Web 服务器需以 biba/low 运行以阻止向上写,可将其安装于设为 biba/low 的独立 UFS 文件系统 /usr/local

28.4.4.1 配置标签

标签策略模块的几乎所有配置均可通过基本系统工具完成,这些命令为客体或主体配置,或对配置控制和验证提供简单接口。

全部配置可用 setfmac(设置系统客体 MAC 标签)和 setpmac(设置系统主体标签)完成。例如,将 test 的 MAC 标签 biba 设为 high

sh
# setfmac biba/high test

命令执行成功后直接返回提示符,无错误信息。

常见错误 Permission denied 通常发生在受限客体上设置或修改标签时。其他情况可能有不同失败:文件可能不属于尝试重新标记客体的用户、客体可能不存在,或客体可能只读。强制策略禁止进程重新标记文件,原因可能与文件属性、进程属性或新标签值属性有关。例如低完整性用户尝试更改高完整性文件标签,或低完整性用户尝试将低完整性文件标签改为高完整性标签,均将失败。

系统管理员可用 setpmac 为被调用进程分配不同标签,覆盖策略模块设置:

sh
# setfmac biba/high test
Permission denied
# setpmac biba/low setfmac biba/high test
# getfmac test
test: biba/high

对于当前运行进程(如 sshd),通常改用 getpmac 获取其标签。此命令以进程 ID(PID)代替命令名。如果用户试图访问不在其权限范围内的文件,将因已加载策略模块的限制而显示 Operation not permitted 错误。

28.4.4.2 预定义标签

部分支持标签化的 FreeBSD 策略模块提供三种预定义标签:lowequalhigh

标签说明
low客体或主体可拥有的最低标签设置。设置此标签将阻止其访问标记为 high 的客体或主体。
equal将主体或客体设为禁用或不受影响,仅应置于豁免于策略的客体上。
high授予客体或主体在 Biba 和 MLS 策略模块中可用的最高设置。

此类策略模块包含 mac_biba(4)、mac_mls(4) 和 mac_lomac(4)。各预定义标签确立不同信息流指令,参阅模块手册页以确定通用标签配置特性。

28.4.4.3 数值标签

Biba 和 MLS 策略模块支持数值标签,可设置以指示层次控制的精确级别。此数值用于将信息划分至不同分类组,仅允许访问该组或更高级别。例如:

sh
biba/10:2+3+6(5:2+3-20:2+3+4+5+6)

可解释为“Biba 策略标签/等级 10:区间 2、3 和 6:(等级 5 …)”。

此示例中第一等级为具有效区间的有效等级,第二为低等级,末为高等级。多数配置无需如此细粒度,因为其属高级配置。

系统客体仅有当前等级和区间。系统主体反映系统中可用权限范围及访问控制用网络接口。

主体和客体对中的等级和区间用于构造 支配(dominance) 关系:主体支配客体、客体支配主体、互不支配或互相支配。“互相支配”见于两标签相等时。因为 Biba 信息流特性,用户拥有一组可能对应项目区间权限的集合,客体也拥有一组区间。用户可能需要借助 susetpmac 缩减权限以访问非受限区间中的客体。

28.4.4.4 用户标签

用户需要在 /etc/login.conf 中以登录类配置标签,确保其文件和进程与系统安全策略正确交互。各使用标签的策略模块均实现用户类设置。

要设置 MAC 强制执行的用户类默认标签,添加 label 条目。包含各策略模块的示例 label 条目如下。注意,实际配置中管理员不会启用全部策略模块。建议实施前完整阅读本节。

ini
default:
	:welcome=/etc/motd:
	:setenv=MAIL=/var/mail/$,BLOCKSIZE=K:
	:path=~/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:
	:manpath=/usr/share/man /usr/local/man:
	:nologin=/usr/sbin/nologin:
	:cputime=1h30m:
	:datasize=8M:
	:vmemoryuse=100M:
	:stacksize=2M:
	:memorylocked=4M:
	:memoryuse=8M:
	:filesize=8M:
	:coredumpsize=8M:
	:openfiles=24:
	:maxproc=32:
	:priority=0:
	:requirehome:
	:passwordtime=91d:
	:umask=022:
	:ignoretime@:
	:label=partition/13,mls/5,biba/10(5-15),lomac/10[2]:

用户虽无法修改默认值,但登录后可在策略约束内更改标签。上例告知 Biba 策略:某进程最低完整性 5、最高 15,默认有效标签 10。该进程以 10 运行,直至选择更改(可能因用户使用 setpmac),受限于 Biba 已配置范围。

/etc/login.conf 文件变更后,需要用 cap_mkdb 重建登录类能力数据库。

许多站点用户众多,需要划分不同的用户类并深入规划,这可能导致管理变得复杂。

28.4.4.5 网络接口标签

网络接口上可设置标签,帮助控制跨网络数据流。网络接口标签在各策略中的运作方式与客体标签相同。例如 Biba 中处于高设置的用户,不允许访问标签为 low 的网络接口。

网络接口上设置 MAC 标签时,可在 ifconfig 中使用 maclabel 参数:

sh
# ifconfig bge0 maclabel biba/equal

此示例在 bge0 接口上设置 biba/equal 的 MAC 标签。使用如 biba/high(low-high) 的设置时,应对整个标签加引号以防返回错误。

各支持标签化的策略模块均有可调参数,可用于在网络接口上禁用 MAC 标签。将标签设为 equal 效果类似。可调参数详情见 sysctl 输出、策略手册页及本章后续内容。

28.4.5 规划安全配置

实施任何 MAC 策略前,建议进行规划。规划阶段应考虑实施要求与目标,例如:

  • 对目标系统信息和资源如何分类。
  • 限制访问哪些信息或资源,以及施加何种访问限制。
  • 达成此目标需哪些 MAC 模块。

生产系统上使用 MAC 实施前,应对受信系统及其配置试运行。环境不同则需求各异,建立完整安全配置可减少上线后修改。

需考虑 MAC 框架如何从整体增强系统安全性。MAC 框架提供的各种安全策略模块可用于保护网络和文件系统,或阻止用户访问特定端口和套接字。策略模块的最佳用法或许是同时加载多个以提供 MLS 环境,此方法有别于仅针对特定用途、强化系统局部元素的策略。MLS 的缺点在于管理开销增加。

但与框架为特定配置灵活选择策略且保持较低性能开销的长期收益相比,这一开销可以接受。减少不必要策略的支持可提升系统整体性能,同时提供选择灵活性。良好的实施应考量整体安全需求,有效部署框架提供的各种安全策略模块。

MAC 可确保用户无法擅自更改系统安全属性。所有用户实用程序、程序和脚本都需在选定安全策略模块的访问规则约束内运行,MAC 访问规则控制权归系统管理员。

系统管理员有责任慎重选择正确的安全策略模块。需限制网络访问控制的环境,mac_portacl(4)、mac_ifoff(4) 和 mac_biba(4) 为良好起点。需文件系统客体严格机密性的环境,可考虑 mac_bsdextended(4) 和 mac_mls(4)。

策略决策可基于网络配置。如果仅应允许特定用户访问 ssh(1),mac_portacl(4) 是妥当选择。文件系统方面,对客体的访问可能对某些用户机密而对其他用户不然。例如大型开发团队可能拆分为较小项目组:项目 A 的开发人员不得访问项目 B 开发人员所写客体,但两组可能均需访问项目 C 开发人员创建的客体。利用 MAC 框架提供的不同安全策略模块,可将用户划入各组再授予适当访问权限。

各安全策略模块有处理系统安全的独特方式。模块选择应基于周全安全策略,该策略可能需修订和重新实施。了解 MAC 框架提供的不同安全策略模块有助于管理员选择最佳方案。

实施 MAC 类似实施防火墙,需防止管理员自身被完全排除在外。应考虑恢复先前配置的能力,通过远程连接实施 MAC 时应格外小心。

28.4.6 可用的 MAC 策略

默认的 FreeBSD 内核包含 options MAC。源代码路径位于 sys/security

测试模块后,将模块名称添加到 /boot/loader.conf 以便在引导时加载。每个模块也为选择编译自定义内核的管理员提供了内核选项。

28.4.6.1 各模块加载时机限制

模块描述标签支持加载时机
mac_biba(4)Biba 完整性策略仅引导时
mac_bsdextended(4)文件系统防火墙任意时机
mac_ddb(4)内核调试器接口限制任意时机
mac_do(4)非特权用户凭据变更任意时机
mac_ifoff(4)接口静默任意时机
mac_ipacl(4)IP 地址访问控制任意时机
mac_lomac(4)Low-Watermark 完整性策略仅引导时
mac_mls(4)多级安全机密性策略仅引导时
mac_none(4)空策略模块(无访问控制效果)任意时机
mac_ntpd(4)NTP 非特权运行任意时机
mac_partition(4)进程分区策略任意时机
mac_portacl(4)端口绑定访问控制任意时机
mac_priority(4)调度优先级策略任意时机
mac_seeotheruids(4)跨用户可见性策略任意时机

以下各节逐一介绍这些策略。最后三种标签化策略(Biba、MLS、LOMAC)支持使用整数值代替三个默认标签。

28.4.6.2 MAC See Other UIDs 策略

模块名称:mac_seeotheruids.ko

内核配置行:options MAC_SEEOTHERUIDS

引导选项:mac_seeotheruids_load="YES"

mac_seeotheruids(4) 模块提供独立的 sysctl 可调参数树 security.mac.seeotheruids.*,其功能类似于 security.bsd.see_other_uidssecurity.bsd.see_other_gids。此选项无需事先设置标签,并可与其他模块透明协同工作。

加载模块后可用以下 sysctl 可调参数控制功能:

  • security.mac.seeotheruids.enabled 启用模块并实施默认设置,拒绝用户查看其他用户拥有的进程和套接字。
  • security.mac.seeotheruids.suser_privileged 设非零值时,允许超级用户(root)查看所有用户的进程和套接字。
  • security.mac.seeotheruids.specificgid_enabled 允许指定组豁免于此策略。使用 security.mac.seeotheruids.specificgid=XXX 可调参数设置,将 XXX 替换为数字组 ID。
  • security.mac.seeotheruids.primarygroup_enabled 用于豁免特定主组。被豁免组中的用户可互相查看进程和套接字。

28.4.6.3 MAC BSD Extended 策略

模块名称:mac_bsdextended.ko

内核配置行:options MAC_BSDEXTENDED

引导选项:mac_bsdextended_load="YES"

mac_bsdextended(4) 模块实施文件系统防火墙,为标准文件系统权限模型提供扩展,允许管理员创建类防火墙规则集保护文件系统层次结构中的文件、实用程序和目录。访问文件系统客体时遍历规则列表,直到找到匹配规则或到达末尾。此行为可用 security.mac.bsdextended.firstmatch_enabled 更改。与 FreeBSD 其他防火墙模块类似,可创建包含访问控制规则的文件,并由系统在引导时使用 rc.conf(5) 变量读取。

规则列表可用 ugidfw(8) 输入,语法类似 ipfw(8)。更多工具可用 libugidfw(3) 库函数编写。

加载 mac_bsdextended(4) 模块后可用以下命令查看当前规则配置:

sh
# ugidfw list
0 slots, 0 rules

默认无规则定义,所有内容完全可访问。创建一条规则阻止所有用户访问但不影响 root

警告

此规则将阻止所有非 root 用户执行任何操作,可能导致系统完全不可用。仅作为反面示例展示,切勿在生产环境中使用。

sh
# ugidfw add subject not uid root new object not uid root mode n

此规则虽简单,却是极为不当的做法:阻止所有用户执行任何命令。更实际的示例是阻止 user1user2 主目录的一切访问(包含目录列表):

sh
# ugidfw set 2 subject uid user1 object uid user2 mode n
# ugidfw set 3 subject uid user1 object gid user2 mode n

可改用 not uid user2 替代 user1,对所有用户强制执行相同访问限制。但 root 不受此规则影响。

使用此模块应格外谨慎,不当使用可能阻止对文件系统部分的访问。

28.4.6.4 MAC DDB 策略

模块名称:mac_ddb.ko

内核配置行:options MAC_DDB

引导选项:mac_ddb_load="YES"

mac_ddb(4) 策略模块限制内核调试器 ddb(4) 命令提示符下可用的命令子集。允许的命令仅限于不允许涉及任意内存的读写操作的命令,防止提取系统机密,同时保留足够调试功能以诊断内核 panic。例如允许 traceshow registers,不允许 show buffer addr

所有以 DB_CMD_MEMSAFE 标志声明的调试器命令均允许。该策略还提供验证函数,根据用户参数有条件地允许部分额外命令。

加载后 mac_ddb 还确保仅可执行 ddb(4) 调试器后端,不可执行 gdb(4)。

此策略不使用标签。

28.4.6.5 MAC DO 策略

模块名称:mac_do.ko

内核配置行:options MAC_DO

引导选项:mac_do_load="YES"

mac_do(4) 策略模块允许非特权用户按管理员配置规则更改进程凭据(用户 ID 和组 ID),支持按 Jail 独立配置。

该策略通过 /usr/bin/mdo 可执行文件生效,详情参阅 mdo(1)。规则以 from>to 格式的字符串指定,每条规则包含 from 部分(匹配当前凭据)和 to 部分(目标凭据),多条规则以分号 ; 分隔。

以下 sysctl 可调参数可用:

  • security.mac.do.enabled 启用或禁用 mac_do 策略(默认:1)。
  • security.mac.do.rules 凭据规则列表,各 Jail 独立配置。

mac_do 支持按 Jail 配置规则。各 Jail 必须在 /usr/bin/mdo 路径安装 mdo(1)。Jail 参数包含 mac.doenable/disable/inherit)和 mac.do.rules

与传统 setuid 方式不同,mac_do 不依赖 setuid 程序决定凭据变更是否可接受,由内核按管理员配置规则决策,从而避免 setuid 程序漏洞的安全风险。

28.4.6.6 MAC Interface Silencing 策略

模块名称:mac_ifoff.ko

内核配置行:options MAC_IFOFF

引导选项:mac_ifoff_load="YES"

mac_ifoff(4) 模块用于动态禁用网络接口,防止网络接口在系统引导期间启动。它不使用标签,不依赖任何其他 MAC 模块。

此模块主要控制通过以下 sysctl 可调参数执行:

  • security.mac.ifoff.lo_enabled 启用或禁用环回接口 lo(4) 上所有流量。
  • security.mac.ifoff.bpfrecv_enabled 启用或禁用伯克利包过滤器接口 bpf(4) 上所有流量。
  • security.mac.ifoff.other_enabled 启用或禁用所有其他接口上的流量。

mac_ifoff(4) 最常见的用途之一是在引导期间禁止网络流量的环境中进行网络监控。另一用途是编写脚本,使用 security/aide 等应用程序在受保护目录中发现新文件或更改文件时自动阻止网络流量。

28.4.6.7 MAC IP Address Access Control List 策略

模块名称:mac_ipacl.ko

内核配置行:options MAC_IPACL

引导选项:mac_ipacl_load="YES"

mac_ipacl(4) 策略允许主机用 sysctl(8) 接口限制 VNET(9) Jail 设置 IPv4 和 IPv6 地址的能力。默认策略强制执行时拒绝 Jail 的所有 IP 地址。

以下 sysctl 可调参数可用:

  • security.mac.ipacl.ipv4 对 IPv4 地址强制执行 mac_ipacl(默认:1)。
  • security.mac.ipacl.ipv6 对 IPv6 地址强制执行 mac_ipacl(默认:1)。
  • security.mac.ipacl.rules IP 地址访问控制列表,格式为 jid,allow,interface,addr_family,IP_addr/prefix[@jid,...]。其中 allow 为 1 表示允许、0 表示拒绝;interface 留空表示匹配所有接口;addr_familyAF_INETAF_INET6prefix 为 -1 表示单个 IP,非负值表示子网。

多条规则适用于同一 IP 地址时,列表中后定义的规则决定最终结果。

28.4.6.8 MAC Port Access Control List 策略

模块名称:mac_portacl.ko

内核配置行:options MAC_PORTACL

引导选项:mac_portacl_load="YES"

mac_portacl(4) 模块用于限制本地 TCP 和 UDP 端口绑定,使非 root 用户可绑定 1024 以下指定特权端口。

加载后此模块在所有套接字上启用 MAC 策略。提供以下可调参数:

  • security.mac.portacl.enabled 完全启用或禁用此策略。
  • security.mac.portacl.port_high 设置 mac_portacl(4) 保护的最高端口号。
  • security.mac.portacl.suser_exempt 设非零值时将 root 豁免于此策略。
  • security.mac.portacl.autoport_exempt 设非零值(默认)时允许应用程序用端口 0 自动分配,绕过规则检查。
  • security.mac.portacl.rules 以文本字符串指定策略,格式 rule[,rule,…],按需包含任意数量规则,每条格式 idtype:id:protocol:portidtype 应为 uidgidprotocol 可为 tcpudpport 是允许指定用户或组绑定的端口号。用户 ID、组 ID 和端口参数仅用数值。

默认情形下 1024 以下端口仅可由 root 身份运行的特权进程使用。使 mac_portacl(4) 允许非特权进程绑定 1024 以下端口,按如下设置:

sh
# sysctl security.mac.portacl.port_high=1023
# sysctl net.inet.ip.portrange.reservedlow=0
# sysctl net.inet.ip.portrange.reservedhigh=0

警告

net.inet.ip.portrange.reservedlownet.inet.ip.portrange.reservedhigh 均设为 0 会彻底移除内核级特权端口保护机制,使原本仅 root 可绑定的 1-1023 端口不再受任何内核限制。此配置的含义是:用 mac_portacl 的规则层保护完全替代传统 UNIX 特权端口保护

若 mac_portacl 模块因任何原因未加载、被禁用(security.mac.portacl.enabled=0)或规则配置不正确,则系统将回退为 所有用户均可绑定任意端口 的状态——这包括 SSH(22)、HTTP(80)、HTTPS(443)等关键服务端口,可能导致服务劫持或权限提升攻击。务必确保 mac_portacl 始终可靠加载且规则完备。

避免 root 受此策略影响,将 security.mac.portacl.suser_exempt 设非零值:

sh
# sysctl security.mac.portacl.suser_exempt=1

允许 UID 80 的 www 用户绑定端口 80 而无需 root 权限:

sh
# sysctl security.mac.portacl.rules=uid:80:tcp:80

下例允许 UID 1001 用户绑定 TCP 端口 110(POP3)和 995(POP3s):

sh
# sysctl security.mac.portacl.rules=uid:1001:tcp:110,uid:1001:tcp:995

28.4.6.9 MAC NTPD 策略

模块名称:mac_ntpd.ko

内核配置行:options MAC_NTPD

引导选项:mac_ntpd_load="YES"

mac_ntpd(4) 策略模块允许 ntpd(8) 以非 root 用户身份运行,授予 UID 123(ntpd 用户)运行的进程以下特权:

特权说明
PRIV_ADJTIME调整系统时间
PRIV_CLOCK_SETTIME设置系统时钟
PRIV_NTP_ADJTIMENTP 时间调整
PRIV_NETINET_RESERVEDPORT绑定特权端口
PRIV_NETINET_REUSEPORT重用端口

ntpd(8) 使用 -u <user>[:group] 启动时,先以 root 权限初始化再降权切换至指定用户。此策略确保降权后 ntpd 仍能执行时间同步所需特权操作。

以下 sysctl 可调参数可用:

  • security.mac.ntpd.enabled 启用 mac_ntpd 策略(默认:1)。
  • security.mac.ntpd.uid ntpd 用户数字 UID(默认:123)。

28.4.6.10 MAC Partition 策略

模块名称:mac_partition.ko

内核配置行:options MAC_PARTITION

引导选项:mac_partition_load="YES"

mac_partition(4) 策略按进程 MAC 标签将进程放入特定“分区”。此策略大部分配置用 setpmac(8) 完成。sysctl 可调参数:

  • security.mac.partition.enabled 启用 MAC 进程分区强制执行。

启用此策略后用户仅可查看自身进程及分区内其他进程,不得使用超出分区范围的实用程序。例如 insecure 类用户不得访问 top 及许多需要生成进程的命令。

此示例将 top 添加至 insecure 类用户标签集。insecure 类所有进程保持在 partition/13 标签内:

sh
# setpmac partition/13 top

显示分区标签和进程列表:

sh
# ps Zax

显示另一用户进程的分区标签及该用户当前运行进程:

sh
# ps -ZU trhodes

除非加载 mac_seeotheruids(4),否则用户可见 root 标签中进程。

28.4.6.11 MAC Priority 策略

模块名称:mac_priority.ko

内核配置行:options MAC_PRIORITY

引导选项:mac_priority_load="YES"

mac_priority(4) 策略模块按 group(5) 组成员身份授予调度优先级特权。realtime 组(GID 47)用户或进程允许以实时调度优先级运行线程和进程;idletime 组(GID 48)用户或进程允许以空闲调度优先级运行。

realtime 策略授予内核特权:

  • PRIV_SCHED_RTPRIO — 实时优先级
  • PRIV_SCHED_SETPOLICY — 设置调度策略

idletime 策略授予内核特权:

  • PRIV_SCHED_IDPRIO — 空闲优先级

启用 realtime 后特权用户可用 rtprio(1) 以实时优先级启动进程;启用 idletime 后可用 idprio(1) 以空闲优先级启动。应用程序可通过 rtprio(2) 系统调用调整优先级。

以下 sysctl 可调参数可用:

  • security.mac.priority.realtime 启用 realtime 策略(默认:1)。
  • security.mac.priority.realtime_gid realtime 组数字 GID(默认:47)。
  • security.mac.priority.idletime 启用 idletime 策略(默认:1)。
  • security.mac.priority.idletime_gid idletime 组数字 GID(默认:48)。

28.4.6.12 MAC 多级安全模块

模块名称:mac_mls.ko

内核配置行:options MAC_MLS

引导选项:mac_mls_load="YES"

mac_mls(4) 策略实施严格的信息流控制,管理系统中主体与客体之间的访问。

MLS 环境中,各主体或客体的标签包含“许可(clearance)”级别及区间。许可级别可达数千之多,逐一配置每个主体或客体工作量极大。为降低管理负担,此策略内置三种标签:mls/lowmls/equalmls/high

  • mls/low 标签代表低许可级别,不可访问更高级信息,且阻止更高级客体向更低级写入或传递信息。
  • mls/equal 标签适用于需豁免策略的客体。
  • mls/high 为最高许可级别。分配此标签的客体支配系统中所有其他客体,但信息不可泄漏至更低级别客体。

MLS 提供:

  • 分层安全级别,附带一组非层次类别;
  • 固定规则“不上读、不下写(no read up, no write down)”——主体可读取同级或更低级客体,不可读取更高级客体;同理,主体可写入同级或更高级客体,不可写入更低级客体;
  • 保密性(防止数据不当泄漏);
  • 支持同一系统中并行处理多个敏感性级别数据而不会在机密与保密之间泄漏信息的设计基础。
sh
MLS 策略信息流(保密性:不上读、不下写):

  高级别 ◄── 信息可流入

  读取:✗ 不可向上读
  写入:✓ 可向上写

  中级别

  读取:✗ 不可向上读
  写入:✓ 可向上写

  低级别 ──► 信息不可向下流

以下 sysctl 可调参数可用:

  • security.mac.mls.enabled 启用或禁用 MLS 策略。
  • security.mac.mls.ptys_equal 创建时将全部 pty(4) 设备标记为 mls/equal
  • security.mac.mls.revocation_enabled 标签变更为更低等级后撤销对客体的访问。
  • security.mac.mls.max_compartments 设定系统允许的最大区间级别数。

管理 MLS 标签用 setfmac(8)。为客体分配标签:

sh
# setfmac mls/5 test

获取文件 test 的 MLS 标签:

sh
# getfmac test

也可在 /etc/ 路径中创建主策略文件,指定 MLS 策略信息后交由 setfmac 处理。

使用 MLS 策略模块时,管理员需规划敏感信息流动。默认 block read up block write down 将所有对象设为低级别:所有内容均可访问,管理员逐步提升信息机密性。

除三种基本标签之外,管理员可按需对用户和组分组以阻断信息往来。采用描述性词汇(如 ConfidentialSecretTop Secret)查看许可级别信息或更直观。部分管理员按项目级别建立不同分组。不论分类方法如何,施行限制性策略前均需要周密规划。

MLS 策略模块的典型应用场景包含电子商务 Web 服务器、存放关键公司信息的文件服务器及金融机构环境。

28.4.6.13 MAC Biba 模块

模块名称:mac_biba.ko

内核配置行:options MAC_BIBA

引导选项:mac_biba_load="YES"

mac_biba(4) 模块加载 MAC Biba 策略。此策略与 MLS 策略类似,但信息流规则恰好相反:Biba 阻止敏感信息向下流动,而 MLS 阻止敏感信息向上流动。

Biba 环境中,各主体或客体设置“完整性”标签。标签由层次等级和非层次组件组成。等级越高,完整性越高。

支持的标签为 biba/lowbiba/equalbiba/high

  • biba/low 为客体或主体可拥有的最低完整性。对客体或主体设置此标签后,其不可写入 biba/high 标签的客体或主体,但读访问不受限制。
  • biba/equal 仅用于需豁免策略的客体。
  • biba/high 允许写入更低标签的客体,但不可读取更低标签的客体。建议对影响系统整体完整性的客体分配此标签。

Biba 提供:

  • 分层完整性级别,附带一组非层次完整性类别;
  • 固定规则“不上写、不下读(no write up, no read down)”,与 MLS 相反——主体可写入同级或更低级客体,不可写入更高级客体;同理,主体可读取同级或更高级客体,不可读取更低级客体;
  • 完整性保障(防止数据不当篡改);
  • 基于完整性级别而非 MLS 的敏感性级别。
sh
Biba 策略信息流(完整性:不上写、不下读):

  高级别 ──► 信息可向下流

  读取:✓ 可向下读
  写入:✗ 不可向上写

  中级别

  读取:✓ 可向下读
  写入:✗ 不可向上写

  低级别 ◄── 信息不可流入

以下可调参数用于控制 Biba 策略:

  • security.mac.biba.enabled 启用或禁用 Biba 策略强制执行。
  • security.mac.biba.ptys_equal 在 pty(4) 设备上禁用 Biba 策略。
  • security.mac.biba.revocation_enabled 标签变更为支配主体的标签后撤销对客体的访问。

访问系统客体上的 Biba 策略设置用 setfmacgetfmac

sh
# setfmac biba/low test
# getfmac test
test: biba/low

完整性(有别于敏感性)用于保证信息不受不可信方控制,包含主体与客体之间传递的信息。它确保用户仅可修改或访问明确授权其访问的信息。mac_biba(4) 安全策略模块允许管理员配置用户可以查看及调用哪些文件和程序,同时确保这些程序和文件对该用户可信。

初始规划阶段,管理员需要将用户划分到等级、级别和区域中。启用此策略模块后,系统默认设为高标签,由管理员为不同用户配置不同等级和级别。良好的规划方法可按主题而非许可级别划分。例如,仅允许开发人员对源代码仓库、源代码编译程序及其他开发实用程序拥有修改权限;其他用户(如测试人员、设计人员或最终用户)仅允许读访问。

较低完整性主体不可向较高完整性主体写入;较高完整性主体不可列出或读取较低完整性客体。将标签设为尽可能低的等级后,客体可能对主体不可访问。此安全策略模块的适用环境包含受限 Web 服务器、开发与测试计算机及源代码仓库;不太适用的场景包含个人工作站、路由器或网络防火墙。

28.4.6.14 MAC Low-watermark 模块

模块名称:mac_lomac.ko

内核配置行:options MAC_LOMAC

引导选项:mac_lomac_load="YES"

与 MAC Biba 策略不同,mac_lomac(4) 允许访问较低完整性客体,但前提是不破坏完整性规则,且必须在降低自身完整性级别之后。

Low-watermark 完整性策略的工作方式与 Biba 基本一致,区别在于使用了浮动标签:通过辅助等级区间支持主体降级。辅助区间格式为 [auxgrade]。分配带辅助等级的策略时语法为 lomac/10[2],其中 2 是辅助等级。

此策略依赖对所有系统客体普遍标记完整性标签,允许主体从低完整性客体读取后降低主体标签,利用 [auxgrade] 阻止后续对高完整性客体的写入。相比 Biba,此策略兼容性更高、初始配置需求更少。

与 Biba 和 MLS 策略相同,使用 setfmacsetpmac 在系统客体上放置标签:

sh
# setfmac lomac/high[low] /usr/home/trhodes
# getfmac /usr/home/trhodes

辅助等级 low 是 LOMAC 策略独有的功能。

28.4.7 用户锁定

本例设想一个小型存储系统,用户不足五十人。用户可登录、存储数据和访问资源。

此场景下,mac_bsdextended(4) 和 mac_seeotheruids(4) 策略模块可共存,既隐藏用户进程又阻止对系统客体的访问。

首先在 /boot/loader.conf 中添加:

ini
mac_seeotheruids_load="YES"

/etc/rc.conf 中添加以下行以激活 mac_bsdextended(4) 安全策略模块:

ini
ugidfw_enable="YES"

系统初始化时将加载 /etc/rc.bsdextended 中的默认规则。默认条目可能需要修改。此计算机仅用于用户服务,除最后两行外其余均可保留注释,以默认强制加载用户拥有的系统客体。

将所需用户添加到该计算机并重启。测试时,在两个控制台分别以不同用户登录。运行 ps aux 查看其他用户进程是否可见。验证对其他用户主目录执行 ls(1) 是否失败。

除非特定 sysctl 已修改以阻止超级用户访问,否则勿以 root 用户进行测试。

添加新用户时,其 mac_bsdextended(4) 规则不会出现在规则集列表中。要快速更新规则集,先卸载安全策略模块,再用 kldunload(8) 和 kldload(8) 重新加载。

28.4.8 故障排除

本节讨论常见配置错误及其解决方法。

28.4.8.1 multilabel 标志未在根(/)分区上保持启用

如果 multilabel 标志未在根(/)分区上保持启用,以下步骤可解决此临时错误:

  1. 编辑 /etc/fstab,将根分区设为 ro(只读)。
  2. 重启进入单用户模式。
  3. / 上运行命令 tunefs -l enable
  4. 立即运行 mount -urw /,在 /etc/fstab 中将 ro 改回 rw
  5. 重启系统至正常模式。
  6. 仔细检查 mount 输出,确认根文件系统已正确设置 multilabel

28.4.8.2 无法启动 Xorg

使用 MAC 建立安全环境后 Xorg 无法启动。原因可能是 MAC partition 策略或某 MAC 标签策略中标签设置错误。调试步骤如下:

  1. 检查错误消息。如果用户处于 insecure 类,partition 策略可能是问题所在。尝试将用户类恢复为 default 类,使用 cap_mkdb 重建数据库。
  2. 仔细检查标签策略对用户、Xorg 和 /dev 条目的设置。
  3. 如果均无法解决,可将错误消息和环境描述发送到 FreeBSD general questions mailing list

28.4.8.3 切换用户时报错

用户从 root 切换到系统中其他用户时,可能出现错误信息 _secure_path: unable to stat .login_conf。此消息通常发生在用户标签高于欲切换的目标用户时。例如,如果 joe 默认标签为 biba/lowroot 标签为 biba/high,则 root 无法查看 joe 的主目录,因为 Biba 完整性模型不允许 root 查看处于更低完整性级别的客体——无论 root 是否用 su 切换为 joe,均会发生此情况。

28.4.8.4 无法识别 root 用户

系统不再识别 root。此时 whoami 返回 0su 返回 who are you?

此情况可能是标签策略遭 sysctl(8) 禁用或策略模块已卸载所致。如果策略已禁用,需重新配置登录能力数据库:仔细检查 /etc/login.conf 确保已移除所有 label 选项,再用 cap_mkdb 重建数据库。

策略限制对 /etc/master.passwd 的访问时也可能发生此情况。通常因为管理员在不符系统通用策略的标签下更改文件所致。此时系统会读取用户信息,但因为文件继承了新标签而阻止访问。使用 sysctl(8) 禁用该策略后应可恢复。

28.4.9 课后习题

  1. FreeBSD MAC 框架采用模块化设计,内核通过 mac_*.ko 策略模块实现不同强制访问控制策略。请列举至少 4 种 FreeBSD 内置 MAC 策略模块,并简要说明各自应用场景。

  2. MAC 框架与传统自主访问控制(DAC)有何本质区别?

  3. 在 FreeBSD 中启用 MAC 策略模块(如 mac_portacl)时通常需修改 /boot/loader.conf 并重启系统。请编写一个完整配置示例,并说明如何在不重启的情况下验证当前已加载的 MAC 策略模块。