生产环境的安全加固
本节将讨论在生产环境部署 Vault 的最佳实践。
这些关于最佳实践的建议被分为两个部分:在任何生产环境中部署 Vault 时都必须尽全力遵守的基线建议,以及提供了额外的安全性,却由于需要额外的管理开销而可能不适用于某些环境的扩展建议。
基线建议
- 不要用 root 账号运行:使用专用的非特权服务帐户运行 Vault,而不是使用 root 或管理员帐户运行。 Vault 旨在由非特权用户运行,这样做可以显著防御各种提权攻击。
- 仅允许最小化的写特权:非特权 Vault 服务帐户不应拥有可覆盖其可执行二进制文件或任何 Vault 配置文件的权限。Vault 用户只能写入本地 Vault 存储(例如,用于集成存储后端)或审计日志的目录和文件。
- 端到端的 TLS:Vault 在生产环境中应始终启用 TLS。如果在 Vault 前方还部署了中间负载均衡器或是反向代理,则应将 TLS 用于系统的每个组件(包括存储后端)之间的所有网络连接,以确保在进出 Vault 的传输过程中对所有流量进行加密。如果可能,应使用 Vault 的自定义响应标头功能设置 HTTP 严格传输安全 (HSTS) 标头。
- 禁用虚拟内存:Vault 的数据在传输时或是落盘时都是加密的,但是在内存中仍然保有敏感数据的明文。应通过禁用虚拟内存来最小化数据泄露风险,以防止操作系统将敏感数据换出到磁盘。这在使用集成存储后端时尤其重要。
- 禁用核心转储(Core Dump):可以强制执行核心转储并有权访问转储文件的用户或管理员可能可以访问到 Vault 加密密钥。禁用核心转储是一个特定于平台的过程;在 Linux 平台上可以通过将资源的
RLIMIT_CORE
限制设置为 0 来禁用核心转储。如果使用的是 systemd 服务,可以通过设置LimitCORE=0
来强制 Vault 服务禁用核心转储。 - 单租户:Vault 应该是机器上运行的唯一主进程。这降低了在同一台机器上运行的另一个进程被破坏并通过它与 Vault 交互的风险。同样,在裸机上运行应该优于在 VM 上运行,在 VM 中运行应该优于在容器中运行。
- 使用防火墙控制流量:使用云服务商的本地防火墙或网络安全功能来限制 Vault 和 NTP 等基本系统服务的传入和传出流量。这包括限制传入流量到允许的子网和传出流量到 Vault 需要连接到的服务,例如数据库。
- 避免使用根令牌:Vault 在首次初始化时会返回一个根令牌。此令牌应用于最初设置系统,特别是设置身份验证方法以便用户可以进行身份验证。我们建议使用代码来编排 Vault 配置,并对 Vault 策略进行版本化控制。设置后,应撤销根令牌以消除暴露风险。根令牌可以在需要时生成,并应尽快撤销。
- 启用审计日志:Vault 支持数种审计设备。启用审计日志记录可提供 Vault 执行的所有操作的历史记录,并在误用或泄露的情况下提供取证跟踪。审计日志中敏感数据会被安全地哈希,但仍应限制访问日志文件以防止任何意外泄露。
- 禁用 Shell 命令历史记录:我们最好能够将
vault
命令排除在 Shell 命令历史记录之外以防止命令中的机密信息泄漏。在bash
中我们可以通过设置环境变量来实现该目标:
$ export HISTIGNORE="&:vault*"
- 频繁升级:Vault 开发非常活跃,并且频繁更新对于合并安全修复和默认设置(例如密钥长度或密码套件)中的任何更改非常重要。请订阅 HashiCorp 公告邮件列表来获取新版本发布的通告,并访问 Vault 变更记录 以获取每次版本更新的变更详情。
- 同步时钟:使用 NTP 或任何适合运行环境的机制来确保所有 Vault 节点有一致的时间。 Vault 将时钟用于执行 TTL 和在 PKI 证书中设置日期等事情,如果节点有明显的时钟偏差,故障转移可能会引发严重破坏。
- 限制对存储的访问:无论使用的是哪种存储后端,Vault 都会加密所有静态数据。尽管数据是加密的,但具有最高控制权的攻击者可以通过修改或删除密钥来导致数据损坏或丢失。对存储后端的访问应仅限于 Vault,以避免未经授权的访问或操作。
不要用明文存储凭据:Vault 配置文件中的
seal
配置节可以用来配置使用的封印类型以提供额外的数据保护,例如使用 HSM 或是云端 KMS 方案来加解密主密钥。不要用明文形式在seal
配置节中存储云的凭据或是 HSM 的 pin 码。如果 Vault 服务器与 KMS 服务托管在同一云平台上,请使用特定于平台的身份解决方案:- AWS 上的实例配置文件
- Azure 上的 Managed Service Identities (MSI)
如果以上都不可用,可以将凭据设置在环境变量中(例如 VAULT_HSM_PIN
)。
- 尽可能使用最安全的算法:Vault 的 TLS 侦听器支持多种遗留算法以实现向后兼容性。虽然这些算法可用,但不建议使用它们,尤其是在有更强大的替代方案可用时。如果可能,使用 TLS 1.3 可确保使用现代加密算法来加密传输中的数据和前向保密。
- 遵循插件的最佳实践:虽然 HashiCorp 开发的插件通常默认为安全配置,但应该注意是否有配置错误或恶意的 Vault 插件。这些可能会损害 Vault 部署的安全状况。
- 非确定性的文件合并:Vault 的配置文件合并是不确定的,文件之间的设置不一致可能会导致 Vault 设置不一致。确保所有文件(以及由
-config
表示的任何合并在一起的文件)的设置配置一致。 - 使用正确的文件系统权限:始终确保在启动 Vault 之前对文件应用适当的权限,尤其是那些包含敏感信息的文件。
扩展建议
- 禁用 SSH/远程桌面:将 Vault 作为单租户应用程序运行时,用户不应直接访问计算机。相反,他们应该通过网络上的 API 访问 Vault。使用集中式日志记录和遥测解决方案进行调试。请务必根据需要限制对日志的访问。
- 开启 systemd 安全功能:Systemd 提供了许多可用于锁定对文件系统和管理功能的访问的功能。官方 Vault Linux 软件包提供的服务单元文件默认设置了其中的一些,包括:
ProtectSystem=full
PrivateTmp=yes
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK
AmbientCapabilities=CAP_IPC_LOCK
ProtectHome=read-only
PrivateDevices=yes
NoNewPrivileges=yes
请阅读 systemd.exec 手册获取更多详细信息。
- 采用不可变风格的更新方式:Vault 依赖于外部存储后端来实现持久性,这种解耦允许使用不可变的风格来管理运行 Vault 的服务器。升级到新版本时,带有升级版 Vault 的新服务器将联机。它们连接到同一个共享存储后端并且解封。然后旧服务器被销毁。这减少了对可能引入安全漏洞的远程访问和升级编排的需求。
- 配置使用 SELinux / AppArmor:在使用 Vault 时,使用 SELinux 和 AppArmor 等额外机制有助于提供额外的安全层。虽然 Vault 可以在许多操作系统上运行,但由于此处提到的各种安全原语,我们建议使用 Linux。
- 调整 ulimits:我们使用的 Linux 发行版可能对进程的
ulimits
有严格的约束。在部署到生产环境之前,应考虑审查ulimits
规定的打开文件数、连接数等,该限制数可能需要增大。 - Docker 容器:为了在 Vault 容器内部使用“内存锁定”功能,我们可能需要使用类似
overlayfs2
或是其他支持该功能的驱动。