Sửa lỗi Ansible WinRM SSL: HTTPSConnectionPool Max Retries Exceeded trên cổng 5986

intermediate🔧 Ansible2026-05-11| Ansible 2.9+, Python 3.x, Windows Server 2016/2019/2022, WinRM qua HTTPS (cổng 5986)

Error Message

fatal: [win_host]: UNREACHABLE! => {"msg": "ssl: HTTPSConnectionPool(host='192.168.1.10', port=5986): Max retries exceeded with url: /wsman"}
#ansible#winrm#windows#ssl#kết nối#https

Nguyên nhân gây ra lỗi này

Bạn chạy một Ansible playbook nhắm vào Windows host và nhận được thông báo:

fatal: [win_host]: UNREACHABLE! => {"msg": "ssl: HTTPSConnectionPool(host='192.168.1.10', port=5986): Max retries exceeded with url: /wsman"}

Kết nối chưa kịp thiết lập đã thất bại. Thường có ba nguyên nhân: cổng chưa mở, SSL handshake bị lỗi, hoặc Ansible không tin tưởng certificate. Xác định trường hợp phù hợp với bạn và thực hiện theo các bước bên dưới.

Nguyên nhân gốc rễ

  • WinRM HTTPS listener chưa được cấu hình trên Windows host
  • Cổng 5986 bị chặn bởi Windows Firewall hoặc firewall mạng phía trước
  • Self-signed certificate không được Ansible tin tưởng (thiếu validate_certs: false)
  • Gói pywinrm chưa cài hoặc phiên bản quá cũ trên Ansible controller
  • Sai ansible_winrm_transport hoặc các biến kết nối trong inventory

Cách sửa nhanh: tắt xác thực certificate để kiểm tra

Hầu hết môi trường lab nội bộ và staging đều dùng self-signed certificate. Mặc định, Ansible sẽ từ chối các kết nối như vậy. Thêm các dòng sau vào inventory hoặc group_vars để bỏ qua xác thực certificate trong lúc chẩn đoán:

[windows:vars]
ansible_user=Administrator
ansible_password=YourPassword
ansible_connection=winrm
ansible_winrm_scheme=https
ansible_port=5986
ansible_winrm_transport=ntlm
ansible_winrm_server_cert_validation=ignore

Sau đó chạy thử kiểm tra kết nối nhanh:

ansible win_host -m win_ping

Nếu thành công, SSL certificate chính là thủ phạm — không có gì khác. Hãy bỏ qua và đến phần sửa vĩnh viễn bên dưới.

Bước 1: Kiểm tra xem WinRM có đang chạy không

Kết nối RDP hoặc console vào máy Windows và chạy các lệnh sau trong PowerShell:

Get-Service WinRM
winrm enumerate winrm/config/listener

Bạn cần thấy một listener hiển thị Transport=HTTPS trên cổng 5986. Nếu kết quả chỉ thấy HTTP trên cổng 5985, tức là HTTPS listener chưa được thiết lập.

Khởi tạo WinRM HTTPS với self-signed cert chỉ trong một bước:

# Run on the Windows host as Administrator
$cert = New-SelfSignedCertificate -DnsName "$(hostname)" -CertStoreLocation Cert:\LocalMachine\My
$thumbprint = $cert.Thumbprint
New-WSManInstance -ResourceURI winrm/config/listener `
  -SelectorSet @{Address="*"; Transport="HTTPS"} `
  -ValueSet @{CertificateThumbprint=$thumbprint}

# Prefer the Ansible-maintained setup script instead:
$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

Script của Ansible xử lý việc tạo cert, thiết lập listener và cấu hình firewall chỉ trong một lần — rất đáng dùng nếu bạn cần cài đặt cho nhiều host.

Bước 2: Mở cổng 5986 trong Windows Firewall

New-NetFirewallRule -DisplayName "Ansible WinRM HTTPS" `
  -Direction Inbound `
  -Protocol TCP `
  -LocalPort 5986 `
  -Action Allow

