如何实现ansible到windows的免密

文章导读
Ansible 管理 Windows 默认使用 WinRM 协议而非 SSH,因此原生不支持 SSH 密钥免密,若需实现类似体验需配置 Kerberos 认证、证书认证或在 Windows 上安装 OpenSSH 服务。
📋 目录
  1. 前置准备:Inventory 配置示例
  2. 命令速用版
  3. 为什么会这样
  4. 分步处理
  5. 怎么验证是否生效
  6. 常见坑
  7. 参考来源
A A

Ansible 管理 Windows 默认使用 WinRM 协议而非 SSH,因此原生不支持 SSH 密钥免密,若需实现类似体验需配置 Kerberos 认证、证书认证或在 Windows 上安装 OpenSSH 服务。

先说结论:Windows 默认不开启 SSH 服务,Ansible 通过 WinRM 连接,要实现免密需根据环境选择 Kerberos、证书或 OpenSSH 方案。

  • 适合:域环境首选 Kerberos,独立主机可选证书或 OpenSSH
  • 先准备:确认 Windows 开启 WinRM 服务或安装 OpenSSH Server
  • 验收:使用 ansible -m win_ping 测试连通性与认证方式

前置准备:Inventory 配置示例

无论选择哪种方案,都需要在 inventory 文件中正确定义主机变量。以下是三种方案的配置对照,请根据实际方案修改 inventory.ini:

[windows_hosts]
# 方案一:Kerberos (域环境)
win-host-kerb ansible_connection=winrm ansible_user=administrator@EXAMPLE.COM

# 方案二:证书认证 (独立主机 HTTPS)
win-host-cert ansible_connection=winrm ansible_user=administrator ansible_winrm_transport=cert ansible_winrm_cert_cert_pem=/path/to/client.pem ansible_winrm_cert_key_pem=/path/to/client.key

# 方案三:OpenSSH (最接近 Linux 体验)
win-host-ssh ansible_connection=ssh ansible_user=administrator ansible_ssh_private_key_file=~/.ssh/id_rsa

命令速用版

如果你希望在 Linux 控制端直接测试连通性,可使用以下命令检查当前配置并尝试连接。注意以下命令假设你已经完成了基础的 WinRM 或 SSH 配置。

ansible windows_host -m win_ping -i inventory.ini -u Administrator -k

若已配置免密(如 Kerberos 票据或 SSH 密钥),则不需要 -k 参数。对于 WinRM 连接,查看当前连接插件配置:

ansible-config dump | grep -i winrm

为什么会这样

Linux 主机之间通常使用 SSH 协议,支持公钥/私钥认证,因此可以实现“免密”。但 Ansible 管理 Windows 默认使用 WinRM(Windows Remote Management)协议,该协议设计之初主要依赖 Kerberos、NTLM 或证书认证,原生并不支持 SSH 密钥对。

这意味着如果你直接在 Windows 上生成 SSH 密钥并放入 authorized_keys,但 Ansible 仍使用默认的 winrm 连接插件,免密不会生效。要实现免密,要么在 WinRM 层面配置 Kerberos 或证书认证,要么在 Windows 上安装 OpenSSH 服务器并切换 Ansible 连接插件为 ssh。

分步处理

方案一:WinRM + Kerberos(适合域环境)

1. 确保控制端 Linux 已安装 Kerberos 相关包。建议在使用 Ansible 的 Python 环境中安装:

pip install pykerberos
系统层面可安装 krb5-user(Debian/Ubuntu)或 krb5-workstation(RHEL/CentOS)。

2. 配置 /etc/krb5.conf,确保 realm 和 kdc 指向正确的域控制器。参考配置如下:

[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = false

[realms]
EXAMPLE.COM = {
    kdc = dc.example.com
    admin_server = dc.example.com
}

3. 在 Linux 上获取票据:

kinit administrator@EXAMPLE.COM

4. 在 Ansible inventory 中设置 ansible_connection=winrm,ansible_user 为用户主体,无需填写密码。

方案二:WinRM + 证书认证(适合独立主机)

1. 在 Windows 上创建自签名证书并绑定到 WinRM 监听器(HTTPS)。

2. 将公钥导出并放置在 Linux 控制端。

如何实现ansible到windows的免密

3. 在 Ansible 配置中指定证书路径和密钥路径,关键变量如下:

  • ansible_winrm_transport=cert
  • ansible_winrm_cert_cert_pem=/path/to/client_cert.pem
  • ansible_winrm_cert_key_pem=/path/to/client_key.pem

方案三:Windows 安装 OpenSSH(最接近 Linux 体验)

1. 以管理员身份运行 PowerShell,安装 OpenSSH 服务器功能:

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

2. 启动 SSH 服务并设置开机自启:

Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'

3. 将 Linux 控制端的公钥写入 Windows 用户目录下的 authorized_keys(通常位于 C:\ProgramData\ssh\administrators_authorized_keys)。

4. 在 Ansible inventory 中设置 ansible_connection=ssh,ansible_ssh_private_key_file 指向私钥路径。

怎么验证是否生效

执行 ping 模块测试,观察是否需要输入密码或是否报错认证失败。

ansible all -m win_ping -v

如果配置成功,输出应显示 SUCCESS 且无密码提示。若使用 OpenSSH 方案,可添加 -vvv 查看调试信息,确认连接插件为 ssh 而非 winrm。

检查 Windows 端服务状态:

Get-Service WinRM
Get-Service sshd

常见坑

1. 协议混淆:安装了 OpenSSH 但 inventory 未改 connection 插件,Ansible 仍会尝试 WinRM 导致失败。

2. 加密配置:WinRM 默认可能只允许 HTTP,生产环境建议配置 HTTPS,否则 Ansible 需设置 ansible_winrm_server_cert_validation=ignore

3. 权限问题:Windows 用户必须有远程管理权限,Administrator 账户默认启用策略需检查。

4. 防火墙:WinRM 默认端口 5985/5986,SSH 默认 22,需确保网络可达。

5. 依赖包差异:Kerberos 方案中,确保 Python 环境安装了 pykerberos,仅安装系统包可能无法被 Ansible 调用。

参考来源

  • Ansible 官方文档,Windows Remote Management,https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html
  • Microsoft Learn,OpenSSH 安装与配置,https://learn.microsoft.com/zh-cn/windows-server/administration/openssh/openssh_install_firstuse