保护 Windows 容器
适用范围:Windows Server 2022、Windows Server 2019、Windows Server 2016
容器可以缩减其映像大小,这是因为它们可依靠主机来提供对各种资源的有限访问。 如果容器知道主机将能够提供执行一组特定操作所需的功能,则该容器不需要在其基础映像中包含相关软件。 但是,发生的资源共享程度可能会对容器的性能和安全性产生显著影响。 如果共享的资源过多,应用程序可能也会作为进程在主机上运行。 如果共享的资源过少,容器就变得无法与 VM 区分。 这两种配置都适用于许多场景,但大多数使用容器的用户通常会选择适中的内容。
Windows 容器的安全性派生自其主机发生的共享程度。 容器的安全边界通过可将容器与主机隔离开来的机制构成。 最重要的是,这些隔离机制定义了容器中哪些进程可与主机交互。 如果容器的设计允许提升的(管理员)进程与主机进行交互,则 Microsoft 不会认为此容器具有可靠的安全边界。
Windows Server 容器与 Linux 容器
进程隔离的 Windows Server 容器和 Linux 容器具有相似的隔离程度。 对于这两种容器类型,开发人员须承担可通过主机上的提升进程执行的任何攻击,以及还可通过容器中的提升进程进行的攻击。 两种容器都通过各自主机内核提供的基元功能来运行。 容器映像的构建包含利用主机内核所提供 API 的用户模式二进制文件。 主机内核为用户空间中运行的每个容器提供相同的资源隔离和管理功能。 如果内核遭到入侵,则共享该内核的每个容器同样遭到入侵。
Linux 和 Windows server 容器的基本设计以安全性换取灵活性。 Windows Server 和 Linux 容器在 OS 提供的基元组件基础之上构建。 这样一来便可以灵活在容器之间共享资源和命名空间,但会增加额外的复杂性,易于受到攻击。 通俗地说,我们认为内核对恶意多租户工作负载而言并不足以成为安全边界。
使用虚拟机监控程序隔离容器的内核隔离
与进程隔离的 Windows Server 或 Linux 容器相比,虚拟机监控程序隔离的容器提供了更高的隔离程度,被视为可靠的安全边界。 虚拟机监控程序隔离的容器由在超轻型 VM 中包装的 Windows Server 容器组成,并通过 Microsoft 的虚拟机监控程序与主机 OS 一起运行。 虚拟机监控程序提供硬件级隔离,在主机与其他容器之间包含了高度可靠的安全边界。 即使攻击要对 Windows Server 容器进行转义,攻击也将包含在虚拟机监控程序隔离的 VM 中。
Windows Server 容器或 Linux 容器均不提供 Microsoft 认为可靠的安全边界,且不应在恶意多租户场景中使用。 容器必须局限于专用 VM,以防止恶意容器进程与主机或其他租户进行交互。 虚拟机监控程序隔离实现了这种程度的分离,同时还提供了优于传统 VM 的多方面性能提升。 因此,强烈建议在恶意多租户场景中,虚拟机监控程序隔离的容器应是所选容器。
Windows 安全服务标准
Microsoft 致力于修补所有可破坏任何 Windows 容器类型所建立的隔离边界的攻击和转义。 但是,只有破坏安全边界的漏洞才通过 Microsoft 安全响应中心 (MSRC) 进程进行修复。 只有虚拟机监控程序隔离的容器提供安全边界,而进程隔离容器不提供。 为进程隔离容器转义生成 bug 的唯一方式就是非管理员进程可访问主机。 如果攻击使用管理员进程来转义容器,则 Microsoft 会认为这是一个非安全 bug,并按常规服务过程进行修补。 如果攻击使用非管理员进程来执行违反安全边界的操作,则 Microsoft 将按确立的安全服务标准对其进行调查。
什么情况下会将多租户工作负载视为具有恶意?
当多个工作负载在共享基础结构和资源上操作时,存在多租户环境。 如果基础结构上运行的一个或多个工作负载不可信任,多租户环境就会被视为恶意环境。 Windows Server 和 Linux 容器共享主机内核,因此对单个容器执行的任何攻击都可能影响共享基础结构上运行的所有其他工作负载。
可以采取措施来降低发生攻击的可能性,例如,通过使用 Pod 安全策略、AppArmor 和基于角色的访问控制 (RBAC),但这些措施无法针对攻击者提供有保证的保护。 对于所有多租户场景,建议你遵循群集隔离最佳做法。
何时使用 ContainerAdmin 和 ContainerUser 用户帐户
Windows Server 容器提供两个默认用户帐户:ContainerUser 和 ContainerAdministrator,每个帐户都有自己的特定用途。 ContainerAdministrator 帐户使你能够使用容器进行管理:安装服务和软件(例如在容器中启用 IIS)、进行配置更改,以及创建新帐户。 这些任务对可能在自定义本地部署环境中运行的多种 IT 场景都非常重要。
对于不需要 Windows 中的管理员特权的所有其他场景,可使用 ContainerUser 帐户。 例如,在 Kubernetes 中,如果用户为 ContainerAdministrator,并且允许将 hostvolumes 装载到 Pod,则用户可以装载 .ssh 文件夹并添加公钥。 对于 ContainerUser,此示例将无法实现。 该帐户是专门为不需要与主机进行交互的应用程序设计的受限用户帐户。 强烈建议在将 Windows Server 容器部署到任何多租户环境时,应用程序通过 ContainerUser 帐户运行。 在多租户环境中,最好始终遵循最低权限原则,因为如果攻击者入侵了工作负载,则共享资源和邻近工作负载也会受到影响。 使用 ContainerUser 帐户运行容器极大地降低了环境遭到入侵的可能性。 但是,这仍然未提供可靠的安全边界,因此,如果需要考虑安全性,则应使用虚拟机监控程序隔离的容器。
若要更改用户帐户,可以在 Dockerfile 中使用 USER 语句:
USER ContainerUser
你也可以创建一个新用户:
RUN net user username ‘<password>’ /ADD
USER username
Windows 服务
Microsoft Windows 服务(过去称为 NT 服务)允许用户创建可在其自身的 Windows 会话中长时间运行的可执行应用程序。 这些服务可以在操作系统启动时自动启动,可以暂停和重新启动,并且不显示任何用户界面。 还可以在与登录用户或默认计算机帐户不同的特定用户帐户的安全性上下文中运行服务。
在容器化和保护作为 Windows 服务运行的工作负荷时,还需要注意一些其他注意事项。 首先,容器的 ENTRYPOINT
不会成为工作负荷,因为服务作为后台进程运行,通常 ENTRYPOINT
将是诸如服务监视器或日志监视器之类的工具。 其次,运行工作负荷的安全帐户将由服务配置,而不是由 dockerfile 中的 USER 指令配置。 可以通过运行 Get-WmiObject win32_service -filter "name='<servicename>'" | Format-List StartName
来检查服务将在哪个帐户下运行。
例如,使用 ASP.NET(Microsoft 项目注册表)映像托管 IIS Web 应用程序时,容器的 ENTRYPOINT
为 "C:\\ServiceMonitor.exe", "w3svc"
。 此工具可用于配置 IIS 服务,然后监视服务,以确保该服务保持运行状态并退出,从而在服务因任何原因停止时停止容器。 默认情况下,IIS 服务以及 Web 应用程序在容器中的低权限帐户下运行,但服务监视器工具需要管理权限才能配置和监视服务。