Đang chạy trên AWS, Azure, hoặc GCP? Đừng quên security group hoặc NSG — các quy tắc Windows Firewall sẽ vô nghĩa nếu tầng cloud đang chặn lưu lượng ở cấp VPC.

Từ Ansible controller, kiểm tra xem cổng 5986 có thực sự kết nối được không:

nc -zv 192.168.1.10 5986
# or
curl -k https://192.168.1.10:5986/wsman

Chỉ cần curl trả về HTTP 401 hoặc 500 là cổng đã mở và WinRM đang hoạt động. Nếu bị từ chối kết nối hoặc timeout thì firewall vẫn đang chặn.

Bước 3: Cài pywinrm trên Ansible controller

Không có pywinrm thì không thể kết nối WinRM — Ansible cần gói này để giao tiếp theo giao thức này:

pip install pywinrm
pip install pywinrm[kerberos]   # domain environments using Kerberos
pip install pywinrm[credssp]    # if using CredSSP auth

Xác nhận đã cài và kiểm tra phiên bản (cần từ 0.4.x trở lên):

pip show pywinrm

Sửa vĩnh viễn: tin tưởng certificate của Windows host

Đưa server_cert_validation=ignore lên môi trường production là một ý tưởng tồi. Nó mở ra nguy cơ tấn công man-in-the-middle vào hệ thống tự động hóa của bạn. Cách sửa thực sự là xuất certificate của Windows host và thêm vào kho tin tưởng trên Ansible controller.

Trên Windows host, xuất certificate:

$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -match "$(hostname)"}
Export-Certificate -Cert $cert -FilePath C:\winrm_cert.cer -Type CERT

Sao chép winrm_cert.cer sang Ansible controller (qua scp, SMB share, hay bất kỳ cách nào bạn có), rồi chuyển đổi và cài đặt:

# Convert .cer (DER format) to PEM
openssl x509 -inform DER -in winrm_cert.cer -out winrm_cert.pem

# Ubuntu/Debian
cp winrm_cert.pem /usr/local/share/ca-certificates/winrm_cert.crt
update-ca-certificates

# RHEL/CentOS
cp winrm_cert.pem /etc/pki/ca-trust/source/anchors/
update-ca-trust extract

Sau đó cập nhật inventory để xác thực đúng cách:

[windows:vars]
ansible_winrm_server_cert_validation=validate
ansible_winrm_ca_trust_path=/path/to/winrm_cert.pem

Tham khảo: inventory hoàn chỉnh

Đây là inventory đầy đủ hoạt động với NTLM qua HTTPS — hãy sao chép và chỉnh sửa theo nhu cầu:

[windows]
win_host ansible_host=192.168.1.10

[windows:vars]
ansible_user=Administrator
ansible_password=YourSecurePassword
ansible_connection=winrm
ansible_winrm_scheme=https
ansible_port=5986
ansible_winrm_transport=ntlm
ansible_winrm_server_cert_validation=ignore

Host đã tham gia domain với Active Directory? Chuyển sang Kerberos — bảo mật hơn và xử lý token delegation đúng cách:

ansible_winrm_transport=kerberos
ansible_user=user@DOMAIN.COM

Kiểm tra sau khi sửa

Bắt đầu với win_ping — bài kiểm tra kết nối ít tốn tài nguyên nhất mà Ansible có cho Windows:

ansible win_host -m win_ping

Kết quả mong đợi:

win_host | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Sau khi ping thành công, chạy một lệnh thực tế để xác nhận toàn bộ hệ thống hoạt động đầu cuối:

ansible win_host -m win_shell -a "Get-ComputerInfo | Select-Object WindowsProductName"

Vẫn thấy lỗi SSL sau tất cả những bước trên? Tăng mức độ chi tiết lên bốn và lọc trace của quá trình handshake:

ansible win_host -m win_ping -vvvv 2>&1 | grep -i ssl

Kết quả handshake sẽ cho bạn biết chính xác nơi thất bại — CN của certificate không khớp, cert hết hạn, CA không được tin tưởng, v.v.

Related Error Notes