Ansible正成为当今最重要的配置管理工具之一,如果不是最重要的话。Ansible是一个方便的工具(在大多数情况下是免费的),允许DevOps工程师和系统工程师/管理员以幂等的、基于基础设施即代码的方式构建和维护跨所有环境的基础设施。但是,将其配置为通过WinRM与Windows通信可能是一个挑战。
与许多其他基础设施组件一样,Ansible可以在Windows主机上部署和维护配置状态。Ansible通过WinRM连接到这些Windows主机,尽管他们正在尝试使用SSH。
当你为Ansible配置WinRM时,你有几个不同的选项,涵盖了从设置的简易性到安全性影响的范围。很多人选择简便的方法;使用HTTP进行基本身份验证。尽管你省去了涉及证书的额外工作,但除非必须,否则在网络上传输未加密的数据永远不是一个好主意。
在这篇文章中,您将学习如何使用基于证书的身份验证来设置 WinRM 以便 Ansible 使用自签名证书与其通信。
您将在本教程中学到的设置不仅适用于 Ansible 作为客户端。这种基于证书的身份验证同样适用于其他像其他 Windows 主机这样的 WinRM 客户端。
假设
本文将是基于教程的步骤说明。如果您打算按照这里提出的步骤配置 WinRM 以供 Ansible 使用,教程将假设:
- 您已在 Linux 主机上安装了 Ansible。
- 您已经根据您的 Windows 主机设置了 Ansible 清单。
- 您有一个用于管理的 Windows Server 2016 或更高版本。本教程中使用的某些 cmdlet 在较旧版本的 Windows 上无法使用。
- Windows 主机不在域中。尽管示例是在非域加入的主机上执行的,但这种配置在域加入的主机上仍然可以工作。
- 您有 RDP 或控制台访问权限到 Windows 主机,并且以本地管理员身份登录。
- 您熟悉 PowerShell。几乎所有示例都将使用 PowerShell 代码在 Windows 主机上进行更改。
每个部分都将使用依赖于上一个部分的代码片段。一些片段将引用先前定义的变量。如果您计划完全按照此代码进行操作,请确保保持您的控制台处于打开状态。
如果您只想要代码而不需要所有的解释,请随意下载此 GitHub Gist。
为 Ansible 启用 WinRM 的 PowerShell 远程控制
虽然所有运行 Windows Server 2016 或更新版本的服务器都已启用了 PowerShell 远程控制,但确认一下总是一个好主意。
在要管理的 Windows 主机上,以管理员身份打开 PowerShell 控制台,并运行以下代码片段。此代码片段确保 WinRM 服务已启动,并设置为在系统引导时自动启动。
接下来,确保已启用 PowerShell 远程控制,首先检查是否有任何活动会话配置。如果没有,则确保它没有任何可用的监听器。Ansible 的 WinRM 必须至少有一个监听器。如果其中任何一个条件返回空值,请运行 Enable-PSRemoting
。

启用基于证书的认证
默认情况下,WinRM 未配置为基于证书的身份验证。您必须通过配置 WSMan 来启用此功能,如下所示。
创建本地用户帐户
要使用基于证书的 WinRM 进行 Ansible 身份验证,您必须将本地用户帐户“映射”到证书。您可以使用本地管理员帐户执行此操作,但最好创建一个特定帐户以便管理更加方便。
以下代码片段将为 WinRM for Ansible 创建一个名为 ansibletestuser
的本地用户帐户,密码为 p@$$w0rd12
(如果不存在的话)。为确保其始终处于活动状态,该帐户的密码将永不过期。
创建客户端证书
为了安全地使用 WinRM for Ansible,必须拥有两个证书;一个客户端证书和一个服务器证书。
您可以使用同一证书用于客户端/服务器,但我尝试此方法时遇到了问题。在 Ansible 文档和许多其他来源中,您会找到使用 PowerShell 的
New-SelfSignedCert
cmdlet 生成客户端证书的说明。尽管此方法可能有效,但我无法轻松地使其正常工作。
要为 Ansible 的 WinRM 创建客户端证书,您必须创建一个私钥和一个公钥。首先通过 SSH 登录到 Ansible 主机,并运行以下 openssl
命令。此命令将在名为 cert_key.pem 的文件中创建一个私钥,并创建一个名为 cert.pem 的公钥。密钥用途将是客户端身份验证 (1.3.6.1.4.1.311.20.2.3),“映射”到您之前创建的本地用户帐户,名为 ansibletestuser。
离 Ansible WinRM 身份验证又近了一步!
导入客户端证书
一旦您为 Ansible 的 WinRM 创建了客户端证书,您将需要将其导入到 Windows 主机上的两个证书存储中,以使 Ansible 上的 WinRM 正常工作。为此,首先将 cert.pem 公钥传输到 Windows 主机。下面的示例假定该密钥存在于 C:\cert.pem。
一旦您在 Windows 主机上拥有了公共证书,按照下面所示使用 Import-Certificate
将其导入到 受信任的根证书颁发机构 和 受信任的用户 证书存储中。
创建服务器证书
为 Ansible 的 WinRM 需要定义一个具有服务器身份验证密钥用途的证书。此证书将存储在 Windows 主机的 LocalMachine\My 证书存储中。使用下面的代码片段创建自签名证书。
创建 Ansible WinRM 监听器
一旦您创建了两个证书,现在您必须在 Windows 主机上创建一个 WinRM 监听器。此监听器开始在端口 5986 上监听传入连接。创建后,此监听器接受传入连接,并将尝试使用上面创建的服务器证书对数据进行加密。
PowerShell 远程使用此 WinRM 监听器作为传输一旦进行了身份验证。
在下面的代码片段中,您可以看到一个很好的示例,检查是否存在现有的 HTTPS 监听器。如果找不到使用上面创建的服务器证书的监听器,它将创建一个新的。
将客户端证书映射到本地用户帐户
下一步是确保当 Ansible 使用服务器证书连接到 Windows 主机时,然后将执行所有指令作为本地用户。在这种情况下,由 Ansible 执行的所有活动都将使用本地用户帐户ansibletestuser。
允许 WinRM 用于 Ansible 与用户账户控制(UAC)
如果使用本地账户映射证书,还必须将 LocalAccountTokenFilterPolicy
设置为 1,以确保 UAC 不会产生影响。 LocalAccountTokenFilterPolicy
适用于所有本地账户(非域账户),导致您的网络登录成为令牌的有限部分。这将阻止它作为管理员登录,因为默认情况下 WinRM 要求用户是本地管理员。
通过设置 LocalAccountTokenFilterPolicy
,您告诉 Windows 不为本地账户的网络登录创建有限令牌,并使用其完整令牌。
在 Windows 防火墙上打开端口 5986
WinRM over HTTPS 使用端口 5986。如果启用了 Windows 防火墙,必须打开此端口。您可以通过运行以下 PowerShell 代码片段来执行此操作。此代码片段过于宽松,允许所有计算机使用它。如果想要进一步锁定,请确保使用 LocalAddress
参数并指定 Ansible 的 IP。
将本地用户添加到管理员组
您可能会问为什么本教程没有早些将本地用户添加到管理员组。原因是,当您尝试将客户端证书映射到用户时,用户帐户不能是本地管理员。
运行以下代码片段将ansibletestuser本地用户帐户添加到管理员组。
结论
如果您按照所示的每个步骤进行操作,现在应该能够针对 Windows 主机执行 Ansible 命令。 使用win_shell模块执行测试。 如果此模块成功,则已成功配置了 Ansible 和基于证书的身份验证!