Tom Rhodes Written by 集权式访问控制 概要 MAC 集权式访问控制 MAC &os; 5.X 在 &posix;.1e 草案的基础上引入了 TrustedBSD 项目提供的新的安全性扩展。 新安全机制中最重要的两个, 是文件系统访问控制列表 (ACL) 和集权式访问控制 (MAC) 机制。 集权式访问控制允许加载新的访问控制模块, 并借此实施新的安全策略, 其中一部分为一个很小的系统子集提供保护并加强特定的服务, 其他的则对所有的主体和对象提供全面的标签式安全保护。 定义中有关集权的部分源于如下事实, 控制的实现由管理员和系统作出, 而不像全权式访问控制 (DAC, &os; 中的标准文件以及 System V IPC 权限) 那样是按照用户意愿进行的。 本章将集中讲述集权式访问控制框架 (MAC 框架) 以及一套用以实施多种安全策略的插件式的安全策略模块。 阅读本章之后, 您将了解: 目前 &os; 中具有哪些 MAC 安全策略模块, 以及与之相关的机制。 MAC 安全策略模块将实施何种策略, 以及标签式与非标签式策略之间的差异。 如何高效地配置系统令使其使用 MAC 框架。 如何配置 MAC 框架所提供的不同的安全策略模块。 如何用 MAC 框架构建更为安全的环境, 并举例说明。 如何测试 MAC 配置以确保正确构建了框架。 阅读本章之前, 您应该: 了解 &unix; 和 &os; 的基础 ()。 熟悉内核配置/编译 () 的基础。 对安全及其如何与 &os; 相配合有些了解; ()。 对本章信息的不当使用可能导致丧失系统访问权, 激怒用户, 或者无法访问 X11 提供的特性。 更重要的是, MAC 不能用于彻底保护一个系统。 MAC 框架仅用于增强现有安全策略; 如果没有健全的安全条例以及定期的安全检查, 系统将永远不会绝对安全。 此外还需要注意的是, 本章中所包含的例子仅仅是例子。 我们并不建议在一个生产用系统上进行这些特别的设置。 实施各种安全策略模块需要谨慎的考虑, 因为那些并不完全理解所有机制如何工作的人, 可能会发现需要对整个系统中很多的文件或目录进行重新配置。 未涉及的内容 本章涵盖了与 MAC 框架有关的诸多方面的安全问题; 尽管如此, 本章将不涉及新 MAC 安全策略模块的开发成果。 MAC 框架中所包含的一部分安全策略模块, 具有一些用于测试及新模块开发的特定属性, 其中包括 &man.mac.test.4;、 &man.mac.stub.4; 以及 &man.mac.none.4;。 关于这些安全策略模块及其提供的众多机制的详细信息,请参阅联机手册中的内容。 本章出现的重要术语 在阅读本章之前, 有些关键术语需要解释, 希望能藉此扫清可能出现的疑惑, 并避免在文中对新术语、 新信息进行生硬的介绍。 区间: 区间, 是指一组被划分或隔离的程序和数据, 其中, 用户被明确地赋予了访问特定系统组件的权限。 同时, 区间也能够表达分组, 例如工作组、 部门、 项目, 或话题。 可以通过使用区间来实施 need-to-know 安全策略。 完整性: 作为一个关键概念, 完整性是数据可信性的一种程度。 若数据的完整性提高, 则数据的可信性相应提高。 标签: 标签是一种可应用于文件、 目录或系统其他对象的安全属性, 它也可以被认为是一种机密性印鉴。 当一个文件被施以标签时, 其标签会描述这一文件的安全参数, 并只允许拥有相似安全性设置的文件、 用户、 资源等访问该文件。 标签值的涵义及解释取决于相应的策略配置: 某些策略会将标签当作对某一对象的完整性和保密性的表述, 而其它一些策略则会用标签保存访问规则。 程度: 对某种安全属性加强或削弱的设定。 若程度增加, 其安全性也相应增加。 多重标签 (multilabel) 属性是一个文件系统选项。 该选项可在单用户模式下通过 &man.tunefs.8; 程序进行设置。 可以在引导时使用的 &man.fstab.5; 文件中, 也可在创建新文件系统时进行配置。 该选项将允许管理员对不同对象施以不同的 MAC 标签。 该选项仅适用于支持标签的安全策略模块。 对象: 对象或系统对象是一种实体, 信息随 主体 的导向在对象内部流动。 对象包括目录、 文件、 区段、 监视器、 键盘、 存储器、 磁存储器、 打印机及其它数据存储/转移设备。 基本上, 一个对象就是一个数据容器或一种系统资源。 对 对象 的访问实际上意味着对数据的访问。 策略: 一套用以规定如何达成目标的规则。 策略 一般用以描述如何对特定对象进行操作。 本章将在安全策略的范畴内讨论策略, 一套用以控制数据和信息流并规定其访问者的规则,就是其中一例。 敏感性: 通常在讨论 MLS 时使用。 敏感性程度曾被用来描述数据应该有何等的重要或机密。 若敏感性程度增加, 则保密的重要性或数据的机密性相应增强。 单一标签: 整个文件系统使用一个标签对数据流实施访问控制, 叫做单一标签。 当文件系统使用此设置时, 即无论何时当 选项未被设定时, 所有文件都将遵守相同标签设定。 主体: 主体就是引起信息在两个 对象间流动的任意活动实体, 比如用户, 用户处理器, 系统进程等。 在 &os; 中, 主体几乎总是代表用户活跃在某一进程中的一个线程。 关于 MAC 的说明 在掌握了所有新术语之后, 我们从整体上来考虑 MAC 是如何加强系统安全性的。 MAC 框架提供的众多安全策略模块可以用来保护网络及文件系统, 也可以禁止用户访问某些特定的端口、 套接字及其它对象。 将策略模块组合在一起以构建一个拥有多层次安全性的环境, 也许是其最佳的使用方式, 这可以通过一次性加载多个安全策略模块来实现。 在多层次安全环境中, 多重策略模块可以有效地控制安全性, 这一点与加强式策略不同。 加强式策略一般加强仅具有某些特殊用途的系统对象的安全性。 相比之下, 多重策略的唯一不足是需要系统管理员先期设置好参数, 如多重文件系统安全标志、每一位用户的网络访问权限等等。 与框架长久的效果相比, 这些不足之处微乎其微。 例如, 为某种特殊配置选择其所需策略的能力, 会使整体性能下降, 但减少对无用策略的支持却可以提高系统整体性能, 同时还可以为选择提供弹性空间。 好的应用应该考虑到整体的安全性要求, 并有效地实施框架提供的众多安全策略模块。 这样一个使用 MAC 特性的系统, 至少要保证不允许用户任意更改安全属性; 所有的用户实用工具、 程序以及脚本, 必须在所选安全策略模块提供的访问规则的约束下工作; 并且系统管理员应掌握 MAC 访问规则的一切控制权。 细心选择正确的安全策略模块是系统管理员专有的职责。 某些环境也许需要限制网络的访问控制权, 在这种情况下, 使用 &man.mac.portacl.4;、 &man.mac.ifoff.4; 乃至 &man.mac.biba.4; 安全策略模块都会是不错的开始; 在其他情况下, 系统对象也许需要严格的机密性, 像 &man.mac.bsdextended.4; 和 &man.mac.mls.4; 这样的安全策略模块就是为此而设。 对安全策略模块的决定可依据网络配置进行, 也许只有特定的用户才应该被允许使用由 &man.ssh.1; 提供的程序以访问网络或互联网, &man.mac.portacl.4; 安全策略模块应该成为这种情况下的选择。 但对文件系统又该作些什么呢? 是由特定的用户或群组来确定某些目录的访问权限, 抑或是将特定对象设为保密以限制用户或组件访问特定文件? 在文件系统的例子中, 也许访问对象的权限对某些用户是保密的, 但对其他则不是。 比如, 一个庞大的开发团队, 也许会被分成许多由几人组成的小组, A 项目中的开发人员可能不被允许访问 B 项目开发人员创作的对象, 但同时他们还需要访问由 C 项目开发人员创作的对象, 这正符合上述情形。 使用由 MAC 框架提供的不同策略, 用户就可以被分成这种小组, 然后被赋予适当区域的访问权, 由此, 我们就不用担心信息泄漏的问题了。 因此, 每一种安全策略模块都有其处理系统整体安全问题的独特方法。 对安全策略模块的选择应在对安全策略深思熟虑的基础之上进行。 很多情况下, 整体安全策略需要重新修正并在系统上实施。 理解 MAC 框架提供的不同安全策略模块会帮助管理员就其面临的情形选择最佳的策略模块。 &os; 的默认内核并不包含 MAC 框架选项, 因此, 在尝试使用本章中的例子或信息之前, 您应该添加以下内核选项: options MAC 此外, 内核还需要重新编译并且重新安装。 尽管有关 MAC 的许多联机手册中都声明它们可以被编译到内核中, 但对这些策略模块的使用仍可能导致锁死系统的网络及其他功能。 使用 MAC 就像使用防火墙一样, 因此必须要小心防止将系统完全锁死。 在使用 MAC 时, 应该考虑是否能够回退到之前的配置, 在远程进行配置更应加倍小心。 理解 MAC 标签 MAC 标签是一种安全属性, 它可以被应用于整个系统中的主体和对象。 配置标签时, 用户必须能够确切理解其所进行的操作。 对象所具有的属性取决于被加载的策略模块, 不同策略模块解释其属性的方式也差别很大。 由于缺乏理解或无法了解其间联系而导致的配置不当, 会引起意想不到的, 也许是不愿看到的系统异常。 对象上的安全标签是由安全策略模块决定的安全访问控制的一部分。 在某些策略模块中, 标签本身所包含的所有信息足以使其作出决策, 而在其它一些安全策略模块中, 标签则可能被作为一个庞大规则体系的一部分进行处理。 举例来说, 在文件上设定 biba/low 标签, 意味着此标签隶属 Biba 策略模块, 其值为 low 某些在 &os; 中支持标签特性的策略会提供三个预定义的标签, 分别是 low、 high 及 equal 标签。 尽管这些标签在不同安全策略模块中会对访问控制采取不同措施, 但有一点是可以肯定的, 那就是 low 标签表示最低限度的设定, equal 标签会将主体或对象设定为被禁用的或不受影响的, high 标签则会应用 Biba 及 MLS 安全策略模块中允许的最高级别的设定。 在单一标签文件系统的环境中, 同一对象上只会应用一个标签, 于是, 一套访问权限将被应用于整个系统, 这也是很多环境所全部需要的。 另一些应用场景中, 我们需要将多重标签应用于文件系统的对象或主体, 如此一来, 就需要使用 &man.tunefs.8; 的 选项。 在使用 Biba 和 MLS 时可以配置数值标签, 以精确地标示分级控制的中的程度。 数值的程度可以用来划分或将信息按组分类, 从而只允许同程度或更高程度的组对齐进行访问。 多数情况下, 管理员将仅对整个文件系统设定单一标签。 等一下, 这看起来很像 DAC! 但我认为 MAC 确实只将控制权赋予了管理员。 此声明依然有效。 在某种程度上, root 是实施控制的用户, 他配置安全策略模块以使用户们被分配到适当的类别/访问 levels 中。 唉, 很多安全策略模块同样可以限制 root 用户。 对于对象的基本控制可能会下放给群组, 但 root 用户随时可以废除或更改这些设定。 这就是如 Biba 及 MLS 这样一些安全策略模块所包含的 hierarchal/clearance 模型。 配置标签 实际上, 有关标签式安全策略模块配置的各种问题都是用基础系统组件实现的。 这些命令为对象和主体配置以及配置的实施和验证提供了一个简便的接口。 所有的配置都应该通过 &man.setfmac.8; 及 &man.setpmac.8; 组件实施。 setfmac 命令是用来对系统对象设置 MAC 标签的, 而 setpmac 则是用来对系统主体设置标签的。 例如: &prompt.root; setfmac biba/high test 若以上命令不发生错误则会直接返回命令提示符, 只有当发生错误时, 这些命令才会给出提示, 这和 &man.chmod.1; 和 &man.chown.8; 命令类似。 某些情况下, 以上命令产生的错误可能是 Permission denied, 一般在受限对象上设置或修改设置时会产生此错误。 其它情况也能导致不同的执行失败。 例如, 文件可能并不隶属于尝试重标签该文件的用户, 对象可能不存在或着是只读的。 文件的某一属性、 进程的某一属性或新的自定义标签值的某一属性, 将使集权式策略不允许进程重标签文件。 例如: 低完整性的用户试图修改高完整性文件的标签, 或者低完整性的用户试图将低完整性文件的标签改为高完整性标签。 系统管理员可使用以下命令解决此问题: &prompt.root; setfmac biba/high test Permission denied &prompt.root; setpmac biba/low setfmac biba/high test &prompt.root; getfmac test test: biba/high 如上所示, 通过 setpmac 对被调用的进程赋予不同的标签, 以覆盖安全策略模块的设置。 getpmac 组件通常用于当前运行的进程, 如 sendmail: 尽管其使用进程编号来替代命令, 其逻辑是相同的。 如果用户试图对其无法访问的文件进行操作, 根据所加载的安全策略模块的规则, 函数 mac_set_link 将会给出 Operation not permitted 的错误提示。 一般标签类型 &man.mac.biba.4;、 &man.mac.mls.4; 及 &man.mac.lomac.4; 策略模块提供了设定简单标签的功能, 其值应该是 high、 equal 及 low 之一。 以下是对这些标签功能的简单描述: low 标签被认为是主体或对象所具有的最低层次的标签设定。 对主体或对象采用此设定, 将阻止其访问标签为 high 的对象或主体。 equal 标签只能被用于不希望受策略控制的对象上。 high 标签对对象或主体采用可能的最高设定。 至于每个策略模块, 每种设定都会产生不同的信息流指令。 阅读联机手册中相关的章节将进一步阐明这些一般标签配置的特点。 标签高级配置 如下所示, 用于 比较: 区间+ 区间 的数值等级数: biba/10:2+3+6(5:2+3-20:2+3+4+5+6) 可被解释为: Biba 策略标签/等级10区间 2、 3及6: (等级5 ...) 本例中, 第一个等级将被认为是 有效区间有效等级, 第二个等级是低级等级, 最后一个则是高级等级。 大多数配置中不会使用这些设置, 实际上, 它们是为更高级的配置准备的。 当把它们应用在系统对象上时, 则只有当前的等级/区间, 因为它们反映可以实施访问控制的系统中可用的范围, 以及网络接口。 等级和区间, 可以用来在一对主体和对象之间建立一种称为 支配 的关系, 这中关系可能是主体支配对象, 对象支配主体, 互不支配或互相支配。 互相支配 这种情况会在两个标签相等时发生。 由于 Biba 的信息流特性, 您可以设置一系列区间, need to know, 这可能发生于项目之间, 而对象也由其对应的区间。 用户可以使用 susetpmac 来将他们的权限进一步细分, 以便在没有限制的区间里访问对象。 用户和标签设置 用户本身也需要设置标签, 以使其文件和进程能够正确地与系统上定义的安全策略互动, 这是通过使用登录分级在文件 login.conf 中配置的。 每个使用标签的策略模块都会进行用户分级设定。 以下是一个使用所有策略模块的例子: default:\ :copyright=/etc/COPYRIGHT:\ :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),lomac10[2]: label 选项用以设定用户分级默认标签, 该标签将由 MAC 执行。 用户绝不会被允许更改该值, 因此其从用户的观点看不是可选的。 当然, 在真实情况的配置中, 管理员不会希望启用所有策略模块。 我们建议您在实施以上配置之前阅读本章的其余部分。 用户也许会在首次登录后更改其标签, 尽管如此, 这仅仅是策略的主观局限性。 上面的例子告诉 Biba 策略, 进程的最小完整性是为5, 最大完整性为15, 默认且有效的标签为10。 进程将以10的完整性运行直至其决定更改标签, 这可能是由于用户使用了 setpmac 命令 (该操作将在登录时被 Biba 限制在一定用户范围之内)。 在所有情况下, 修改 login.conf 之后, 都必须使用 cap_mkdb 重编译登录分级 capability 数据库, 这在接下来的例子和讨论中就会有所体现。 很多站点可能拥有数目可观的用户需要不同的用户分级, 注意到这点是大有裨益的。 深入来说就是需要事先做好计划, 因为管理起来可能十分困难。 在 &os 以后的版本中, 将包含一种将用户映射到标签的新方式, 尽管如此, 这也要到 &os; 5.3 之后的某个时间才能实现。 网络接口和标签设定 也可以在网络接口上配置标签, 以控制进出网络的数据流。 在所有情况下, 策略都会以适应对象的方式运作。 例如, 在 biba 中设置为高的用户, 就不能访问标记为低的网络接口。 可以作为 ifconfig 的参数用于设置网络接口的 MAC 标签。 例如: &prompt.root; ifconfig bge0 maclabel biba/equal 将在 &man.bge.4; 接口上设置 biba/equalMAC 标签。 当使用类似 biba/high(low-high) 这样的标签时, 整个标签应使用引号括起来; 否则将发生错误。 每一个支持标签的策略模块都提供了用于在网络接口上禁用该 MAC 标签的系统控制变量。 将标签设置为 的效果与此类似。 请参见 sysctl 的输出、 策略模块的联机手册, 或本章接下来的内容, 以了解更进一步的详情。 用单一标签还是多重标签? 默认情况下, 系统采用的是 选项。 但这对管理员意味着什么呢? 两种策略之间存在很多的不同之处, 它们在系统安全模型的灵活性方面, 提供了不同的选择。 只允许在每个 subject 或对象上使用一个标签, 如 biba/high。 这降低了管理的开销, 但也同时降低了支持标签的策略的灵活性。 许多管理员可能更希望在安全策略中使用 选项允许每一个 subject 或对象拥有各自独立的 MAC 标签, 起作用与标准的、 只允许整个分区上使用一个的 选项类似。 标签选项只有对实现了标签功能的那些策略, 如 Biba、 Lomac、 MLS 以及 SEBSD 才有意义。 很多情况下是不需要设置 的。 考虑下列情形和安全模型: 使用了 MAC 以及许多混合策略的 &os; web-服务器。 这台机器上的整个系统中只需要一个标签, 即 biba/high。 此处的文件系统并不需要 选项, 因为有效的 label 只有一个。 因为这台机器将作为 Web 服务器使用, 因此应该以 biba/low 运行 Web 服务, 以杜绝向上写。 Biba 策略以及它如何运作将在稍后予以讨论, 因此, 如果您感觉前面的说明难以理解的话, 请继续阅读下面的内容, 再回来阅读这些内容就会有较为清晰的认识了。 服务器可以使用设置为 biba/low 的单独的分区, 用于保持其运行环境的状态。 这个例子中还省略了许多内容, 例如, 如何为数据配置访问限制、 参数配置和用户的设置; 它只是为前述的内容提供一个简单的例子。 如果打算使用非标签式策略, 就不需要 选项了。 这些策略包括 seeotheruidsportaclpartition 另一个需要注意的事情是, 在分区上使用 并建立基于 可能会提高系统管理的开销, 因为文件系统中的所有对象都需要指定标签。 这包括对目录、文件, 甚至设备节点。 接下来的命令将在需要使用多个标签的文件系统上设置 。 这一操作只能在单用户模式下完成: &prompt.root; tunefs -l enable / 交换区不需要如此配置。 某些用户可能会在根分区上配置 标志时遇到困难。 如果发生这样的情况, 请复查本章的 用系统控制变量控制 MAC 即使在没有加载任何模块的时候, 也仍然有一些可以通过 sysctl 接口来控制的 MAC 特性。 这些系统控制变量将在下面予以描述, 在所有的例子中, 数字一 (1) 都表示启用, 而数字零 (0) 则表示禁用: security.mac.enforce_fs 表示在文件系统上启用 MAC 策略。 security.mac.enforce_kld 表示启用动态内核连接器 (参见 &man.kld.4;) 上的 MAC 内核连接策略。 security.mac.enforce_network 表示启用 MAC 网络策略。 security.mac.enforce_pipe 表示启用 MAC 管道策略。 security.mac.enforce_process 表示启用使用进程间通讯机制的进程上的 MAC 策略。 security.mac.enforce_socket 表示启用 socket 上的 MAC 策略 (参见 &man.socket.2; 联机手册)。 security.mac.enforce_system 表示启用系统活动, 如记账和重新启动的 MAC 策略。 security.mac.enforce_vm 表示启用虚拟内存系统上的 MAC 策略。 每个策略或 MAC 选项都支持通过系统控制变量来进行调整。 这些选项通常都位于 security.mac.<策略名> 的树状结构之下。 要查看所有的 MAC 系统控制变量, 可以使用下述命令: &prompt.root; sysctl -da | grep mac 前面的所有基本 MAC 策略默认都会启用。 如果编入内核的模块被过分锁死, 则可能无法与局域网或 Internet 进行通讯, 或发生其他严重问题。 这也是为什么不完全鼓励将这些模块编入内核的原因。 尽管这样做并不妨碍通过使用 sysctl 来禁用这些策略, 但以模块方式加载可以让管理员更容易地切换是否使用策略, 而不需要构建和重新安装一套新系统。 模块配置 MAC 框架中的每个模块, 都可以像前述那样连编入内核, 或作为运行时内核模块加载。 推荐的用法, 是通过在 /boot/loader.conf 加入适当的设置, 以便在系统启动时的初始化操作过程中加载这些模块。 接下来的一些小节, 将讨论许多 MAC 模块, 并简单介绍它们的功能。 此外, 这一章还将介绍一些具体环境中的用例。 某些模块支持一种称为标签 (labeling) 的用法, 它可以通过使用类似 允许做这个而不允许做那个 的标签来实现访问控制。 标签配置文件可以控制允许的文件访问方式、 网络通讯, 以及许多其他权限。 在前一节中, 我们已经展示了文件系统中如何通过 标志来启用基于文件或分区的访问控制的方法。 单标签配置在整个系统中只强制一个标签的限制, 这也是 tunefs 选项为什么是 的原因。 MAC seeotheruids 模块 MAC 其他 UID 可见策略 模块名: mac_seeotheruids.ko 对应的内核配置: options MAC_SEEOTHERUIDS 引导选项: mac_seeotheruids_load="YES" &man.mac.seeotheruids.4; 模块模仿并扩展了 security.bsd.see_other_uidssecurity.bsd.see_other_gids sysctl 变量。 这一模块并不需要预先配置标签, 它能够透明地与其他模块协同工作。 加载模块之后, 下列 sysctl 变量可以用来控制其功能: security.mac.seeotheruids.enabled 将启用模块的功能, 并使用默认的配置。 这些默认设置将阻止用户看到其他用户的进程和 socket。 security.mac.seeotheruids.specificgid_enabled 将允许特定的组从这一策略中和面。 要将某些组排除在这一策略之外, 可以用 security.mac.seeotheruids.specificgid=XXX sysctl 变量。 前述例子中, XXX 应替换为希望不受限的组 ID 的数值形式。 security.mac.seeotheruids.primarygroup_enabled 可以用来将特定的主要组排除在策略之外。 使用这一变量时, 不能同时设置 security.mac.seeotheruids.specificgid_enabled MAC bsdextended 模块 MAC 文件系统防火墙策略 模块名: mac_bsdextended.ko 对应的内核配置: options MAC_BSDEXTENDED 引导选项: mac_bsdextended_load="YES" &man.mac.bsdextended.4; 模块能够强制文件系统防火墙策略。 这一模块的策略提供了标准文件系统权限模型的一种扩展, 使得管理员能够建立一种类似防火墙的规则集, 以文件系统层次结构中的保护文件、 实用程序,以及目录。 这类策略可以通过工具 &man.ugidfw.8; 工具来创建, 其语法类似 &man.ipfw.8;。 此外还可以通过使用 &man.libugidfw.3; 库来开发其他的工具。 当使用这一模块模块时应极其小心; 不正确的使用将导致文件系统的某些部分无法访问。 例子 在加载了 &man.mac.bsdextended.4; 模块之后, 下列命令可以用来列出当前的规则配置: &prompt.root; ugidfw list 0 slots, 0 rules 如希望的那样, 目前还没有定义任何规则。 这意味着一切都还可以访问。 要创建一个阻止所有用户, 而保持 root 不受影响的规则, 只需运行下面的命令: &prompt.root; ugidfw add subject not uid root new object not uid root mode n 在 &os; 5.3 之前的版本中, add 参数并不存在。 此时应使用 set 来代替它。 请参见下面的命令例子。 这本身可能是一个很糟糕的主意, 因为它会阻止所有用户执行哪怕最简单的命令, 例如 ls。 更富于爱心的规则可能是: &prompt.root; ugidfw set 2 subject uid user1 object uid user2 mode n &prompt.root; ugidfw set 3 subject uid user1 object gid user2 mode n 这将阻止任何 user1user2 的主目录的全部访问, 包括目录列表。 user1 可以用 代替。 这将同样的强制访问控制实施在所有用户, 而不是单个用户上。 root 用户不会受到这些变动的影响。 我们已经给出了 &man.mac.bsdextended.4; 模块如何帮助加强文件系统的大致介绍。 要了解更进一步的信息, 请参见 &man.mac.bsdextended.4; 和 &man.ugidfw.8; 联机手册。 MAC ifoff 模块 MAC 接口屏蔽策略 模块名: mac_ifoff.ko 对应的内核配置: options MAC_IFOFF 引导选项: mac_ifoff_load="YES" &man.mac.ifoff.4; 模块完全是为了立即禁止网络接口, 以及阻止在系统初启时启用网络接口而设计的。 它不需要再系统中配置任何标签, 也不依赖于其他 MAC 模块。 绝大多数特性都可以通过调整下面的 sysctl 来加以控制。 security.mac.ifoff.lo_enabled 表示 启用/禁用 环回接口 (&man.lo.4;) 上的全部流量。 security.mac.ifoff.bpfrecv_enabled 表示 启用/禁用 伯克利包过滤器 (&man.bpf.4;) 接口上的全部流量。 security.mac.ifoff.other_enabled 将在所有其他接口 启用/禁用 网络。 最为常用的 &man.mac.ifoff.4; 用法之一是在不允许引导过程中出现网络流量的环境中监视网络。 另一个建议的用法是撰写一个使用 security/aide 的脚本, 以便自动地在受保护的目录中发现新的或修改过的文件时切断网络。 MAC portacl 模块 MAC 端口访问控制表策略 模块名: mac_portacl.ko 对应的内核配置: MAC_PORTACL 引导选项: mac_portacl_load="YES" &man.mac.portacl.4; 模块可以用来通过一系列 sysctl 变量来限制绑定本地的 TCPUDP 端口。 本质上 &man.mac.portacl.4; 使得 非-root 用户能够绑定到它所指定的特权端口, 也就是那些编号小于 1024 的端口。 在加载之后, 这个模块将在所有的 socket 上启用 MAC 策略。 可以调整下列一些配置: security.mac.portacl.enabled 将完全 启用/禁用 策略。 由于一个 bug, security.mac.portacl.enabled sysctl 变量在 &os; 5.2.1 和更早版本上并不起作用。 security.mac.portacl.port_high 将设置为 &man.mac.portacl.4; 所保护的最高端口号。 security.mac.portacl.suser_exempt 如果设置为非零值, 表示将 root 用户排除在策略之外。 security.mac.portacl.rules 将指定实际的 mac_portacl 策略; 请参见下文。 实际的 mac_portacl 策略, 是在 security.mac.portacl.rules sysctl 所指定的一个下列形式的字符串: rule[,rule,...] 其中可以给出任意多个规则。 每一个规则的形式都是: idtype:id:protocol:port。 这里的 idtype 参数可以是 uidgid, 分别表示将 id 参数解释为用户 id 或组 id。 protocol 参数可以用来确定希望应用到 TCPUDP 协议上, 方法是把这一参数设置为 tcpudp。 最后的 port 参数则给出了所指定的用户或组能够绑定的端口号。 由于规则集会直接由内核加以解释, 因此只能以数字形式表示用户 ID、 组 ID, 以及端口等参数。 换言之, 您不能使用用户、 组, 或端口服务的名字来指定它们。 默认情况下, 在 类-&unix; 系统中, 编号小于 1024 的端口只能为特权进程使用或绑定, 也就是那些以 root 身份运行的进程。 为了让 &man.mac.portacl.4; 能够允许非特权进程绑定低于 1024 的端口, 就必须首先禁用标准的 &unix; 限制。 这可以通过把 &man.sysctl.8; 变量 net.inet.ip.portrange.reservedlownet.inet.ip.portrange.reservedhigh 设置为 0 来实现。 请参见下面的例子, 或 &man.mac.portacl.4; 联机手册中的说明, 以了解进一步的信息。 例子 下面的例子更好地展示了前面讨论的内容: &prompt.root; sysctl security.mac.portacl.port_high=1023 &prompt.root; sysctl net.inet.ip.portrange.reservedlow=0 net.inet.ip.portrange.reservedhigh=0 首先我们需要设置使 &man.mac.portacl.4; 管理标准的特权端口, 并禁用普通的 &unix; 绑定限制。 &prompt.root; sysctl security.mac.portacl.suser_exempt=1 您的 root 用户不应因此策略而失去特权, 因此请把 security.mac.portacl.suser_exempt 设置为一个非零的值。 现在您已经成功地配置了 &man.mac.portacl.4; 模块, 并使其默认与 类-&unix; 系统一样运行了。 &prompt.root; sysctl security.mac.portacl.rules=uid:80:tcp:80 允许 UID 为 80 的用户 (正常情况下, 应该是 www 用户) 绑定到 80 端口。 这样 www 用户就能够运行 web 服务器, 而不需要使用 root 权限了。 &prompt.root; sysctl security.mac.portacl.rules=uid:1001:tcp:110,uid:1001:tcp:995 允许 UID 为 1001 的用户绑定 TCP 端口 110 (pop3) 和 995 (pop3s)。 这样用户就能够启动接受来发到 110 和 995 的连接请求的服务了。 包含标签功能的 MAC 策略 接下来的几节中, 将讨论使用标签的 MAC 策略。 这一章从此处开始将集中于对 &man.mac.biba.4;、 &man.mac.lomac.4;、 &man.mac.partition.4;, 以及 &man.mac.mls.4; 的介绍。 此处提供的仅仅是示范的配置, 不应用于在实际的生产环境中实施。 这份文档的目标是在展示配置写法的同时, 以实例的形式, 对如何实施和进行测试予以介绍。 要让配置正确工作, 首先需要进行一些准备工作。 准备使用标签策略 下述修改需要在 login.conf 文件上实施: 需要增加一个 insecure 级, 或其他类似类型的分级。 这里, insecure 级并不是必需的, 只是作为例子加以展示; 不同的配置完全可以使用其他的分级名称。 insecure 级应包含下列配置和定义。 其中的许多内容都可以根据需要修改, 但定义了默认标签的行都是必需的, 您应留下它们。 insecure:\ :copyright=/etc/COPYRIGHT:\ :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/low: 需要在 &man.login.conf.5; 上执行 &man.cap.mkdb.1; 之后, 用户才能够切换到新的分级。 root 用户也应出现在某个登录级中; 否则, root 执行每一个命令的时候, 都需要使用 setpmac 重建 login.conf 数据库可能会导致 daemon 级在稍后发生某些错误。 简单地去掉注释掉 daemon 的注释符并重建数据库, 会有助于消除这类问题。 确保将要使用 MAC 标签的所有分区, 都能够支持 。 我们必须这样做, 因为这里的很多例子中都包含了不同的、 用于测试目的的标签。 作为预防性措施之一, 您应复查 mount 命令的输出结果。 把将被应用更高级别的安全机制的那些用户转到新的用户 class 中。 运行 &man.pw.8; 或 &man.vipw.8; 可以完成这样的任务。 MAC partition (分区) 模块 MAC 进程分区策略 模块名: mac_partition.ko 对应的内核配置: options MAC_PARTITION 引导选项: mac_partition_load="YES" &man.mac.partition.4; 策略将把进程基于其 MAC 标签放到特定的 partitions (分区) 中。 这是一种特殊类型的 &man.jail.8;, 但对两者进行比较意义不大。 这个模块应加到 &man.loader.conf.5; 文件中, 以便在启动过程中启用这些规则。 绝大多数这一策略的配置是通过 &man.setpmac.8; 工具来完成的, 它将在后面介绍。 这个策略可以使用下面的 sysctl security.mac.partition.enabled 将启用强制的 MAC 进程 partitions。 当启用了这个规则时, 用户将只被允许看到他们自己的进程, 而无法使用某些工具。 例如, 在前面提到的 insecure class 中的用户, 将无法使用 top 命令, 以及其他必需生成进程的命令。 要设置或删除 partition 标签中的工具, 需要使用 setpmac &prompt.root; setpmac partition/13 top 这将把 top 命令加入到 insecure class 中的用户的标签集。 注意, 所有由 insecure class 中的用户产生的进程, 仍然会留在 partition/13 标签中。 例子 下面的命令将显示 partition 标签以及进程列表: &prompt.root; ps Zax 接下来的这个命令将允许察看其他用户的进程 partition 标签, 以及那个用户正在运行的进程: &prompt.root; ps -ZU trhodes 除非加载了 &man.mac.seeotheruids.4; 策略, 否则用户就看不到 root 的标签。 非常手工化的实现, 可能会在 /etc/rc.conf 中禁用所有的服务, 并用脚本来按不同的标签来启动它们。 下面的几个策略支持基于所给出的三种标签的完整性设定。 这些选项, 连同它们的限制, 在模块的联机手册中进行了进一步介绍。 MAC Multi-Level 安全模块 MAC Multi-Level 安全策略 模块名: mac_mls.ko 对应的内核配置: options MAC_MLS 引导选项: mac_mls_load="YES" &man.mac.mls.4; 策略, 通过严格控制信息流向来控制系统中主体和对象的访问。 MLS 环境中, clearance(透明度) 级别会在每一个主体或对象标签上进行设置, 连同对应的区间。 由于这些透明度或敏感度可以有六千多个层次, 因此为每一个主体或对象进行配置将是一件让任何系统管理员都感到头疼的任务。 所幸的是, 这个策略中已经包含了三个 立即可用的 标签。 这些标签是 mls/lowmls/equal 以及 mls/high。 由于这些标签已经在联机手册中进行了介绍, 这里只给出简要的说明: mls/low 标签包含了最低配置, 从而允许其他对象支配它。 任何标记为 mls/low 的对象将是地透明度的, 从而不允许访问更高级别的信息。 此外, 这个标签也阻止拥有较高透明度的对象向其写入或传递信息。 mls/equal 标签应放到不希望使用这一策略的对象上。 mls/high 标签是允许的最高级别透明度。 指定了这个标签的对象将支配系统中的其他对象; 但是, 它们将不允许向较低级别的对象泄露信息。 MLS 提供了: 提供了一些非层次分类的层次安全模型; 固定规则: 不允许向上读, 不允许向下写 (主体可以读取同级或较低级别的对象, 但不能读取高级别的。 类似地, 主体可以向同级或较高级写, 而不能向下写); 保密 (防止不适当的数据透露); 系统设计的基础要点, 是在多个敏感级别之间并行地处理数据 (而不泄露秘密的和机密的信息)。 下列 sysctl 可以用来配置特殊服务和接口: security.mac.mls.enabled 用来启用/禁用 MLS 策略。 security.mac.mls.ptys_equal 将所有的 &man.pty.4; 设备标记为 mls/equal security.mac.mls.revocation_enabled 可以用来在标签转为较低 grade 时撤销对象访问权。 security.mac.mls.max_compartments 可以用来设置对象的最大区间层次; 基本上, 这也就是系统中所允许的最大区间数。 要管理 MLS 标签, 可以使用 &man.setfmac.8; 命令。 要在对象上指定标签, 需要使用下面的命令: &prompt.root; setfmac mls/5 test 下述命令用于取得文件 test 上的 MLS 标签: &prompt.root; getfmac test 这是 MLS 策略特性的一个摘要。 另一种方法是建立一个主策略文件, 把它放到 /etc, 指定 MLS 策略信息, 并作为 setfmac 命令的输入。 这一方法将在其他策略之后进行介绍。 观察: 拥有较低 clearance 的对象不能够观察较高 clearance 的进程。 基本的策略是在每一个不应被读取的对象上应用 mls/high, 即使需要在其上进行写操作。 在每所有不应被写的对象上应用 mls/low, 即使需要在其上进行度操作。 最后, 在其他对象上应用 mls/equal。 所有标记为 insecure 的用户应被设置为 mls/low MAC Biba 模块 MAC Biba 完整性策略 模块名: mac_biba.ko 对应的内核配置: options MAC_BIBA 引导选项: mac_biba_load="YES" &man.mac.biba.4; 模块将加载 MAC Biba 策略。 这个策略与 MLS 策略非常类似, 只是信息流的规则有些相反的地方。 通俗地说, 这就是防止敏感信息向下传播, 而 MLS 策略则是防止敏感信息的向上传播; 因而, 这一节的许多内容都可以同时应用于两种策略。 在 Biba 环境中, integrity (完整性) 标签, 将设置在每一个 subject 或对象上。 这些标签是按照层次级别建立的。 如果对象或 subject 的级别被提升, 其完整性也随之提升。 被支持的标签是 biba/lowbiba/equal 以及 biba/high; 解释如下: biba/low 标签被认为是对象或 subject 所能拥有的最低完整性级别。 在对象或 subject 上设置它, 将阻止其在更高级别对象或 subject 的写操作, 虽然读仍被允许。 biba/equal 标签只应在那些希望排除在策略之外的对象上设置。 biba/high 允许向较低标签的对象上写, 但不允许读那些对象。 推荐在那些可能影响整个系统完整性的对象上设置这个标签。 Biba 提供了: 层次式的完整性级别, 并提供了一组非层次式的完整性分类; 固定规则: 不允许向上写, 不允许向下读 (与 MLS 相反)。 subject 可以在它自己和较低的级别写, 但不能向更高级别实施写操作。 类似地, subject 也可以读在其自己的, 或更高级别的对象, 但不能读取较低级别的对象; 完整性 (防止对数据进行不正确的修改); 完整性级别 (而不是 MLS 的敏感度级别)。 下列 sysctl 可以用于维护 Biba 策略。 security.mac.biba.enabled 可以用来在机器上启用/禁用是否实施 Biba 策略。 security.mac.biba.ptys_equal 可以用来在 &man.pty.4; 设备上禁用 Biba 策略。 security.mac.biba.revocation_enabled 将在支配 subject 发生变化时强制撤销对对象的访问权。 要操作系统对象上的 Biba 策略, 需要使用 setfmacgetfmac 命令: &prompt.root; setfmac biba/low test &prompt.root; getfmac test test: biba/low 观察: 较低完整性级别的 subject 不能向较高完整性级别的 subject 写; 较高完整性级别的 subject 也不能观察或读取较低完整性级别的对象。 MAC LOMAC 模块 MAC LOMAC 模块名: mac_lomac.ko 对应的内核配置: options MAC_LOMAC 引导选项: mac_lomac_load="YES" MAC Biba 策略不同, &man.mac.lomac.4; 策略只允许在降低了完整性级别之后, 才允许在不破坏完整性规则的前提下访问较低完整性级别的对象。 MAC 版本的 Low-watermark 完整性策略不应与较早的 &man.lomac.4; 实现相混淆, 除了使用浮动的标签来支持 subject 通过辅助级别 compartment 降级之外, 其工作方式与 Biba 大体相似。 这一词要的 compartment 以 [auxgrade] 的形式出现。 当指定包含辅助级别的 lomac 策略时, 其形式应类似于: lomac/10[2] 这里数字二 (2) 就是辅助级别。 MAC LOMAC 策略依赖于系统对象上存在普适的标签, 这样就允许 subject 来从较低完整性级别的对象读取, 并对 subject 的标签降级, 以防止其在之后写高完整性级别的对象。 这就是前面讨论的 [auxgrade] 选项, 因此这个策略能够提供更大的兼容性, 而所需要的初始配置也要比 Biba 少。 例子 与 Biba 和 MLS 策略类似; setfmacsetpmac 工具可以用来在系统对象上放置标签: &prompt.root; setfmac /usr/home/trhodes lomac/high[low] &prompt.root; getfmac /usr/home/trhodes lomac/high[low] 注意, 这里的辅助级别是 low, 这一特性只由 MAC LOMAC 策略提供。 通过使用 MAC 来实现安全的环境 MAC 实现举例 下面给出了通过多种 MAC 模块, 并正确地配置策略来实现安全环境的例子。 这只是一个测试, 因此不应被看作四海一家的解决之道。 仅仅实现一个策略, 而忽略它不能解决任何问题, 并可能在生产环境中产生灾难性的后果。 在开始这些操作之前, 必须在每一个文件系统上设置 multilabel 选项, 这些操作在这一章开始的部分进行了介绍。 不完成这些操作, 将导致错误的结果。 创建一个 insecure (不安全) 用户 Class 首先是在 /etc/login.conf 文件中加入一个新的用户 class: insecure:\ :copyright=/etc/COPYRIGHT:\ :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: 并在 default 用户 class 中加入: :label=mls/equal,biba/equal,partition/15: 一旦完成上述操作, 就需要运行下面的命令来重建数据库: &prompt.root; cap_mkdb /etc/login.conf 配合正确的模块启动 /boot/loader.conf 中加入下面的配置, 以保证系统初始化过程中加载那些模块: mac_biba_load="YES" mac_mls_load="YES" mac_seeotheruids_load="YES" mac_partition_load="YES" 将所有用户设置为不安全的 所有非 root 或系统的用户, 现在需要一个登录 class。 登录 class 是必须的, 否则这些用户将被禁止使用类似 &man.vi.1; 这样的命令。 下面的 sh 脚本应能完成这个工作: &prompt.root; for x in `awk -F: '($3 >= 1001) && ($3 != 65534) { print $1 }' \ /etc/passwd`; do pw usermod $x -L insecure; done; 改完后, 需要在 /etc/master.passwd 上运行 cap_mkdb 命令。 完成配置 现在需要创建一个 contexts 文件; 下面的例子来自 Robert Watson 的策略示例, 应放到 /etc/policy.contexts 中。 # 这是系统中的默认 BIBA/MLS 策略。 .* biba/high,mls/high /sbin/dhclient biba/high(low),mls/high(low) /dev(/.*)? biba/equal,mls/equal # This is not an exhaustive list of all "privileged" devices. /dev/mdctl biba/high,mls/high /dev/pci biba/high,mls/high /dev/k?mem biba/high,mls/high /dev/io biba/high,mls/high /dev/agp.* biba/high,mls/high (/var)?/tmp(/.*)? biba/equal,mls/equal /tmp/\.X11-unix biba/high(equal),mls/high(equal) /tmp/\.X11-unix/.* biba/equal,mls/equal /proc(/.*)? biba/equal,mls/equal /mnt.* biba/low,mls/low (/usr)?/home biba/high(low),mls/high(low) (/usr)?/home/.* biba/low,mls/low /var/mail(/.*)? biba/low,mls/low /var/spool/mqueue(/.*)? biba/low,mls/low (/mnt)?/cdrom(/.*)? biba/high,mls/high (/usr)?/home/(ftp|samba)(/.*)? biba/high,mls/high /var/log/sendmail\.st biba/low,mls/low /var/run/utmp biba/equal,mls/equal /var/log/(lastlog|wtmp) biba/equal,mls/equal 这个策略将通过在信息的上下行流上, 根据左边列出的工具和目录实施限制来强制安全。 可以通过下面的命令将其读入我们的系统: &prompt.root; setfsmac -ef /etc/policy.contexts / &prompt.root; setfsmac -ef /etc/policy.contexts /usr 上述文件系统布局, 可能随环境而略有不同。 /etc/mac.conf 文件中的 main 小节需要进行下面的修改: default_labels file ?biba,?mls default_labels ifnet ?biba,?mls default_labels process ?biba,?mls,?partition default_labels socket ?biba,?mls 对配置进行测试 MAC 配置测试 使用 adduser 命令来增加用户, 并把这个用户放到 insecure class 中, 以用于测试。 下面的例子中混合了 root 和普通用户 tests 的测试结果, 并使用提示符来区别它们。 基本的标签测试 &prompt.user; getpmac biba/15(15-15),mls/15(15-15),partition/15 &prompt.root; setpmac partition/15,mls/equal top 在启动其他 top 进程之前应该首先杀掉我们的这个 top 进程。 MAC Seeotheruids 测试 &prompt.user; ps Zax biba/15(15-15),mls/15(15-15),partition/15 1096 #C: S 0:00.03 -su (bash) biba/15(15-15),mls/15(15-15),partition/15 1101 #C: R+ 0:00.01 ps Zax 我们应该看不到其他用户的进程。 MAC Partition 测试 为其他测试禁用 MAC seeotheruids 策略: &prompt.root; sysctl security.mac.seeotheruids.enabled=0 &prompt.user; ps Zax LABEL PID TT STAT TIME COMMAND biba/equal(low-high),mls/equal(low-high),partition/15 1122 #C: S+ 0:00.02 top biba/15(15-15),mls/15(15-15),partition/15 1096 #C: S 0:00.05 -su (bash) biba/15(15-15),mls/15(15-15),partition/15 1123 #C: R+ 0:00.01 ps Zax 现在所有的用户都应能够看到他们的 partition 中的所有进程了。 测试 Biba 和 MLS 标签 &prompt.root; setpmac partition/15,mls/equal,biba/high\(high-high\) top &prompt.user; ps Zax LABEL PID TT STAT TIME COMMAND biba/high(high-high),mls/equal(low-high),partition/15 1251 #C: S+ 0:00.02 top biba/15(15-15),mls/15(15-15),partition/15 1096 #C: S 0:00.06 -su (bash) biba/15(15-15),mls/15(15-15),partition/15 1157 #C: R+ 0:00.00 ps Zax Biba 策略允许我们读取标签为较高标签的对象。 &prompt.root; setpmac partition/15,mls/equal,biba/low top &prompt.user; ps Zax LABEL PID TT STAT TIME COMMAND biba/15(15-15),mls/15(15-15),partition/15 1096 #C: S 0:00.07 -su (bash) biba/15(15-15),mls/15(15-15),partition/15 1226 #C: R+ 0:00.01 ps Zax Biba 策略不允许读取低标签的对象; 但 MLS 允许此类操作。 &prompt.user; ifconfig bge0 | grep maclabel maclabel biba/low(low-low),mls/low(low-low) &prompt.user; ping -c 1 192.0.34.166 PING 192.0.34.166 (192.0.34.166): 56 data bytes ping: sendto: Permission denied 由于这个原因, 用户将无法 ping example.com 或其他主机。 要防止发生这类错误, 需要运行下面的命令: &prompt.root; sysctl security.mac.biba.trust_all_interfaces=1 这将把默认的接口标签置为不安全模式, 这样就不会强制使用 Biba 策略了。 &prompt.root; ifconfig bge0 maclabel biba/equal\(low-high\),mls/equal\(low-high\) &prompt.user; ping -c 1 192.0.34.166 PING 192.0.34.166 (192.0.34.166): 56 data bytes 64 bytes from 192.0.34.166: icmp_seq=0 ttl=50 time=204.455 ms --- 192.0.34.166 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/stddev = 204.455/204.455/204.455/0.000 ms 通过设置更为正确的标签, 我们就能够发出 ping 请求了。 现在建立几个文件来测试一下读写操作: &prompt.root; touch test1 test2 test3 test4 test5 &prompt.root; getfmac test1 test1: biba/equal,mls/equal &prompt.root; setfmac biba/low test1 test2; setfmac biba/high test4 test5; \ setfmac mls/low test1 test3; setfmac mls/high test2 test4 &prompt.root; setfmac mls/equal,biba/equal test3 && getfmac test? test1: biba/low,mls/low test2: biba/low,mls/high test3: biba/equal,mls/equal test4: biba/high,mls/high test5: biba/high,mls/equal &prompt.root; chown testuser:testuser test? 所有这些文件应属于 testuser 用户。 现在测试一下读操作: &prompt.user; ls test1 test2 test3 test4 test5 &prompt.user; ls test? ls: test1: Permission denied ls: test2: Permission denied ls: test4: Permission denied test3 test5 没有允许我们 observe pairs; 例如: (biba/low,mls/low)(biba/low,mls/high) 以及 (biba/high,mls/high)。 因此, 很显然读操作应该被拒绝。 现在测试一下写操作: &prompt.user; for i in `echo test*`; do echo 1 > $i; done -su: test1: Permission denied -su: test4: Permission denied -su: test5: Permission denied 和读操作的尝试类似, write pairs 不应允许这类操作; 例如: (biba/low,mls/high)(biba/equal,mls/equal) &prompt.user; cat test? cat: test1: Permission denied cat: test2: Permission denied 1 cat: test4: Permission denied 现在以 root 身份进行: &prompt.root; cat test2 1 另一个例子: 使用 MAC 来约束 Web 服务器 将配置一个独立的位置来保存 web 数据, 并只允许特定的用户来访问。 这样, 拥有 biba/high 的进程就能够访问 web 数据了。 首先需要创建一个用于保存 web 数据的目录: &prompt.root; mkdir /usr/home/cvs 接下来使用 cvs 来对其进行初始化: &prompt.root; cvs -d /usr/home/cvs init 第一件事是启用 biba 策略, 因此应把 mac_biba_enable="YES" 加入到 /boot/loader.conf。 当然, 这样做的前提是在内核中启用了 MAC 支持。 从现在开始, 整个系统中的所有对象, 都会默认设置为 biba/high 必须在 login.conf 中的 default (默认) 用户 class 上进行下列修改: :ignoretime@:\ :umask=022:\ :label=biba/high: 现在每个用户都需要放到 default class 中; 类似下面的命令: &prompt.root; for x in `awk -F: '($3 >= 1001) && ($3 != 65534) { print $1 }' \ /etc/passwd`; do pw usermod $x -L default; done; 可以很快地完成这个工作。 接下来建立另一个 class, web, 它是 default 的一个副本, 但将标签设置为 biba/low 建立一个用于在 cvs 中的主 web 库的数据上工作的用户。 这个用户必须被放到我们新建立的那个登录 class, web 中。 由于所有地方的默认值都是 biba/high, 因此库也是一样的。 web 数据必须同样地被用户读写; 然而, 由于我们的 web 服务器将要提供 biba/high 用户需要访问的数据, 因此必须将所有这些数据降级。 完成这些事情的最好工具是 &man.sh.1; 和 &man.cron.8;, 它们已经由 &os; 提供了。 下面的脚本将完成全部所需的工作: PATH=/bin:/usr/bin:/usr/local/bin; export PATH; CVSROOT=/home/repo; export CVSROOT; cd /home/web; cvs -qR checkout -P htdocs; exit; 很多时候, cvs Id tag 必须放到 web 站点的数据文件中。 现在可以把这个脚本放到 web 的主目录中, 并增加下面的 &man.crontab.1; 项: # Check out the web data as biba/low every twelve hours: 0 */12 * * * web /home/web/checkout.sh 这样, 这台机器上每十二小时都会检出一次 HTML 源代码。 Web 服务器的默认启动方式也必须进行修改, 以便以 biba/low 来启动服务。 这可以通过对 /usr/local/etc/rc.d/apache.sh 脚本进行下面的修改来完成: command="setpmac biba/low /usr/local/sbin/httpd" Apache 配置必须进行修改, 以便在 biba/low 策略下工作。 因为这时软件必须配置为在设置了 biba/low 的目录中记录日志, 否则将返回 access denied 错误。 完全按照上面的例子进行配置的话, docroot 应被设置为 /home/web/htdocs; 否则, Apache 将无法查找其提供文档的目录。 同时, 也需要修改一些其他的配置变量, 包括 PID 文件, ScoreboardfileDocumentRoot、 日志文件的位置, 以及其他需要写权限的配置。 使用 biba 时, 所有发生在 没有 配置为 biba/low 的写操作都会失败。 MAC 框架的故障排除 MAC 故障排除 在开发过程中, 有一些用户报告了正常配置下出现的问题。 其中的一些问题如下所示: 无法在 <filename>/</filename> 上启用 <option>multilabel</option> 选项 标志在根 (/) 分区上没有保持启用状态! 看起来每五十个用户中就有一个遇到这样的问题, 当然, 在我们的初始配置过程中也出现过这样的问题。 更进一步的观察使得我相信这个所谓的 bug 是由于文档中不确切的描述, 或对其产生的误解造成的。 无论它是因为什么引发的, 下面的步骤应该能够解决此问题: 编辑 /etc/fstab 并将根分区设置为 , 表示只读。 重新启动并进入单用户模式。 / 上运行 tunefs 重新启动并进入正常的模式。 运行 mount / 并把 /etc/fstab 中的 改回 , 然后再次重新启动。 再次检查来自 mount 的输出, 已确认根文件系统上正确地设置了 在 <acronym>MAC</acronym> 之后无法启动 X11 了 在使用 MAC 建立安全的环境之后, 就无法启动 X 了! 这可能是由于 MAC partition 策略, 或者对某个 MAC 标签策略进行了错误的配置导致的。 要调试这个问题, 请尝试: 检查错误信息; 如果用户是在 insecure class 中, 则 partition 策略就可能导致问题。 尝试将用户的 class 重新改为 default class, 并使用 cap_mkdb 命令重建数据库。 如果这无法解决问题, 则进入第二步。 仔细检查标签策略。 确认针对有问题的用户的策略是正确的, 特别是 X11 应用, 以及 /dev 项。 如果这些都无法解决问题, 将出错消息和对您的环境的描述, 发送到 TrustedBSD 网站上的 TrustedBSD 讨论邮件列表, 或者 &a.questions; 邮件列表。 Error: &man..secure.path.3; cannot stat <filename>.login_conf</filename> 当我试图从 root 切换到其同中的其他用户时, 出现了错误提示 _secure_path: unable to state .login_conf 这个提示通常在用户拥有高于它将要成为的那个用户的 标签设定时出现。 例如, 如果系统上的一个用户 joe 拥有默认的 标签, 而 root 用户拥有 , 它也就不能查看 joe 的主目录, 无论 root 是否使用了 su 来成为 joe。 这种情况下, Biba 完整性模型, 就不会允许 root 查看在较低完整性级别中的对象。 <username>root</username> 用户名被破坏了! 在普通模式, 甚至是单用户模式中, root 不被识别。 whoami 命令返回了 0 (零) 而 su 则提示 who are you?。 到底发生了什么? 标签策略被禁用可能会导致这样的问题, 无论是通过 &man.sysctl.8; 或是卸载了策略模块。 如果打算禁用策略, 或者临时禁用它, 则登录性能数据库需要重新配置, 在其中删除 选项。 仔细检查 login.conf 以确保所有的 选项都已经删除, 然后使用 cap_mkdb 命令来重建数据库。