WinRM 通信器

原文


通信器(Communicators) 是 Packer 用来向创建的机器上上传文件、执行脚本等的机制。WinRM 通信器使用 Windows 远程管理协议(Windows Remote Management protocol)来执行此操作。

使用 WinRM 通信器的准备

WinRM 通信器不是默认的通信器,因此您始终必须明确设置 "communicator": "winrm", 模板选项。除此之外,您几乎总是必须提供一个预运行脚本,用于在来宾计算机上启用和配置 WinRM。这通常采用 PowerShell 脚本或批处理文件的形式。

如果您从全新且未配置的操作系统镜像构建,则需要将此预运行脚本作为 Autounattend.xml 文件的一部分提供,这是 Windows 自动安装操作系统所必需的。如果您在云上或从预装的镜像构建,您提供此预运行脚本的方法将因构建器而异。有关如何提供 winrm 配置脚本的更多信息,请参阅每个构建器的文档。

如果您不熟悉如何使用 autounattend 文件,请查看我们的快速指南;了解如何自动初始化操作系统对于成功使用 Packer 从 iso 构建至关重要。

WinRM 通信器选项

  • winrm_username(string)- 用于连接到 WinRM 的用户名。
  • winrm_password(string)- 用于连接到 WinRM 的密码。
  • winrm_host(string)- WinRM 要连接的地址。 注意:如果使用 Amazon EBS 构建器,您可以指定 WinRM 通过 ssh_interface 连接的接口
  • winrm_no_proxy (bool) - 将此设置为 true 将远程 host:port 添加到 NO_PROXY 环境变量。这可以连接到远程主机时绕过所有配置的代理。默认为 false
  • winrm_port (int) - 要连接的 WinRM 端口。当 winrm_use_ssl 设置为 true 时,普通未加密连接默认为 5985,SSL 默认为 5986
  • winrm_timeout (duration string | ex: "1h5m2s") - 等待 WinRM 可用的时间量。默认为 "30m",因为设置 Windows 机器通常需要很长时间。
  • winrm_use_ssl (bool) - 如果为 true,则对 WinRM 使用 HTTPS。
  • winrm_insecure (bool) - 如果为 true,则不检查服务器证书链和主机名。
  • winrm_use_ntlm (bool) - 如果为 true,WinRM 将启用 NTLMv2 身份验证(具有会话安全性),而不是默认值(基本身份验证),从而消除了在发起连接的目标来宾机器上启用基本身份验证的要求。可以在此处.aspx)找到有关远程连接身份验证的进一步阅读。

例子

WinRM 连接基础

请注意,WinRM 不是 Packer 特有的协议。 Microsoft 有大量关于 WinRM 的文档。如果您在阅读本指南后发现仍然无法通过 WinRM 进行连接,请查看 Microsoft 文档以确保没有遗漏任何内容。

为了使 Packer 能够通过 WinRM 进行连接,您通常需要执行一些步骤:

  1. 设置 Packer 连接用的用户名和密码。
  2. 对注册表进行必要的设置以启用远程执行(如果需要,还可以启用提权的远程执行)
  3. 启动 WinRM,对设置进行必要的修改以允许基本身份验证
  4. 根据您的连接方式打开端口 5985 和/或 5986
  5. 启动 WinRM 并将其设置为在计算机重新启动时自动启动
  6. 如有必要,生成自签名证书或向 WinRM 侦听器提供真实证书。

在 VMWare 中配置 WinRM

如果您使用 Autounattend.xml 配置 WinRM,设置 WinRM 的最简单方法是像这样将配置命令直接放入 Autounattend 文件中。

您还可以将一个批处理文件添加到您的 autounattend,而不是单独输入每一行,其中包含用于配置 winrm 的命令。根据您的 winrm 设置,这可能是一个复杂的批处理文件,也可能是一个非常简单的批处理文件。

下面是我们如何从 Autounattend 文件中调用批处理文件的示例:

<FirstLogonCommands>
  ...
  <SynchronousCommand wcm:action="add">
      <CommandLine>cmd.exe /c a:\winrmConfig.bat</CommandLine>
      <Description>Configure WinRM</Description>
      <Order>3</Order>
      <RequiresUserInput>true</RequiresUserInput>
  </SynchronousCommand>
  ...
</FirstLogonCommands>

也可以用类似的方式调用 PowerShell 脚本。

上面引用的 winrmConfig.bat 可以很简单:

rem basic config for winrm
cmd.exe /c winrm quickconfig -q

rem allow unencrypted traffic, and configure auth to use basic username/password auth
cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}
cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}

rem update firewall rules to open the right port and to allow remote administration
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes

rem restart winrm
cmd.exe /c net stop winrm
cmd.exe /c net start winrm

请注意,上面的批处理文件是极度简化的,而且不安全,它只是提供了一个刚好能够运行的例子。下面,我们将提供一个更安全也更复杂的 WinRM 配置过程的示例。

此批处理文件仅适用于 HTTP 连接,不适用于 HTTPS,但可让您仅使用之前在 Autounattend 文件中创建的用户名和密码进行连接。下面的批处理文件将允许您使用非常简单的 Packer 配置进行连接:

        "communicator": "winrm",
        "winrm_username": "packeruser",
        "winrm_password": "SecretPassword"

下面是一个更复杂的用于配置的 PowerShell 脚本示例:

# A Packer config that works with this example would be:
#
#
#    "winrm_username": "Administrator",
#    "winrm_password": "SuperS3cr3t!!!",
#    "winrm_insecure": true,
#    "winrm_use_ssl": true
#
#

# Create username and password
net user Administrator SuperS3cr3t!!!
wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE

Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore

# Don't set this before Set-ExecutionPolicy as it throws an error
$ErrorActionPreference = "stop"

# Remove HTTP listener
Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse

# Create a self-signed certificate to let ssl work
$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force

# WinRM
write-output "Setting up WinRM"
write-host "(host) setting up WinRM"

# Configure WinRM to allow unencrypted communication, and provide the
# self-signed cert to the WinRM listener.
cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}'
cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"

# Make sure appropriate firewall port openings exist
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"

# Restart WinRM, and set it so that it auto-launches on startup.
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm

请注意,如果您将来不需要服务器接收 WinRM 连接,那么让 WinRM 保持自动启动可能不是正确的选择。自行清理并在最后的配置步骤关闭不必要的防火墙端口,以确保镜像安全。

在云端配置 WinRM

大多数云允许我们提供在实例启动时运行的配置脚本。在 AWS 上是 user_data_file。在 Google Cloud 上,这是使用 windows-startup-script-cmd 元数据标签提供的功能(例子)。

本质上,这些文件是配置 winrm 的 powershell 或 cmd 脚本,无需包装在 Autounattend 中。以各家云厂商要求的格式提供脚本,并确保您手动配置云厂商不允许内部管理的防火墙规则。各家云厂商的更多具体细节可以在构建器部分找到。

results matching ""

    No results matching ""