Ansible 的大量工作都是在 Linux 操作系统上完成的;事实上,这本书的前两个版本完全基于在以 Linux 为中心的环境中使用 Ansible。然而,大多数环境并不是这样,至少,很可能至少有一些微软 Windows 服务器和台式机。自从这本书的第三版出版以来,Ansible 已经做了很多工作来创建一个真正强大的跨平台自动化工具,无论是在 Linux 数据中心还是在 Windows 数据中心,它都同样适用。当然,Windows 和 Linux 主机的操作方式有着根本的区别,因此,在 Linux 上 Ansible 如何自动执行任务和在 Windows 上 ansi ble 如何自动执行任务之间存在一些根本的区别也就不足为奇了。
我们将在本章中介绍这些基础知识,以便为您开始使用 Ansible 自动化您的 Windows 任务打下坚实的基础,具体包括以下几个方面:
- 从窗口运行 Ansible
- 为 Ansible 控件设置 Windows 主机
- 处理 Windows 身份验证和加密
- 使用 Ansible 自动执行 Windows 任务
为了遵循本章中给出的示例,您将需要一台运行 Ansible 4.3 或更高版本的 Linux 机器。几乎任何味道的 Linux 都应该做;对于那些对细节感兴趣的人来说,本章介绍的所有代码都在 Ubuntu 服务器 20.04 LTS 和 Ansible 4.3 上进行了测试,除非另有说明。
在本章使用 Windows 的地方,示例代码在 Windows Server 2019(版本 1809,内部版本 17763.1817)上进行了测试和运行。Windows 商店的截图来自 Windows 10 Pro,版本 20H2,构建版本 19042.906。
本章附带的示例代码可从 GitHub 下载,网址为:https://GitHub . com/PacktPublishing/Mastering-Ansible-第四版/tree/main/Chapter04 。
查看以下视频,了解《行动守则》:https://bit.ly/3B2zmvL。
如果您浏览 Ansible 的官方安装文档,您会发现大多数主流 Linux 变体、Solaris、macOS 和 FreeBSD 的各种说明。但是,您会注意到,没有提到 Windows。这有一个很好的理由——对于那些对技术细节感兴趣的人来说,Ansible 在其操作中广泛使用了 POSIX fork()
系统调用,而在 Windows 上不存在这样的调用。POSIX 兼容性项目,比如德高望重的 Cygwin,曾试图在 Windows 上实现fork()
,但有时这甚至在今天也无法正常工作。因此,尽管有一个可行的 Python 实现,如果没有这个重要的系统调用,Ansible 就不能在这个平台上本地运行。
好消息是,如果你运行的是最新版本的 Windows 10,或 Windows Server 2016 或 2019,现在安装和运行 Ansible 非常容易,这要归功于Linux Windows 子系统 ( WSL )。这项技术现在有两个版本,原始 WSL 版本(在本书第三版中有介绍)和更新的 WSL2 。 WSL2 在撰写本文时,仅在 Windows 10 上可用,版本为 1903(或更高版本),内置 18362(或更高版本)。这两种技术都允许 Windows 用户在 Windows 上运行未修改的 Linux 发行版,而没有虚拟机的复杂性或开销(尽管在幕后对等,您会看到 WSL2 在 Hyper-V 上运行,尽管是以无缝的方式)。因此,这些技术非常适合运行 Ansible,因为它可以通过可靠的fork()
系统调用轻松安装和运行。
在我们继续之前,让我们停下来看一下两个要点。首先,WSL 或 WSL2 只需要从 Windows 运行 Ansible 来控制其他机器(运行任何操作系统)——它们不需要使用 Ansible 来控制 Windows 机器。我们将在本章后面看到更多关于这方面的内容。其次,不要让 Windows Server 的 WSL2 官方版本的缺乏妨碍你——如果你有 Windows bastion 主机,并希望从它们运行 Ansible,它在 WSL 上就像在 WSL2 上一样。在写这篇文章的时候,有传言说 WSL2 可以获得 Windows Server 的最新内幕预览版;然而,正如我预计大多数读者会寻找一个稳定的、生产就绪的解决方案一样,在本章中,我们将更多地关注 WSL 而不是 WSL2 。
官方 Ansible 安装文档可在https://docs . ansi ble . com/ansi ble/latest/installation _ guide/intro _ installation . html上找到。
WSL 仅在特定版本的 Windows 上可用,如下所示:
- windows 10—版本 1607(内部版本 14393)或更高版本:
- 请注意,如果您想通过微软商店安装 Linux,您将需要版本 16215 或更高版本。
- 如果您确实想使用 WSL2,您将需要 Windows 10 的版本 1903 或更高版本(内部版本 18362 或更高版本)。
- 仅支持 64 位英特尔和 ARM 版本的 Windows 10。
- Windows Server 2016 版本 1803(内部版本 16215)或更高版本
- Windows Server 2019 版本 1709(内部版本 16237)或更高版本
通过运行以下命令,您可以在 PowerShell 中轻松检查您的内部版本号:
systeminfo | Select-String "^OS Name","^OS Version"
如果您运行的是早期版本的 Windows,则仍然可以通过虚拟机或 Cygwin 运行 Ansible。然而,这些方法超出了本书的范围。
一旦您验证了您的构建,启用 WSL 就很容易了。只需以管理员身份打开 PowerShell 并运行以下命令:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
安装成功完成后,您将能够选择并安装您喜欢的 Linux 发行版。有一些是可用的,但是为了运行 Ansible,选择官方 Ansible 安装说明中列出的一个是有意义的,比如 Debian 或者 Ubuntu。
如果你有足够新的 Windows 10 版本,那么安装你喜欢的 Linux 就像打开微软商店并搜索它一样简单。比如搜索Ubuntu
,应该很容易找到。图 4.1 显示了最新的 LTS 版 Ubuntu,可在微软 Windows 10 商店下载:
图 4.1–Windows 10 上微软商店应用中的 WSL 和 WSL2 可用的 Linux 发行版之一
要在 WSL 下安装 Ubuntu,只需点击获取按钮,等待安装完成。
如果您运行的是 Windows 10,但支持的版本早于 16215,或者实际上支持任何版本的 Windows Server 2016/2019,那么安装 Linux 是一个稍微更手动的过程。首先,从微软下载您喜欢的 Linux 发行版——例如,可以使用以下 PowerShell 命令下载 Ubuntu 20.04:
Invoke-WebRequest -Uri https://aka.ms/wslubuntu2004 -OutFile Ubuntu.appx -UseBasicParsing
一旦成功下载,解压缩Ubuntu.appx
文件—只要它在系统(引导)驱动器上,通常是C:
,就可以解压缩到任何位置。如果你想保持你的 Linux 发行版的私密性,它可以解压到你的配置文件目录中的某个地方,否则,你可以解压文件到系统驱动器上的任何地方。例如,以下 PowerShell 命令会将档案解压到C:\WSL\
中:
Rename-Item Ubuntu.appx Ubuntu.zip
Expand-Archive Ubuntu.zip C:\WSL\Ubuntu
完成后,您可以使用以发行版本身命名的可执行文件启动新安装的 Linux 发行版。在我们的 Ubuntu 示例中,您将通过资源管理器(或您喜欢的方法)运行以下内容:
C:\WSL\Ubuntu\ubuntu2004.exe
第一次运行新安装的 Linux 发行版时,无论是通过微软商店安装还是手动安装,它都会自动初始化。作为此过程的一部分,它将要求您创建一个新的用户帐户。请注意,这个账号是独立于你的 Windows 用户名和密码的,所以一定要记住你在这里设置的密码!每次通过sudo
运行命令时,您都将需要它(例如),尽管像任何 Linux 发行版一样,如果您愿意,您可以通过/etc/sudoers
自定义此行为。这在图 4.2 中有演示:
图 4.2–首次运行时的 WSL Ubuntu 终端输出
恭喜你!现在您已经在 WSL 下运行了 Linux。从这里开始,您应该遵循 Ansible 的标准安装过程,并且您可以从您的 Linux 子系统运行它,就像在任何其他 Linux 盒子上一样。
到目前为止,我们已经讨论了从 Windows 运行 Ansible 本身。这是很有帮助的,尤其是在一个公司的环境中,在这个环境中,也许 Windows 终端用户系统是常态。然而,实际的自动化任务呢?好消息是,如前所述,使用 Ansible 实现窗口自动化不需要 WSL。Ansible 的核心前提之一是无代理,这一点在 Windows 和 Linux 中依然适用。可以公平地假设,几乎任何现代 Linux 主机都将启用 SSH 访问,同样,大多数现代 Windows 主机都内置了一个远程管理协议,称为 WinRM。Windows 的忠实追随者会知道,微软在更近的版本中,同时添加了 OpenSSH 客户端和服务器包,自从这本书的上一版出版以来,对这些包的实验性支持已经添加到 Ansible 中。出于安全原因,这两种技术在默认情况下都被禁用,因此,在本书的这一部分中,我们将介绍使用 Ansible 启用和保护 WinRM 进行远程管理的过程。我们还将简要介绍如何在 Windows 上设置和使用 OpenSSH Server–然而,由于 Ansible 目前对此的支持是实验性的,并且在未来版本中带有许多关于稳定性和向后不兼容更改的警告,大多数用户将希望使用 WinRM,尤其是在稳定的生产环境中。
考虑到这一点,让我们在本章的下一部分开始研究使用 WinRM 在 Windows 主机上自动执行任务。
Ansible 对 WinRM 的使用意味着对新老 Windows 版本的广泛支持——实际上,几乎任何支持以下功能的 Windows 版本都可以工作:
- PowerShell 3.0
- 。NET 4.0
实际上,这意味着可以支持以下 Windows 版本,前提是满足前面的要求:
- 桌面 : Windows 7 SP1、8.1 和 10
- 服务器 : Windows Server 2008 SP2,2008 R2 SP1,2012,2012 R2,2016,2019
请注意,之前列出的较旧操作系统(如 Windows 7 或 Server 2008)没有随附。NET 4.0 或 PowerShell 3.0,这些都需要安装后才能与 Ansible 一起使用。正如您所料,支持较新版本的 PowerShell,同样,还可能有针对的安全修补程序。NET 4.0。只要您能够满足这些最低要求,您就可以开始使用 Ansible 自动化 Windows 任务,即使在旧操作系统仍然占主导地位的业务环境中也是如此。
如果您使用的是较旧(但受支持)的 PowerShell 版本,如 3.0,请注意 PowerShell 3.0 下的 WinRM 中存在一个错误,该错误限制了服务可用的内存,这反过来会导致某些 Ansible 命令失败。通过确保将 KB2842230 应用于运行 PowerShell 3.0 的所有主机,可以解决这个问题,因此,如果您通过 PowerShell 3.0 在 Windows 中自动执行任务,请务必检查您的修补程序和补丁。
如前所述,一旦满足了所有系统要求,剩下的任务就是启用并保护 WinRM 侦听器。实现这一点后,我们实际上可以针对 Windows 主机本身运行 Ansible 任务!WinRM 可以在 HTTP 和 HTTPS 协议上运行,虽然通过普通 HTTP 启动和运行是最快和最容易的,但这使您容易受到数据包嗅探器的攻击,并有可能在网络上泄露敏感数据。如果使用基本身份验证,情况尤其如此。默认情况下,也许不出所料,Windows 不允许使用 WinRM 通过 HTTP 或使用基本身份验证进行远程管理。
有时,基本身份验证就足够了(例如,在开发环境中),如果要使用它,那么我们肯定希望启用 HTTPS 作为 WinRM 的传输!但是,在本章的后面,我们将看一下 Kerberos 身份验证,它更可取,并且还支持使用域帐户。不过现在,为了演示将 Ansible 连接到具有一定安全性的 Windows 主机的过程,我们将使用自签名证书在 HTTPS 上启用 WinRM,并启用基本身份验证以允许我们使用本地Administrator
帐户。
要使 WinRM 在 HTTPS 上运行,必须存在具有以下内容的证书:
- 与主机名匹配的
CN
值 - 增强密钥用法字段中的
Server Authentication (1.3.6.1.5.5.7.3.1)
理想情况下,这应该由一个中央证书颁发机构 ( CA )生成,以防止中间人攻击和类似攻击——稍后将对此进行更多介绍。但是,为了给所有读者提供一个他们能够测试出来的例子,我们将生成一个自签名证书。在 PowerShell 中运行以下命令以生成合适的证书:
New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "$env:computername" -FriendlyName "WinRM HTTPS Certificate" -NotAfter (Get-Date).AddYears(5)
New-SelfSignedCertificate
命令仅在较新版本的 Windows 上可用—如果您的系统上没有该命令,请考虑使用 Ansible 提供的自动化 PowerShell 脚本,该脚本可在https://raw . githubusercontent . com/ansi ble/ansi ble/develop/examples/scripts/configureremoting for ansi . PS1上获得。
这应该会产生类似于图 4.3 所示的结果——记下证书指纹,因为您稍后会需要它:
图 4.3–使用 PowerShell 为 WinRM HTTPS 侦听器创建自签名证书
有了证书,我们现在可以使用以下命令设置一个新的 WinRM 侦听器:
New-Item -Path WSMan:\Localhost\Listener -Transport HTTPS -Address * -CertificateThumbprint <thumbprint of certificate>
成功后,该命令会在端口5986
上使用我们之前生成的自签名证书设置一个 WinRM HTTPS 侦听器。为了使 Ansible 能够通过 WinRM 自动运行该窗口主机,我们需要执行两个步骤——在防火墙上打开该端口并启用基本身份验证,以便我们可以使用本地Administrator
帐户进行测试。这是通过以下两个命令实现的:
New-NetFirewallRule -DisplayName "WinRM HTTPS Management" -Profile Domain,Private -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986
Set-Item -Path "WSMan:\localhost\Service\Auth\Basic" -Value $true
您应该会看到类似于图 4.4 所示的先前命令的输出:
图 4.4–在 PowerShell 中创建并启用对 WinRM HTTPS 侦听器的访问
这些命令已经被逐个分解,让你了解为 Ansible 连接设置一个 Windows 主机的过程。对于New-SelfSignedCertificate
不可用的自动化部署和系统,可以考虑使用官方 Ansible GitHub 帐户上可用的ConfigureRemotingForAnsible.ps1
脚本,我们在本节前面已经提到过。该脚本执行我们之前完成的所有步骤(以及更多步骤),并且可以在 PowerShell 中下载和运行,如下所示:
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file
还有许多其他方法来推出 Ansible 所需的 WinRM 配置,包括通过组策略,这在公司环境中几乎肯定是更可取的。本章本节中提供的信息现在应该已经为您提供了在您的环境中设置 WinRM 所需的所有基础知识,准备好启用对您的 Windows 主机的 Ansible 管理。
一旦配置好 WinRM,让 Ansible 与 Windows 对话就相当简单了,前提是你要记住两个警告——它希望使用 SSH 协议,如果你没有指定用户帐户,它将会尝试使用 Ansible 正在运行的同一用户帐户进行连接。这几乎肯定是行不通的与 Windows 用户名。
另外,请注意,Ansible 需要安装winrm
Python 模块才能成功连接。这并不总是默认安装的,所以在开始使用 Windows 主机之前,值得在您的 Ansible 系统上测试一下。如果不存在,您将看到类似于图 4.5 所示的错误:
图 4.5–在 Ubuntu 服务器 20.04 上存在 winrm Python 模块的简单测试
如果您看到此错误,您需要先安装模块,然后再继续。您的操作系统可能有一个预打包版本,例如,在 Ubuntu 服务器 20.04 上,您可以使用以下命令安装它:
sudo apt install python3-winrm
如果没有打包的版本,使用以下命令直接从pip
安装。请注意,在 第 2 章从早期 Ansible 版本迁移中,我们讨论了使用 Python 虚拟环境安装 ansi ble–如果您已经这样做了,您必须确保激活您的 virtualenv,然后在没有sudo
的情况下运行以下命令:
sudo pip3 install "pywinrm>=0.3.0"
一旦这项工作完成,我们就可以进行测试,看看我们早期的 WinRM 配置工作是否成功。对于基于 SSH 的连接,有一个名为ansible.builtin.ping
的 Ansible 模块,它执行完整的端到端测试,以确保连接性、成功的身份验证以及远程系统上可用的 Python 环境。类似地,有一个名为win_ping
(来自ansible.windows
集合)的模块,它在 Windows 上执行类似的测试。
在我的测试环境中,我将准备如下清单,以连接到我新配置的 Windows 主机:
[windows]
10.50.0.101
[windows:vars]
ansible_user=Administrator
ansible_password="Password123"
ansible_port=5986
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
请注意从ansible_
开始的连接特定变量,这些变量是在行动手册的windows:vars
部分设置的。在这个阶段,它们应该是相当不言自明的,因为它们包含在 第 1 章**ansi ble的系统架构和设计中,但是,特别要注意的是ansible_winrm_server_cert_validation
变量,当使用自签名证书时,该变量需要设置为ignore
。显然,在现实世界的例子中,您不会将ansible_password
参数留在明文中——它要么被放在一个 Ansible 的库中,要么在启动时通过使用--ask-pass
参数被提示。
*基于证书的身份验证也可以使用 WinRM,它与基于 SSH 密钥的身份验证具有或多或少的相同优势和风险。
使用之前的清单(针对您的环境进行了适当的更改,如主机名/IP 地址和身份验证详细信息),我们可以运行以下命令来测试连通性:
ansible -i windows-hosts -m ansible.windows.win_ping all
如果一切顺利,您应该会看到一些类似于图 4.6 所示的输出:
图 4.6–使用 Ansible 的 ansible.windows.win_ping 模块测试 WinRM 上的 Windows 主机连接
这就完成了从一台 Ansible 主机到一台 Windows“T2”主机的成功端到端设置!通过这样的设置,您可以像在任何其他系统上一样编写和运行剧本,除了您必须使用专门支持 Windows 的 Ansible 模块。接下来,我们将致力于提高 Ansible 和 Windows 之间连接的安全性,最后再来看一些 Windows 行动手册的示例。
现在,我们已经建立了 Ansible 在使用 WinRM 的 Windows 主机上执行任务所需的基本连接级别,让我们更深入地了解一下事物的身份验证和加密方面。在本章的前面部分,我们使用了本地帐户的基本身份验证机制。虽然这在测试场景中没问题,但是在域环境中会发生什么呢?基本身份验证仅支持本地帐户,因此我们显然需要其他东西。我们还选择不验证 SSL 证书(因为它是自签名的),这对于测试来说也是可以的,但是在生产环境中不是最佳实践。在本节中,我们将探索提高我们与 Windows 的 Ansible 通信安全性的选项。
事实上,Ansible 在使用 WinRM 时支持五种不同的 Windows 身份验证机制,如下所示:
- 基础:仅支持本地账户
- 证书:仅支持本地账户,概念上类似于 SSH 基于密钥的认证
- Kerberos :支持 AD 账号
- NTLM :支持本地和 AD 账户
- 凭证:支持本地和 AD 账户
值得注意的是,Kerberos、NTLM 和 CredSSP 都通过 HTTP 提供消息加密,这提高了安全性。但是,我们已经看到了通过 HTTPS 设置 WinRM 是多么容易,而且默认情况下也不会启用基于普通 HTTP 的 WinRM 管理,所以我们将假设通信通道已经加密。WinRM 是一个 SOAP 协议,这意味着它必须运行在一个传输层上,比如 HTTP 或 HTTPS。为了防止远程管理命令在网络上被截获,最好的做法是确保 WinRM 通过 HTTPS 协议运行。
在这些身份验证方法中,我们最感兴趣的是 Kerberos。Kerberos(就本章而言)有效地取代了 NTLM 对活动目录帐户的可加密身份验证。CredSSP 提供了另一种机制,但也存在与拦截目标主机上的明文登录相关的安全风险,这些风险在部署前最容易理解—事实上,默认情况下是禁用的。
在我们继续配置 Kerberos 之前,先简要说明一下证书身份验证。虽然最初这看起来很有吸引力,因为它实际上是无密码的,但是 Ansible 中当前的依赖关系意味着证书身份验证的私钥必须在 Ansible 自动化主机上不加密。在这方面,将基本或 Kerberos 身份验证会话的密码放在 Ansible 保管库中实际上更安全(也更明智)。我们已经介绍了基本的身份验证,因此我们将在这里重点介绍 Kerberos。
由于 Kerberos 身份验证仅支持活动目录帐户,因此假设由 Ansible 控制的 Windows 主机已经加入域。还假设 HTTPS 上空的 WinRM 已经建立,正如本章前面所讨论的。
有了这些要求,我们要做的第一件事就是在 Ansible 主机上安装一些与 Kerberos 相关的包。确切的软件包将取决于您选择的操作系统,但是在红帽企业版 Linux/CentOS 8 上,它看起来像这样:
sudo dnf -y install python3-devel krb5-devel krb5-libs krb5-workstation
在 Ubuntu 20.04 上,您将安装以下软件包:
sudo apt-get install python3-dev libkrb5-dev krb5-user
信息
更大范围操作系统上 Kerberos 支持的软件包要求可在 Windows 远程管理的 Ansible 文档中获得:https://docs . ansi ble . com/ansi ble/latest/user _ guide/Windows _ winrm . html。
除了这些包,我们还需要安装pywinrm[kerberos]
Python 模块。这个的可用性会有所不同——在 Red Hat Enterprise Linux/CentOS 8 上,它不能作为 RPM 提供,因此我们需要通过pip
进行如下安装(同样,如果您使用了 Python 虚拟环境,请务必激活它并运行pip3
命令,而不要使用sudo
):
sudo dnf -y install gcc
sudo pip3 install pywinrm[kerberos]
注意pip3
需要gcc
来构建模块——如果不再需要,可以在之后移除。
接下来,确保您的 Ansible 服务器可以解析您的广告相关的域名系统条目。此过程将根据操作系统和网络架构而有所不同,但重要的是,您的 Ansible 控制器必须能够解析您的域控制器的名称和相关条目,此过程的其余部分才能工作。
一旦您为您的 Ansible 控制主机配置了您的 DNS 设置,接下来,将您的域添加到/etc/krb5.conf
。比如我的测试域是mastery.example.com
,我的域控制器是DEMODEM-O5NVEP9.mastery.example.com
,所以我的/etc/krb5.conf
文件的底部是这样的:
[realms]
MASTERY.EXAMPLE.COM = {
kdc = DEMODEM-O5NVEP9.mastery.example.com
}
[domain_realm]
.mastery.example.com = MASTERY.EXAMPLE.COM
注意大写——这很重要!使用带有已知域用户帐户的kinit
命令测试您的 Kerberos 集成。例如,我将使用以下命令测试与我的测试域的集成:
kinit Administrator@MASTERY.EXAMPLE.COM
klist
成功的测试应该如图 4.7 所示:
图 4.7–测试 Ubuntu Ansible 控制主机和 Windows 域控制器之间的 Kerberos 集成
最后,让我们创建一个 Windows 主机清单—注意,它几乎与我们在基本身份验证示例中使用的清单相同;只是这次,我们在用户名后面指定了 Kerberos 域:
[windows]
10.0.50.103
[windows:vars]
ansible_user=administrator@MASTERY.EXAMPLE.COM
ansible_password="Password123"
ansible_port=5986
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
现在,我们可以像以前一样测试连通性:
图 4.8–使用 ansible.windows.win_ping 模块和 Kerberos 身份验证的 Ansible 连通性测试
成功!前面的结果显示了与 Windows 成功的端到端连接,包括使用 Kerberos 成功验证域帐户,以及访问 WinRM 子系统。
默认情况下,WinRM 被配置为只允许给定 Windows 主机上的本地Administrators
组成员进行管理。这不一定是管理员帐户本身,我们在这里使用它是为了演示。允许使用特权较低的帐户进行 WinRM 管理是可能的,但是它们的使用可能是有限的,因为大多数 Ansible 命令都需要一定程度的特权访问。如果您希望 Ansible 通过 WinRM 获得一个特权较低的帐户,请在主机上运行以下命令:
winrm configSDDL default
运行此命令将打开一个窗口对话框。使用此选项添加并授予(至少)您希望拥有 WinRM 远程管理功能的任何用户或组Read
和Execute
权限。
到目前为止,我们一直忽略 WinRM 通信中使用的自签名 SSL 证书——显然,这并不理想,如果 SSL 证书不是自签名的,那么让 Ansible 来验证它们是非常简单的。
如果您的 Windows 机器是某个域的成员,最简单的方法是使用活动目录证书服务(ADCS)—但是,大多数企业将通过 ADCS 或另一个第三方服务建立自己的认证流程。为了继续本节,假设所讨论的 Windows 主机具有为远程管理生成的证书,并且 CA 证书以 Base64 格式提供。
正如我们之前在 Windows 主机上所做的那样,您将需要设置一个 HTTPS 侦听器,但这次使用的是您的 CA 签名的证书。您可以使用以下命令来执行此操作(如果尚未完成):
Import-Certificate -FilePath .\certnew.cer -CertStoreLocation Cert:\LocalMachine\My
自然,用与您自己的证书位置相匹配的证书替换FilePath
证书。如果需要,可以使用以下命令删除任何以前创建的 HTTPS WinRM 侦听器:
winrm delete winrm/config/Listener?Address=*+Transport=HTTPS
然后,使用导入的证书中的指纹,创建一个新的侦听器:
New-Item -Path WSMan:\Localhost\Listener -Transport HTTPS -Address * -CertificateThumbprint <thumbprint of certificate>
现在来看 Ansible 控制器。首先要做的是将 WinRM 侦听器的证书颁发机构证书导入到操作系统的证书颁发机构捆绑包中。操作系统之间的方法和位置会有所不同,但是,在 Ubuntu 服务器 20.04 上,您可以将 Base64 编码的证书放在/usr/share/ca-certificates/
中。注意,为了被识别,CA 文件必须有.crt
扩展名。
完成后,运行以下命令:
sudo dpkg-reconfigure ca-certificates
当询问您是否要信任来自新证书颁发机构的证书时,选择Yes
,并确保在下一屏幕显示的列表中选择了您的新证书文件名。
最后,我们需要告诉 Ansible 在哪里可以找到证书。默认情况下,Ansible 使用 Python 认证模块,并将为此使用默认路径,除非我们另有说明。上面的过程更新了 CA 包,位于/etc/ssl/certs/ca-certificates.crt
,幸运的是,我们可以告诉 Ansible 在库存文件中的哪里可以找到这个。请注意清单文件的两个进一步更改,如以下代码所示—首先,我们现在已经为 Windows 主机指定了完整的主机名,而不是 IP 地址,因为清单主机名必须与证书上的CN
值匹配,才能进行完全验证。此外,我们删除了ansible_winrm_server_cert_validation
行,这意味着所有 SSL 证书现在都被隐式验证:
[windows]
DEMODEM-O5NVEP9.mastery.example.com
[windows:vars]
ansible_user=administrator@MASTERY.EXAMPLE.COM
ansible_password="Password123"
ansible_port=5986
ansible_connection=winrm
ansible_winrm_ca_trust_path=/etc/ssl/certs/ca-certificates.crt
如果我们再次运行 ping 测试,现在应该会看到SUCCESS
,如图图 4.9 :
图 4.9–通过 WinRM 对 Windows 域控制器使用 Kerberos 身份验证和 SSL 验证的可执行 ping 测试
显然,我们可以改进我们的证书生成,以消除subjectAltName
警告,但目前,这表明了与 Windows 的 Ansible 连接,对域帐户进行 Kerberos 身份验证并进行完全 SSL 验证。这就完成了我们对设置 WinRM 的了解,应该会为您提供在基础架构中设置 Windows 主机以使用 Ansible 实现自动化所需的所有基础知识。
在本章的下一部分,我们将了解如何在 Windows 上设置新支持的 OpenSSH 服务器,以启用 Ansible 自动化。
微软在支持和拥抱开源社区方面取得了长足的进步,并在其操作系统中添加了许多流行的开源包。就 Ansible 自动化而言,最值得注意的是古老且非常受欢迎的 OpenSSH 包,它有客户端和服务器两种风格。
在 Ansible 2.8 中增加了对使用 SSH 作为传输而不是 WinRM 在 Windows 上自动执行任务的支持——但是,需要注意的是,在官方 Ansible 文档中有很多关于这种支持的警告——这种支持被描述为实验性的,并警告用户未来可能会以不向后兼容的方式发生变化。此外,开发人员希望在继续测试时发现更多的 bug。
出于这些原因,我们花了很多精力来描述 WinRM 的设置,以便用 Ansible 自动化窗口主机。尽管如此,如果不考虑使用 OpenSSH 为窗口启用 Ansible 自动化,这一章就不完整。
Windows 10 版本 1809 和更高版本以及 Windows Server 2019 都支持 Windows 的 OpenSSH Server。如果你运行的是旧版本的 Windows,你有两个选择——要么继续使用 WinRM 作为你的通信协议(毕竟它是内置的,一旦你知道如何使用它,就很容易配置),要么手动安装 Win32-OpenSSH 包——这个过程在这里有详细描述,应该支持从 Windows 7 开始的任何东西:https://github . com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH。鉴于该软件包的积极开发,建议读者如果想在旧版本的 Windows 上安装 OpenSSH Server,请参考本文档,因为在本书开始打印时,说明可能已经更改。
但是,如果您运行的是较新版本的 Windows,安装 OpenSSH 服务器很简单。使用具有管理员权限的 PowerShell 会话,首先,使用以下命令查询可用的OpenSSH
选项:
Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'
该命令的输出应该类似于图 4.10 中的*:*
图 4.10–显示了 Windows Server 2019 上 PowerShell 中可用的 OpenSSH 安装选项
使用这个输出,运行以下命令安装 OpenSSH 服务器:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
接下来,运行以下命令,以确保 SSH 服务器服务在启动时启动,并且存在合适的防火墙规则,以允许 SSH 流量进入服务器:
Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'
Get-NetFirewallRule -Name *ssh*
如果没有合适的防火墙规则,您可以使用如下命令添加一个规则:
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
最后,Windows 的 OpenSSH 服务器的外壳默认为cmd
。这对于交互式任务来说很好,但是大多数用于 Windows 的本机 Ansible 模块都是为支持 PowerShell 而编写的——您可以通过在 PowerShell 中运行以下命令来更改 OpenSSH 服务器的默认 Shell:
New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name 'DefaultShell' -Value 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'
完成所有这些任务后,我们终于可以像以前一样测试我们的ansible.windows.win_ping
模块了。我们的清单文件看起来与 WinRM 文件略有不同,下面的文件应该作为适合您测试目的的示例:
[windows]
DEMODEM-O5NVEP9.mastery.example.com
[windows:vars]
ansible_user=administrator@MASTERY.EXAMPLE.COM
ansible_password="Password123"
ansible_shell_type=powershell
注意我们不再关注证书验证或端口号,因为我们在默认端口22
上使用 SSH。事实上,除了用户名和密码(就像我们在本书前面所做的那样,您可以很容易地将其指定为ansible
命令的命令行参数)之外,唯一需要设置的库存变量是ansible_shell_type
,它将默认为伯恩兼容的外壳,除非我们另有说明。
win_ping
模块在测试连接时使用 PowerShell,使我们能够使用之前的临时命令来测试我们与 Windows 的新 SSH 连接。只需运行这个命令(现在应该很熟悉了!):
ansible -i windows-hosts -m ansible.windows.win_ping all
即使我们现在使用了完全不同的通信协议,这个命令的输出也是完全一样的,应该如下图图 4.11 :
图 4.11–使用 SSH 作为传输机制测试与 Windows 的 Ansible 集成
因此,将 Ansible 与 Windows 主机集成起来真的很容易设置——只需确保关注较新 Ansible 版本的发行说明和移植指南,以防事情以某种不兼容的方式发生变化。然而,我想你会同意使用 OpenSSH 将 Ansible 与 Windows 集成是很容易设置的。当然,您可以以类似于在任何其他基于 SSH 的主机上的方式设置 SSH 密钥身份验证,以确保您可以在不需要用户交互的情况下运行剧本。
现在,在通过 WinRM 和 SSH 演示 Windows 与 Ansible 集成的各个方面时,我们只使用了 Ansible ansible.windows.win_ping
模块来测试连通性。让我们在此基础上,用一些简单的示例行动手册来结束这一章,以帮助您开始使用 Ansible 创建自己的窗口自动化解决方案。
Ansible 4.3 包含的 Windows 模块列表可在以下链接获得,它必须注意的是,虽然可以在 Windows 主机上使用所有熟悉的 Ansible 构造,如vars
、handlers
和blocks
,但在定义任务时必须使用 Windows 特定的模块。集合的引入意味着定位它们相当容易,ansible.windows
集合是一个很好的起点。这包含您在 Ansible 2.9 和更早版本中习惯使用的所有特定于窗口的模块:https://docs . Ansible . com/Ansible/latest/collections/index _ module . html # Ansible-Windows。
在本章的这一部分,我们将通过几个简单的 Windows 行动手册示例来强调为 Windows 编写行动手册时需要了解的一些事情。
如果您在 Linux 服务器上运行 Ansible,并且想要创建一个目录,然后将文件复制到其中,那么您将在类似如下的剧本中使用ansible.builtin.file
和ansible.builtin.copy
Ansible 模块:
---
- name: Linux file example playbook
hosts: all
gather_facts: false
tasks:
- name: Create temporary directory
ansible.builtin.file:
path: /tmp/mastery
state: directory
- name: Copy across a test file
ansible.builtin.copy:
src: mastery.txt
dest: /tmp/mastery/mastery.txt
但是,在 Windows 上,这个剧本将无法运行,因为ansible.builtin.file
和ansible.builtin.copy
模块与 PowerShell 或 cmd 不兼容,无论您是否使用 WinRM 或 SSH 作为与 Windows 机器的通信协议。因此,在 Windows 上执行相同任务的等效剧本如下所示:
---
- name: Windows file example playbook
hosts: all
gather_facts: false
tasks:
- name: Create temporary directory
ansible.windows.win_file:
path: 'C:\Mastery Test'
state: directory
- name: Copy across a test file
ansible.windows.win_copy:
src: ~/src/mastery/mastery.txt
dest: 'C:\Mastery Test\mastery.txt'
请注意两个行动手册之间的以下差异:
ansible.windows.win_file
和ansible.windows.win_copy
用于代替ansible.builtin.file
和ansible.builtin.copy
模块。- 在文档中建议
ansible.windows.win_file
和ansible.windows.win_copy
模块在处理远程(Windows 路径)时使用反斜杠(\
)。 - 在 Linux 主机上继续使用正斜杠(
/
)。 - 使用单引号(而不是双引号)来引用包含空格的路径。
请务必查阅您的行动手册中使用的各个模块的文档。例如,查看ansible.windows.win_copy
模块文档,它建议使用ansible.windows.win_get_url
模块进行大文件传输,因为 WinRM 传输机制不是很有效。当然,如果您使用 OpenSSH 服务器代替 WinRM,这可能不适用——在撰写本文时,本模块的文档尚未更新以考虑到这一点。
另请注意,如果文件名包含某些特殊字符(例如,方括号),则需要使用 PowerShell 转义字符```对进行转义。例如,以下任务将安装c:\temp\setupdownloader_[aaff].exe
文件:
- name: Install package
win_package:
path: 'c:\temp\setupdownloader_`[aaff`].exe'
product_id: {00000000-0000-0000-0000-000000000000}
arguments: /silent /unattended
state: present
许多其他窗口模块应该足以满足您的窗口行动手册需求,结合这些提示,您将快速轻松地获得您需要的最终结果。
大多数 Linux 系统(实际上还有其他 Unix 变体)都有一个原生包管理器,这使得很容易安装各种各样的软件。chocolatey
包管理器使这成为 Windows 的可能,Ansible chocolatey.chocolatey.win_chocolatey
模块使 Ansible 以无人值守的方式安装软件变得简单(注意,这不是我们迄今为止使用的ansible.windows
集合的一部分,而是存在于它自己的集合中)。
您可以在https://chocolatey.org探索chocolatey
知识库并了解更多信息。
例如,如果你想在 Windows 机器上推广 Adobe Acrobat Reader,你可以使用ansible.windows.win_copy
或ansible.windows.win_get_url
模块分发安装程序,然后使用ansible.windows.win_package
模块安装。但是,以下代码可以用更少的代码执行相同的任务:
- name: Install Acrobat Reader
chocolatey.chocolatey.win_chocolatey:
name: adobereader
state: present
您可以使用chocolatey.chocolatey.win_chocolatey
模块运行各种聪明的安装例程,例如,您可以将包锁定到特定的版本,安装特定的体系结构等等,该模块的文档包含了大量有用的示例。官方的巧克力网站本身列出了所有可用的软件包——大多数您期望需要的常见软件包都可以在那里找到,因此它应该足以满足您将遇到的大量安装场景。
就像在任何平台上一样,可能会有某个时候,某个模块无法提供所需的确切功能。尽管编写自定义模块(或修改现有模块)是一个可行的解决方案,但有时需要更直接的解决方案。为此,ansible.windows.win_command
和ansible.windows.win_shell
模块来拯救——它们可以用来在 Windows 上运行字面上的 PowerShell 命令。官方 Ansible 文档中提供了许多示例,但是以下代码将使用 PowerShell 创建C:\Mastery
目录:
- name: Create a directory using PowerShell
ansible.windows.win_shell: New-Item -Path C:\Mastery -ItemType Directory
我们甚至可以回到传统的cmd
外壳来完成这项任务:
- name: Create a directory using cmd.exe
ansible.windows.win_shell: mkdir C:\MasteryCMD
args:
executable: cmd
有了这些指针,应该可以在几乎任何 Windows 环境中创建所需的功能。
这就是我们对带有 Ansible 的 Windows 自动化的看法——只要你记得使用正确的 Windows 本机模块,你就能像对任何给定的 Linux 主机一样轻松地将本书的其余部分应用于 Windows 主机。
Ansible 处理 Windows 主机的效率与处理 Linux(和其他 Unix)主机一样高。在本章中,我们介绍了如何从 Windows 主机运行 Ansible,以及如何将 Windows 主机与 Ansible 集成以实现自动化,包括身份验证机制、加密,甚至特定于 Windows 的行动手册的基础知识。
您已经了解了 Ansible 可以从支持 WSL 的最新版本的窗口运行,以及如何实现这一点。您还学习了如何为 Ansible 控制设置 Windows 主机,以及如何使用 Kerberos 身份验证和加密来保护这些主机。您还学习了如何设置和使用 Ansible 为 SSH 通信提供的新的实验性支持。最后,您学习了创作 Windows 行动手册的基础知识,包括找到与 Windows 主机一起使用的正确模块、转义特殊字符、为主机创建目录和复制文件、安装软件包,甚至使用 Ansible 在 Windows 主机上运行原始 shell 命令。这是一个良好的基础,您可以在此基础上构建管理自己的 Windows 主机资产所需的 Windows 行动手册。
在下一章中,我们将与 AWX 一起探讨 Ansible 在企业中的有效管理。
-
Ansible can communicate with Windows hosts using:
a)宋承宪
(b) WinRM
上述两者
-
Ansible can reliably be run from Windows:
天生地
b)使用 Python 进行 Windows 操作
通过基督教青年会
d)通过 WSL 或 WSL2
-
The
ansible.builtin.file
module can be used to manipulate files on both Linux and Windows hosts:真的
假的
-
Windows machines can have Ansible automation run on them with no initial setup:
真的
假的
-
The package manager for Windows is called:
伯恩维尔
吉百利
(c)巧克力
d) 转速
-
Ansible modules for Windows run their commands by default using:
a) PowerShell
b)
cmd.exe
c)针对 Windows 的 Bash
(d) WSL
(e) Cygwin
-
You can run Windows commands directly even if a module with the functionality you need does not exist:
真的
假的
-
When manipulating files and directories on Windows with Ansible, you should:
a)对 Windows 路径引用使用
\
,对 Linux 主机上的文件使用/
b)对所有路径使用
/
-
Special characters in Windows filenames should be escaped with:
a)
\
b) ```
c)
"
d)
/
-
Your Ansible playbooks must be changed depending on whether you are using WinRM or SSH communication:
真的
假的*