> For the complete documentation index, see [llms.txt](https://man.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://man.bsdcn.org/man7/security.7.md).

# security(7)

`security` — FreeBSD 安全简介

## 名称

`security`, `securelevel`

## 描述

关于 FreeBSD 中漏洞缓解措施的描述，请参见 [mitigations(7)](/man7/mitigations.7.md)。本手册页记录 FreeBSD 其他的安全相关主题。

安全是一项始于系统管理员并终于系统管理员的工作。虽然所有 BSD 多用户系统都具有一些固有的安全性，但构建和维护额外的安全机制以保持用户“规矩”可能是系统管理员最大的单项工作之一。机器的安全性取决于你的设置，安全问题始终与人类对便利性的需求相竞争。UNIX 系统通常能够运行大量同时存在的进程，其中许多进程作为服务器运行——这意味着外部实体可以连接并与它们通信。随着昨天的迷你计算机和大型机变成今天的台式机，随着计算机被网络化和互联，安全成为越来越大的问题。

安全最好通过分层的洋葱方法来实现。简而言之，你要做的是创建尽可能多的便利安全层，然后仔细监控系统以发现入侵。

系统安全还涉及处理各种形式的攻击，包括试图使系统崩溃或不可用但不试图获取 root 权限的攻击。安全问题可以分为以下几类：

* 拒绝服务攻击（DoS）
* 用户账户入侵
* 通过可访问的服务器进行的 root 入侵
* 通过用户账户进行的 root 入侵
* 后门创建

拒绝服务攻击是一种剥夺机器所需资源的行动。通常，DoS 攻击是暴力机制，试图通过使服务器或网络栈不堪重负来使机器崩溃或不可用。一些 DoS 攻击试图利用网络栈中的 bug 用单个数据包使机器崩溃。后者只能通过向内核应用 bug 修复来解决。对服务器的攻击通常可以通过正确指定选项来限制服务器在不利条件下对系统造成的负载。暴力网络攻击更难处理。例如，欺骗数据包攻击几乎无法阻止，除非将你的系统与互联网切断。它可能无法使你的机器瘫痪，但可以填满你的互联网管道。

用户账户入侵比 DoS 攻击更为常见。一些系统管理员仍在他们的机器上运行 `telnetd` 和 [ftpd(8)](/man8/ftpd.8.md) 服务器。这些服务器默认不通过加密连接操作。结果是，如果你有任何中等规模的用户群，从远程位置登录到你的系统（这是登录系统最常见和最方便的方式）的一个或多个用户将使其密码被嗅探。细心的系统管理员会分析远程访问日志，即使对于成功的登录，也会寻找可疑的源地址。

必须始终假设，一旦攻击者获得了用户账户的访问权限，攻击者就能获取 root 权限。然而，实际情况是，在一个安全良好且维护良好的系统中，对用户账户的访问并不一定使攻击者获得 root 访问权限。这一区别很重要，因为如果没有 root 访问权限，攻击者通常无法掩盖其踪迹，最多只能搞乱用户的文件或使机器崩溃。用户账户入侵非常常见，因为用户往往不采取系统管理员所采取的预防措施。

系统管理员必须记住，破坏机器上的 root 可能有多种方式。攻击者可能知道 root 密码，攻击者可能在以 root 运行的服务器中找到 bug 并能够通过网络连接到该服务器获取 root，或者攻击者可能知道 SUID-root 程序中的 bug，使其在入侵用户账户后能够获取 root。如果攻击者找到了破坏机器上 root 的方法，攻击者可能不需要安装后门。迄今为止发现和关闭的许多 root 漏洞都涉及攻击者大量的清理工作，因此大多数攻击者会安装后门。这为你提供了检测攻击者的便捷方式。使攻击者无法安装后门实际上可能对你的安全不利，因为它不会关闭攻击者最初用来入侵的漏洞。

安全补救措施应始终以多层的“洋葱皮”方法实现，可分类如下：

* 保护 root 和员工账户
* 保护 root——以 root 运行的服务器和 SUID/SGID 二进制文件
* 保护用户账户
* 保护密码文件
* 保护内核核心、原始设备和文件系统
* 快速检测对系统的不当更改
* 偏执

## 保护 root 账户和员工账户

如果你没有保护 root 账户，就不必费心保护员工账户。大多数系统为 root 账户分配了密码。你要做的第一件事是假设密码*总是*被泄露。这并不意味着你应该删除密码。对于控制台访问机器，密码几乎总是必需的。它的意思是，你不应该让密码能够在控制台之外使用，甚至可能不能与 [su(1)](/man1/su.1.md) 工具一起使用。例如，确保你的 PTY 在 **/etc/ttys** 文件中被指定为“`insecure`”，以便通过 [telnet(1)](/man1/telnet.1.md) 的直接 root 登录被禁止。如果使用其他登录服务如 sshd(8)，请确保在那里也禁用直接 root 登录。考虑每种访问方法——[ftp(1)](/man1/ftp.1.md) 等服务经常被忽略。仅应通过系统控制台允许直接 root 登录。

当然，作为系统管理员，你必须能够获取 root 权限，所以我们打开了几个漏洞。但我们确保这些漏洞需要额外的密码验证才能操作。使 root 可访问的一种方法是将适当的员工账户添加到“`wheel`”组（在 **/etc/group** 中）。放置在 `wheel` 组中的员工成员被允许 [su(1)](/man1/su.1.md) 到 root。你不应该通过将员工成员放在其密码条目的 `wheel` 组中来给予他们原生 `wheel` 访问权限。员工账户应放在“`staff`”组中，然后通过 **/etc/group** 文件添加到 `wheel` 组。只有那些确实需要 root 访问权限的员工成员才应放在 `wheel` 组中。当使用诸如 Kerberos 之类的身份验证方法时，也可以在 root 账户中使用 Kerberos 的 `.k5login` 文件来允许 ksu(1) 到 root，而无需将任何人放在 `wheel` 组中。这可能是更好的解决方案，因为 `wheel` 机制仍然允许入侵者在获得你的密码文件并能够入侵员工账户时获取 root。虽然拥有 `wheel` 机制比什么都没有好，但它不一定是安全的选择。

保护 root 账户的一种间接方法是通过使用替代登录访问方法来保护你的员工账户，并 *-out 员工账户的加密密码。这样，入侵者可能能够窃取密码文件，但无法入侵任何员工账户或 root，即使 root 关联了加密密码（当然，假设你已将 root 访问限制在控制台）。员工成员通过安全登录机制（如 kerberos(8) 或* [*ssh(1)*](/man1/ssh.1.md)*）使用私钥/公钥对进入其员工账户。当你使用 Kerberos 之类的方法时，通常必须保护运行 Kerberos 服务器的机器和你的桌面工作站。当你使用 SSH 的公/私钥对时，通常必须保护你*从\*其登录的机器（通常是你的工作站），但你也可以通过在用 [ssh-keygen(1)](/man1/ssh-keygen.1.md) 创建密钥对时用密码保护密钥对来为密钥对添加额外的保护层。能够 star-out 员工账户的密码也保证员工成员只能通过你设置的安全访问方法登录。因此，你可以强制所有员工成员为其所有会话使用安全、加密的连接，这关闭了许多入侵者使用的一个重要漏洞：即从无关的、安全性较低的机器上嗅探网络。

更间接的安全机制还假设你从限制更严格的服务器登录到限制较少的服务器。例如，如果你的主机器运行各种服务器，你的工作站不应运行任何服务器。为了使你的工作站合理安全，你应该运行尽可能少的服务器，甚至完全不运行服务器，并应运行密码保护的屏幕保护程序。当然，如果攻击者有工作站的物理访问权限，攻击者可以破坏你在其上设置的任何安全。这绝对是你应该考虑的问题，但你也应该考虑到，绝大多数入侵都是远程的、通过网络进行的，由没有你工作站或服务器物理访问权限的人发起。

使用 Kerberos 之类的方法还使你能够在一个地方禁用或更改员工账户的密码，并使其立即影响员工成员可能有账户的所有机器。如果员工成员的账户被入侵，能够在所有机器上立即更改其密码的能力不应被低估。使用离散密码，在 N 台机器上更改密码可能是一团糟。你还可以使用 Kerberos 施加重设密码限制：不仅 Kerberos 票据可以设置为在一段时间后超时，而且 Kerberos 系统可以要求用户在一定时间后选择新密码（例如，每月一次）。

## 保护 root——以 root 运行的服务器和 SUID/SGID 二进制文件

谨慎的系统管理员只运行他需要的服务器，不多不少。请注意，第三方服务器通常最容易出 bug。例如，运行旧版本的 imapd(8) 或 popper(8)（`ports/mail/popper`）就像向全世界发放通用 root 票据。切勿运行你未仔细检查的服务器。许多服务器不需要以 root 运行。例如，talkd(8)、comsat(8) 和 fingerd(8) 守护进程可以在特殊用户“沙箱”中运行。除非你费很大力气，否则沙箱并不完美，但洋葱安全方法仍然成立：如果有人能够通过沙箱中运行的服务器入侵，他们仍然必须突破沙箱。攻击者必须突破的层越多，其成功的可能性越低。历史上，几乎所有以 root 运行的服务器中都发现过 root 漏洞，包括基本系统服务器。如果你运行的机器上人们只通过 sshd(8) 登录而从不通过 `telnetd` 登录，那么关闭此服务！

FreeBSD 现在默认在沙箱中运行 talkd(8)、comsat(8) 和 fingerd(8)。根据你是安装新系统还是升级现有系统，这些沙箱使用的特殊用户账户可能未安装。谨慎的系统管理员会在可能的情况下研究并为服务器实现沙箱。

有许多其他服务器通常不在沙箱中运行：sendmail(8)、popper(8)、imapd(8) 等。其中一些有替代方案，但安装它们可能需要比你愿意付出的更多工作（便利因素再次作祟）。你可能必须以 root 运行这些服务器，并依赖其他机制来检测可能通过它们发生的入侵。

系统中另一个潜在的 root 大漏洞是系统上安装的 SUID-root 和 SGID 二进制文件。这些二进制文件大多位于 **/bin**、**/sbin**、**/usr/bin** 或 **/usr/sbin** 中。虽然没有任何东西是 100% 安全的，但系统默认的 SUID 和 SGID 二进制文件可以被认为是相当安全的。尽管如此，这些二进制文件中偶尔仍会发现 root 漏洞。1998 年在 Xlib 中发现了一个 root 漏洞，使 xterm(1)（`ports/x11/xterm`）（通常是 SUID）容易受到攻击。宁可安全不要后悔，谨慎的系统管理员会将只有员工才能运行的 SUID 二进制文件限制为只有员工才能访问的特殊组，并删除（“`chmod 000`”）任何没人使用的 SUID 二进制文件。没有显示器的服务器通常不需要 xterm(1)（`ports/x11/xterm`）二进制文件。SGID 二进制文件几乎同样危险。如果入侵者能够破坏 SGID-kmem 二进制文件，入侵者可能能够读取 **/dev/kmem**，从而读取加密密码文件，可能危及任何有密码的账户。或者，破坏“`kmem`”组的入侵者可以监控通过 PTY 发送的击键，包括用户通过安全方法登录使用的 PTY。破坏“`tty`”组的入侵者可以写入几乎任何用户的 TTY。如果用户正在运行具有键盘模拟功能的终端程序或模拟器，入侵者可能生成导致用户终端回显命令的数据流，然后以该用户身份运行。

## 保护用户账户

用户账户通常最难保护。虽然你可以对员工施加严厉的访问限制并 \*-out 他们的密码，但你可能无法对任何可能有的普通用户账户这样做。如果你确实有足够的控制权，你可能胜出并能够正确保护用户账户。如果不能，你只需更加警惕地监控这些账户。由于需要额外的管理和技术支持，对用户账户使用 SSH 和 Kerberos 更成问题，但与加密密码文件相比，仍然是一个非常好的解决方案。

## 保护密码文件

唯一可靠的方法是 \*-out 尽可能多的密码，并使用 SSH 或 Kerberos 访问这些账户。即使加密密码文件（**/etc/spwd.db**）只能由 root 读取，入侵者也可能获得对该文件的读取访问权限，即使攻击者无法获得 root 写访问权限。

你的安全脚本应始终检查并报告密码文件的更改（参见下文“检查文件完整性”章节）。

## 保护内核核心、原始设备和文件系统

如果攻击者破坏了 root，他几乎可以做任何事情，但有一些便利之处。例如，大多数现代内核都内置了数据包嗅探设备驱动程序。在 FreeBSD 中，它被称为 [bpf(4)](/man4/bpf.4.md) 设备。入侵者通常会尝试在被入侵的机器上运行数据包嗅探器。你不需要给入侵者这种能力，大多数系统不应编译 [bpf(4)](/man4/bpf.4.md) 设备。

但即使你关闭了 [bpf(4)](/man4/bpf.4.md) 设备，你仍然需要担心 **/dev/mem** 和 **/dev/kmem**。就此而言，入侵者仍然可以写入原始磁盘设备。此外，还有另一个名为模块加载器 [kldload(8)](/man8/kldload.8.md) 的内核功能。有进取心的入侵者可以使用 KLD 模块在运行中的内核上安装自己的 [bpf(4)](/man4/bpf.4.md) 设备或其他嗅探设备。为避免这些问题，你必须在更高的安全级别（至少级别 1）运行内核。可以使用 [sysctl(8)](/man8/sysctl.8.md) 对 `kern.securelevel` 变量设置安全级别。一旦将安全级别设置为 1，对原始设备的写访问将被拒绝，并且将强制执行特殊的 chflags(1) 标志（如 `schg`）。你还必须确保在关键启动二进制文件、目录和脚本文件上设置 `schg` 标志——直到安全级别设置之前的所有内容。这可能做得过头了，并且在更高安全级别下操作时升级系统要困难得多。你可以折衷，在更高安全级别下运行系统，但不为系统下的每个文件和目录设置 `schg` 标志。另一种可能性是简单地以只读方式挂载 **/** 和 **/usr**。应注意，在你试图保护的内容上过于严苛可能会阻碍对入侵的至关重要的检测。

内核以五种不同的安全级别运行。任何超级用户进程都可以提高级别，但没有进程可以降低它。安全级别如下：

**`-1`** 永久不安全模式——始终以不安全模式运行系统。这是默认初始值。

**`0`** 不安全模式——不可变和仅追加标志可以关闭。所有设备都可以根据其权限进行读取或写入。

**`1`** 安全模式——系统不可变和系统仅追加标志不能关闭；已挂载文件系统的磁盘、**/dev/mem** 和 **/dev/kmem** 不能以写入方式打开；**/dev/io**（如果你的平台有）根本不能打开；内核模块（参见 [kld(4)](/man4/kld.4.md)）不能加载或卸载。除非 [mac(9)](/man9/mac.9.md) 策略授予访问权限（例如使用 [mac\_ddb(4)](/man4/mac_ddb.4.md)），否则不能使用 `debug.kdb.enter` sysctl 进入内核调试器。不能使用 `debug.kdb.panic`、`debug.kdb.panic_str` 和其他 sysctl 强制触发 panic 或陷阱。

**`2`** 高度安全模式——与安全模式相同，加上磁盘不能以写入方式打开（mount(2) 除外），无论是否已挂载。此级别防止通过卸载文件系统来篡改文件系统，但也禁止在系统多用户时运行 newfs(8)。此外，内核时间更改限制为小于或等于一秒。尝试更改时间超过此值将记录消息“Time adjustment clamped to +1 second”。

**`3`** 网络安全模式——与高度安全模式相同，加上 IP 数据包过滤规则（参见 [ipfw(8)](/man8/ipfw.8.md)、[ipfirewall(4)](/man4/ipfirewall.4.md) 和 pfctl(8)）不能更改，[dummynet(4)](/man4/dummynet.4.md) 或 [pf(4)](/man4/pf.4.md) 配置不能调整。

可以使用 [rc.conf(5)](/man5/rc.conf.5.md) 中记录的变量配置安全级别。

## 检查文件完整性：二进制文件、配置文件等

归根结底，你的核心系统配置和控制文件只能在便利因素暴露之前进行一定程度的保护。例如，使用 chflags(1) 在 **/** 和 **/usr** 中的大多数文件上设置 `schg` 位可能适得其反，因为虽然它可以保护文件，但也关闭了检测窗口。你的安全洋葱的最后一层也许是最重要的——检测。如果你无法检测到潜在的入侵，你的其余安全措施几乎毫无用处（或者更糟，给你一种虚假的安全感）。洋葱工作的一半是减缓攻击者而不是阻止他，以便给检测层机会在现场抓住他。

检测入侵的最佳方法是查找已修改、缺失或意外的文件。查找已修改文件的最佳方法是从另一台（通常是集中式的）受限访问系统上。在额外安全的受限访问系统上编写安全脚本使其对潜在攻击者几乎不可见，这很重要。为了充分利用，你通常必须给受限访问机器对业务中其他机器的重要访问权限，通常通过对其他机器进行只读 NFS 导出到受限访问机器，或者设置 SSH 密钥对以允许受限访问机器 SSH 到其他机器。除了网络流量外，NFS 是最不可见的方法——允许你几乎不被察觉地监控每个客户端机器上的文件系统。如果你的受限访问服务器通过交换机连接到客户端机器，NFS 方法通常是更好的选择。如果你的受限访问服务器通过集线器或多层路由连接到客户端机器，NFS 方法可能太不安全（网络方面），使用 SSH 可能是更好的选择，即使 SSH 会留下审计跟踪痕迹。

一旦你给予受限访问机器至少对其应监控的客户端系统的读取访问权限，你必须编写脚本来执行实际监控。给定 NFS 挂载，你可以使用 [find(1)](/man1/find.1.md) 和 [md5(1)](/man1/md5.1.md) 等简单系统实用程序编写脚本。最好每天至少对客户端机器文件进行一次物理 [md5(1)](/man1/md5.1.md) 校验，并且对控制文件（如 **/etc** 和 **/usr/local/etc** 中的文件）进行更频繁的测试。当发现与受限访问机器已知有效的基线 MD5 信息不匹配时，它应该向系统管理员发出警报以进行检查。好的安全脚本还会检查不当的 SUID 二进制文件以及系统分区（如 **/** 和 **/usr**）上新增或删除的文件。

使用 SSH 而不是 NFS 时，编写安全脚本要困难得多。你实际上必须 [scp(1)](/man1/scp.1.md) 脚本到客户端机器才能运行它们，使其可见，并且为了安全，你还需要 [scp(1)](/man1/scp.1.md) 这些脚本使用的二进制文件（如 [find(1)](/man1/find.1.md)）。客户端机器上的 sshd(8) 守护进程可能已被入侵。总之，在不安全链路上运行时可能需要使用 SSH，但处理起来也困难得多。

好的安全脚本还应检查用户和员工访问配置文件的更改：`.rhosts , .shosts , .ssh/authorized_keys` 等，这些文件可能不在 MD5 检查的范围内。

如果你有大量用户磁盘空间，遍历这些分区上的每个文件可能花费太长时间。在这种情况下，设置挂载标志以禁止这些分区上的 SUID 二进制文件是个好主意。`nosuid` 选项（参见 [mount(8)](/man8/mount.8.md)）就是你要寻找的。我仍然会每周至少扫描一次，因为这一层的目的是检测入侵，无论入侵是否有效。

进程 accounting（参见 accton(8)）是操作系统中开销相对较低的功能，我建议将其用作入侵后评估机制。它对于追踪入侵者实际如何入侵系统特别有用，前提是入侵发生后文件仍然完整。

最后，安全脚本应处理日志文件，日志本身应尽可能以安全的方式生成——远程 syslog 非常有用。入侵者试图掩盖其踪迹，而日志文件对于试图追踪最初入侵的时间和方法的管理员至关重要。保留日志文件永久记录的一种方法是将系统控制台运行到串口，并通过监控控制台的安全机器持续收集信息。

## 偏执

一点偏执从无坏处。作为规则，系统管理员可以添加任意数量的安全功能，只要它们不影响便利性，并且可以通过一些额外的思考添加确实影响便利性的安全功能。更重要的是，安全管理员应该混合使用——如果你逐字使用本手册页给出的建议，你就会向同样可以访问本手册页的潜在攻击者透露你的方法。

## 拒绝服务攻击专题

本节涵盖拒绝服务攻击。DoS 攻击通常是数据包攻击。虽然对于使你的网络饱和的现代欺骗数据包攻击你无能为力，但通常可以通过确保攻击不能使你的服务器瘫痪来限制损害。

* 限制服务器派生
* 限制反弹攻击（ICMP 响应攻击、ping 广播等）
* 内核路由缓存

常见的 DoS 攻击针对派生服务器，试图使服务器吞噬进程、文件描述符和内存直到机器死亡。[inetd(8)](/man8/inetd.8.md) 服务器有几个选项可以限制此类攻击。应注意，虽然可以防止机器宕机，但通常无法防止服务被攻击中断。仔细阅读 [inetd(8)](/man8/inetd.8.md) 手册页，特别关注 `-c -, -C` 和 `-` 选项。请注意，欺骗 IP 攻击将绕过 [inetd(8)](/man8/inetd.8.md) 的 `-C` 选项，因此通常必须使用选项组合。一些独立服务器具有自派生限制参数。

sendmail(8) 守护进程有 `-OMaxDaemonChildren` 选项，由于负载延迟，该选项往往比尝试使用 sendmail(8) 的负载限制选项效果更好。你应该在启动 sendmail(8) 时指定足够高的 `MaxDaemonChildren` 参数以处理预期负载，但不要高到计算机无法处理该数量的 `sendmail` 而崩溃。谨慎的做法是以“queued”模式（`-ODeliveryMode=queued`）运行 sendmail(8)，并将守护进程（“`sendmail` `-bd`”）与队列运行（“`sendmail` `-q15m`”）分开运行。如果你仍然想要实时投递，可以以更短的间隔运行队列，如 `-q1m`，但务必为该 sendmail(8) 指定合理的 `MaxDaemonChildren` 选项以防止级联故障。

syslogd(8) 守护进程可能被直接攻击，强烈建议只要可能就使用 `-s` 选项，否则使用 `-a` 选项。

你还应该相当小心 connect-back 服务，如 tcpwrapper 的 reverse-identd，它可能被直接攻击。由于这个原因，你通常不想使用 tcpwrappers 的 reverse-ident 功能。

通过在边界路由器上防火墙隔离内部服务以防止外部访问是个好主意。这里的想法是防止来自 LAN 外部的饱和攻击，而不是保护内部服务免受基于网络的 root 入侵。始终配置排他性防火墙，即“防火墙一切，*除了*端口 A、B、C、D 和 M-Z”。这样你可以防火墙关闭所有低端口，除了某些特定服务如 talkd(8)、sendmail(8) 和其他可互联网访问的服务。如果你尝试以另一种方式配置防火墙——作为包容性或宽松防火墙，你很有可能忘记“关闭”几个服务或添加新的内部服务而忘记更新防火墙。你仍然可以打开防火墙上的高端口范围以允许类似宽松的操作，而不损害你的低端口。还请注意，FreeBSD 允许你通过各种 `net.inet.ip.portrange` sysctl（“`sysctl net.inet.ip.portrange`”）控制用于动态绑定的端口号范围，这也可以简化防火墙配置的复杂性。我通常使用 4000 到 5000 的正常第一个/最后一个范围，以及 49152 到 65535 的 hiport 范围，然后在防火墙中阻止 4000 以下的所有端口（当然，除了某些特定的可互联网访问端口）。

另一种常见的 DoS 攻击称为反弹攻击——以使服务器生成响应的方式攻击服务器，然后使服务器、本地网络或其他机器过载。这种攻击最常见的是 ICMP PING BROADCAST 攻击。攻击者欺骗发送到你的 LAN 广播地址的 ping 数据包，源 IP 地址设置为他们想要攻击的实际机器。如果你的边界路由器未配置为阻止对广播地址的 ping，你的 LAN 最终会向欺骗源地址生成足够的响应以使受害者饱和，特别是当攻击者同时在数十个不同网络上的数十个广播地址上使用相同的伎俩时。已测量到超过 120 兆比特的广播攻击。第二种常见的反弹攻击针对 ICMP 错误报告系统。通过构造生成 ICMP 错误响应的数据包，攻击者可以饱和服务器的传入网络，并使服务器用 ICMP 响应饱和其传出网络。这种类型的攻击还可能通过耗尽服务器的 `mbuf` 而使服务器崩溃，特别是当服务器无法足够快地排空其生成的 ICMP 响应时。FreeBSD 内核有一个名为 `ICMP_BANDLIM` 的新内核编译选项，可限制这些类型攻击的有效性。最后一类主要的反弹攻击与某些内部 [inetd(8)](/man8/inetd.8.md) 服务（如 UDP echo 服务）相关。攻击者只需欺骗一个 UDP 数据包，源地址为服务器 A 的 echo 端口，目标地址为服务器 B 的 echo 端口，其中服务器 A 和 B 都在你的 LAN 上。然后两台服务器在彼此之间来回弹射这一个数据包。攻击者只需以这种方式注入几个数据包就可以使两台服务器及其 LAN 过载。内部 chargen 端口存在类似问题。称职的系统管理员会关闭所有这些 [inetd(8)](/man8/inetd.8.md) 内部测试服务。

## Kerberos 和 SSH 的访问问题

如果你打算使用 Kerberos 和 SSH，需要解决一些问题。Kerberos5 是一个出色的身份验证协议，但 kerberized [telnet(1)](/man1/telnet.1.md) 糟糕透顶。存在一些 bug 使它们不适合处理二进制流。此外，默认情况下 Kerberos 不加密会话，除非你使用 `-x` 选项。SSH 默认加密所有内容。

SSH 在各方面都运行良好，除非设置为转发加密密钥。这意味着如果你有一台安全工作站持有让你访问系统其余部分的密钥，而你 [ssh(1)](/man1/ssh.1.md) 到一台不安全的机器，你的密钥将暴露。实际密钥本身不会暴露，但 [ssh(1)](/man1/ssh.1.md) 会在你登录期间安装一个转发端口，如果攻击者已经在不安全的机器上获得了 root，他可以利用该端口使用你的密钥来访问你的密钥解锁的任何其他机器。

我们建议你尽可能将 SSH 与 Kerberos 结合用于员工登录。SSH 可以用 Kerberos 支持编译。这减少了你对可能暴露的 SSH 密钥的依赖，同时通过 Kerberos 保护密码。SSH 密钥只应用于从安全机器执行的自动任务（Kerberos 不适合的任务）。我们还建议你要么在 SSH 配置中关闭密钥转发，要么使用 SSH 在其 `authorized_keys` 文件中允许的 `from`=`IP/DOMAIN` 选项，使密钥仅对从特定机器登录的实体可用。

## 旋钮和调整

FreeBSD 提供了几个旋钮和调整手柄，使某些内省信息访问更加受限。有些人认为这提高了系统安全性，因此这里简要列出了这些旋钮，以及启用某些硬件状态泄漏缓解的控制。

下面描述的硬件缓解 sysctl 旋钮已移至 `machdep.mitigations` 下，带有向后兼容垫片以接受现有名称。未来的更改将合理化各个 sysctl 的含义（使 enabled/true 始终指示缓解处于活动状态）。因此，以前的名称仍然是设置缓解的规范方式，并在此处记录。不会为 `machdep.mitigations` 下的临时 sysctl 添加向后兼容垫片。

**`security.bsd.see_other_uids`** 控制不同 uid 拥有的主体（如进程）和对象（如套接字）的可见性和可达性。该旋钮直接影响 `kern.proc` sysctl 的数据过滤，从而限制 [ps(1)](/man1/ps.1.md) 等实用程序的输出。

**`security.bsd.see_other_gids`** 同上，针对不同 gid 拥有的主体和对象。

**`security.bsd.see_jail_proc`** 同上，针对属于不同 jail（包括子 jail）的主体和对象。

**`security.bsd.conservative_signals`** 启用时，非特权用户只能向执行已更改 uid 程序的进程发送作业控制和通常的终止信号，如 `SIGKILL`、`SIGINT` 和 `SIGTERM`。

**`security.bsd.unprivileged_kenv_read`** 控制 non-root 用户对内核环境变量的可用性。

**`security.bsd.unprivileged_proc_debug`** 控制 non-root 用户对进程调试设施的可用性。另请参见 proccontrol(1) 模式 `trace`。

**`vm.pmap.pti`** 可调参数，仅限 amd64。启用虚拟内存系统的一种操作模式，其中用户模式页表经过清理，以防止在某些 Intel CPU 上发生所谓的 Meltdown 信息泄漏。默认情况下，系统检测 CPU 是否需要变通方案，并自动启用。另请参见 proccontrol(1) 模式 `kpti`。

**`machdep.mitigations.flush_rsb_ctxsw`** amd64。控制上下文切换时的返回栈缓冲区刷新，以防止跨进程 ret2spec 攻击。仅在机器支持 SMEP 时需要并默认启用，否则 IBRS 会在内核进入时执行必要的刷新。

**`hw.mds_disable`** amd64 和 i386。控制微架构数据采样硬件信息泄漏缓解。

**`hw.spec_store_bypass_disable`** amd64 和 i386。控制推测存储绕过硬件信息泄漏缓解。

**`hw.ibrs_disable`** amd64 和 i386。控制间接分支受限推测硬件信息泄漏缓解。

**`machdep.syscall_ret_flush_l1d`** amd64。控制从报告 `EEXIST`、`EAGAIN`、`EXDEV`、`ENOENT`、`ENOTCONN` 和 `EINPROGRESS` 以外错误的系统调用返回时强制刷新 L1D 缓存。这主要是一个偏执设置，用于防止未知硬件问题的未知 gadget 被假设性利用。错误代码排除列表由正常系统操作中通常发生的最常见错误组成。

**`machdep.nmi_flush_l1d_sw`** amd64。控制 NMI 时强制刷新 L1D 缓存；这为 bhyve 缓解 L1 终端故障硬件信息泄漏提供软件辅助。

**`hw.vmm.vmx.l1d_flush`** amd64。控制 bhyve 虚拟机管理程序中 L1 终端故障的缓解。

**`vm.pmap.allow_2m_x_ept`** amd64。允许在 Intel CPU 上虚拟机管理程序用于将客户机物理地址空间映射到机器物理内存的 EPT 页表格式下，对可执行映射使用超级页。可以禁用以解决称为“页面大小更改时的机器检查错误避免”的 CPU 勘误。

**`machdep.mitigations.rngds.enable`** amd64 和 i386。控制特殊寄存器缓冲区数据采样的缓解与 MCU 访问优化之间的权衡。设置为零时，缓解被禁用，RDSEED 和 RDRAND 指令不会为共享缓冲区访问产生序列化开销，也不会序列化核外内存访问。

**`kern.elf32.aslr.enable`** 控制普通非 PIE（位置无关可执行文件）32 位 ELF 二进制文件的系统全局地址空间布局随机化（ASLR）。另请参见 proccontrol(1) `aslr` 模式，也受每映像控制注释标志的影响。

**`kern.elf32.aslr.pie_enable`** 控制位置无关（PIE）32 位二进制文件的系统全局地址空间布局随机化。

**`kern.elf32.aslr.honor_sbrk`** 使 ASLR 不那么激进，更兼容依赖 sbrk 区域的旧二进制文件。

**`kern.elf32.aslr.stack`** 启用 32 位二进制文件的栈随机化。否则，栈映射在由进程 ABI 确定的固定位置。

**`kern.elf64.aslr.enable`** 64 位 ELF 二进制文件的 ASLR 控制。

**`kern.elf64.aslr.pie_enable`** 64 位 ELF PIE 的 ASLR 控制。

**`kern.elf64.aslr.honor_sbrk`** 64 位二进制文件的 ASLR sbrk 兼容性控制。

**`kern.elf64.aslr.stack`** 控制 64 位二进制文件的栈地址随机化。

**`kern.elf32.nxstack`** 为 32 位进程启用不可执行栈。如果硬件和相应二进制文件支持，则默认启用。

**`kern.elf64.nxstack`** 为 64 位进程启用不可执行栈。

**`kern.elf32.allow_wx`** 为 32 位进程启用同时可写和可执行页面的映射。

**`kern.elf64.allow_wx`** 为 64 位进程启用同时可写和可执行页面的映射。

## 参见

chflags(1), [find(1)](/man1/find.1.md), [md5(1)](/man1/md5.1.md), mdo(1), [netstat(1)](/man1/netstat.1.md), openssl(1), proccontrol(1), [ps(1)](/man1/ps.1.md), [ssh(1)](/man1/ssh.1.md), xdm(1)（`ports/x11/xorg-clients`）, [group(5)](/man5/group.5.md), ttys(5), [mitigations(7)](/man7/mitigations.7.md), accton(8), [init(8)](/man8/init.8.md), sshd(8), [sysctl(8)](/man8/sysctl.8.md), syslogd(8), vipw(8)

## 历史

`sendmail` 手册页最初由 Matthew Dillon 编写，首次出现于 FreeBSD 3.1，1998 年 12 月。
