Windows SSH
在较新的 Windows 版本上,您可以使用 SSH 连接到 Windows 主机。这是 WinRM 的替代连接选项。
注意
虽然 Ansible 自 2.8 版本起可以使用 SSH 连接插件连接 Windows 节点,但官方支持仅在 2.18 版本中添加。
SSH 设置
自 Windows Server 2019 起,Microsoft 为 Windows 提供了一个 OpenSSH 实现作为 Windows 功能。它也可以通过 Win32-OpenSSH 下的上游软件包安装。Ansible 官方仅支持 Windows 附带的 OpenSSH 实现,而不支持上游软件包。OpenSSH 版本必须至少为 7.9.0.0
。这实际上意味着官方支持从 Windows Server 2022 开始,因为 Server 2019 附带的版本是 7.7.2.1
。使用较旧的 Windows 版本或上游软件包可能有效,但不受支持。
要在 Windows Server 2022 及更高版本上安装 OpenSSH 功能,请使用以下 PowerShell 命令
Get-WindowsCapability -Name OpenSSH.Server* -Online |
Add-WindowsCapability -Online
Set-Service -Name sshd -StartupType Automatic -Status Running
$firewallParams = @{
Name = 'sshd-Server-In-TCP'
DisplayName = 'Inbound rule for OpenSSH Server (sshd) on TCP port 22'
Action = 'Allow'
Direction = 'Inbound'
Enabled = 'True' # This is not a boolean but an enum
Profile = 'Any'
Protocol = 'TCP'
LocalPort = 22
}
New-NetFirewallRule @firewallParams
$shellParams = @{
Path = 'HKLM:\SOFTWARE\OpenSSH'
Name = 'DefaultShell'
Value = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'
PropertyType = 'String'
Force = $true
}
New-ItemProperty @shellParams
默认 Shell 配置
默认情况下,Windows 上的 OpenSSH 使用 cmd.exe
作为默认 shell。虽然 Ansible 可以使用此默认 shell,但建议将其更改为 powershell.exe
,因为它经过更好的测试,并且应该比使用 cmd.exe
作为默认 shell 更快。要更改默认 shell,可以使用以下 PowerShell 脚本
# Set default to powershell.exe
$shellParams = @{
Path = 'HKLM:\SOFTWARE\OpenSSH'
Name = 'DefaultShell'
Value = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'
PropertyType = 'String'
Force = $true
}
New-ItemProperty @shellParams
# Set default back to cmd.exe
Remove-ItemProperty -Path HKLM:\SOFTWARE\OpenSSH -Name DefaultShell
新的默认 shell 设置将应用于下一个 SSH 连接,无需重启 sshd
服务。您还可以使用 Ansible 配置默认 shell
- name: set the default shell to PowerShell
ansible.windows.win_regedit:
path: HKLM:\SOFTWARE\OpenSSH
name: DefaultShell
data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
type: string
state: present
- name: reset SSH connection after shell change
ansible.builtin.meta: reset_connection
- name: set the default shell to cmd
ansible.windows.win_regedit:
path: HKLM:\SOFTWARE\OpenSSH
name: DefaultShell
state: absent
- name: reset SSH connection after shell change
ansible.builtin.meta: reset_connection
meta: reset_connection
非常重要,以确保后续任务将使用新的默认 shell。
Ansible 配置
要配置 Ansible 对 Windows 主机使用 SSH,您必须设置两个连接变量
将
ansible_connection
设置为ssh
将
ansible_shell_type
设置为powershell
或cmd
ansible_shell_type
变量应反映 Windows 主机上配置的 DefaultShell
。在 ssh 下记录的其他 SSH 选项也可以为 Windows 主机设置。
SSH 身份验证
Win32-OpenSSH 与 Windows 的身份验证类似于 Unix/Linux 主机上的 SSH 身份验证。虽然可以使用许多身份验证方法,但通常在 Windows 上使用三种方法
选项 |
本地帐户 |
Active Directory 帐户 |
凭据委派 |
---|---|---|---|
密钥 |
是 |
是 |
否 |
GSSAPI |
否 |
是 |
是 |
密码 |
是 |
是 |
是 |
在大多数情况下,建议使用密钥或 GSSAPI 身份验证而不是密码身份验证。
密钥身份验证
Windows 上的 SSH 密钥身份验证的工作方式与 POSIX 节点的 SSH 密钥身份验证相同。您可以使用 ssh-keygen
命令生成密钥对,并将公钥添加到用户配置文件目录中的 authorized_keys
文件中。私钥应保持安全,不得共享。
一个区别是,管理员用户的 authorized_keys
文件不在用户配置文件目录中的 .ssh
文件夹中,而是在 C:\ProgramData\ssh\administrators_authorized_keys
中。可以通过删除或注释 C:\ProgramData\ssh\sshd_config
中的行,然后重启 sshd
服务,将管理员用户的 authorized_keys
文件的位置更改回用户配置文件目录。
Match Group administrators
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
SSH 密钥可与本地帐户和域帐户一起使用,但会受到双跳问题的困扰。这意味着当使用 SSH 密钥身份验证与 Ansible 时,远程会话将无权访问用户凭据,并且在尝试访问网络资源时将失败。要解决此问题,您可以在任务中使用 become,使用需要访问远程资源的用户凭据。
GSSAPI 身份验证
GSSAPI 身份验证将使用 Kerberos 对 Windows 主机进行用户身份验证。要将 GSSAPI 身份验证与 Ansible 一起使用,必须通过编辑 C:\ProgramData\ssh\sshd_config
文件配置 Windows 服务器以允许 GSSAPI 身份验证。添加以下行或编辑现有行
GSSAPIAuthentication yes
编辑完成后,使用 Restart-Service -Name sshd
重启 sshd
服务。
在 Ansible 控制节点上,您需要安装 Kerberos 并将其配置为 Windows 主机所属的域。如何设置和配置不在本文档的范围内。配置 Kerberos 领域后,您可以使用 kinit
命令获取您正在连接的用户的票证,并使用 klist
验证哪些票证可用
> kinit [email protected]
Password for [email protected]
> klist
Ticket cache: KCM:1000
Default principal: [email protected]
Valid starting Expires Service principal
29/08/24 13:54:51 29/08/24 23:54:51 krbtgt/[email protected]
renew until 05/09/24 13:54:48
获得有效的票证后,您可以使用 ansible_user
主机变量指定 UPN 用户名,当使用 SSH 时,Ansible 将自动使用该用户的 Kerberos 票证。
还可以通过 GSSAPI 身份验证启用不受约束的委派,使 Windows 节点访问网络资源。要使 GSSAPI 委派工作,由 kinit
检索的票证必须是可转发的,并且必须使用 -o GSSAPIDelegateCredentials=yes
选项调用 ssh
。要检索可转发的票证,请将 -f
标志与 kinit
一起使用,或者在 /etc/krb5.conf
文件中的 [libdefaults]
下添加 forwardable = true
。
> kinit -f [email protected]
Password for [email protected]
# -f will show the ticket flags, we want to see F
> klist -f
Ticket cache: KCM:1000
Default principal: [email protected]
Valid starting Expires Service principal
29/08/24 13:54:51 29/08/24 23:54:51 krbtgt/[email protected]
renew until 05/09/24 13:54:48, Flags: FRIA
GSSAPIDelegateCredentials=yes
选项可以在 ~/.ssh/config
文件中设置,也可以作为清单中的主机变量设置
ansible_ssh_common_args: -o GSSAPIDelegateCredentials=yes
与 psrp
或 winrm
连接插件不同,当提供显式用户名和密码时,SSH 连接插件无法获取 Kerberos TGT 票证。这意味着用户必须在运行 playbook 之前拥有有效的 Kerberos 票证。
有关如何配置、使用和排除 Kerberos 身份验证故障的更多信息,请参阅 Kerberos 身份验证。
密码身份验证
密码身份验证是最不安全的身份验证方法,不建议使用。但是,可以使用密码身份验证与 Windows SSH 一起使用。要将密码身份验证与 Ansible 一起使用,请在清单文件或 playbook 中设置 ansible_password
变量。使用密码身份验证需要在 Ansible 控制节点上安装 sshpass
软件包。
密码身份验证的工作方式类似于 WinRM CredSSP 身份验证,其中用户名和密码被赋予 Windows 主机,并且它将执行不受约束的委派以访问网络资源。