[Ansible] Windows 連線設定 (basic、certificate authentication)

Ian Hsiao
Ianyc
Published in
11 min readOct 4, 2019

根據官方資料,目前為止 Ansible 控制端 - control node,只能安裝於 Linux 系統,

但是被控制端 (managed node) 可以是 Linux 或 Windows 系統。

只不過 Windows 端必須啟動 WinRM 以及修改一些設定,才能讓 control node 順利連接。

以下分享我的連線配置設定,將分別介紹 basic 以及 certificate authentication。其中測試環境為:

  • Control node: Centos 7.6.1810
  • Managed node: Windows server 2012 R2 (requirement: PowerShell version ≥ 3.0、.NET Framework ≥ 4.0,windows 2012 預設是符合的)
  • Ansible version: 2.7.9

Basic Authentication

  • Control node setup:
  1. 安裝 pywinrm ≥ 0.3.0: https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html#what-is-winrm
  • Managed node setup:
  1. 將官網提供的 ConfigureRemotingForAnsible.ps1 下載到 managed node。(ex: download to C:\ConfigureRemotingForAnsible.ps1。ConfigureRemotingForAnsible.ps1 script 請參考 https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html#winrm-setup)
  2. 以系統管理員身分執行 PowerShell ,
  3. 進入 ConfigureRemotingForAnsible.ps1 檔案存放目錄並執行以下命令:
> cd C:\C:\> powershell -ExecutionPolicy RemoteSigned .\ConfigureRemotingForAnsible.ps1 -SkipNetworkProfileCheck

4. 確認 basic authentication service 是否為 true:

C:\> winrm get winrm/config/Service

5. 接著只要在 control node 的 hosts file 編輯主機資訊:

[host_group]
host_IP
[host_group:vars]
ansible_user=remote_login_user
ansible_connection=winrm
ansible_winrm_transport=basic
ansible_winrm_server_cert_validation=ignore
ansible_port=5986

即完成 Basic Authentication 連線設定。

6. 測試連線:

$ ansible host_group -m win_ping -k
連線成功,回應 “ping”: “pong”

Certificate Authentication

  • Control node setup:
  1. 首先安裝 pywinrm ≥ 0.3.0 (same as basic authentication): https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html#what-is-winrm
  2. 接著執行下列指令產生 certificate (OpenSSL method):
$ USERNAME="username"    //username請填要登入managed node的使用者名稱$ cat > openssl.conf << EOL
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req_client]
extendedKeyUsage = clientAuth
subjectAltName = otherName:1.3.6.1.4.1.311.20.2.3;UTF8:$USERNAME@localhost
EOL
$ export OPENSSL_CONF=openssl.conf$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -out cert.pem -outform PEM -keyout cert_key.pem -subj "/CN=$USERNAME" -extensions v3_req_client$ rm openssl.conf
  • Managed node setup:
  1. 將上面步驟產生的 cert.pem 複製到 managed node (ex: copy to C:\cert.pem)
  2. 將官網提供的 ConfigureRemotingForAnsible.ps1 下載到 managed node。(ex: download to C:\ConfigureRemotingForAnsible.ps1。ConfigureRemotingForAnsible.ps1 script 請參考 https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html#winrm-setup)
  3. 以系統管理員身分執行 PowerShell 並進入 cert.pem 與 ConfigureRemotingForAnsible.ps1 檔案存放目錄 (範例為 C:\),並依序執行以下命令:
C:\> powershell -ExecutionPolicy RemoteSigned .\ConfigureRemotingForAnsible.ps1 -SkipNetworkProfileCheckC:\> Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $false     //關閉basic authentication (recommended)C:\> Get-ChildItem -Path WSMan:\localhost\Listener | Where-Object { $_.Keys -contains "Transport=HTTP" } | Remove-Item -Recurse -Force     //移除HTTP listener,留HTTPS listener (optional)C:\> Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true     //啟動certificate authentication (optional)C:\> $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2

C:\> $cert.Import("C:\cert.pem")

C:\> $store_name = [System.Security.Cryptography.X509Certificates.StoreName]::Root

C:\> $store_location = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine

C:\> $store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location

C:\> $store.Open("MaxAllowed")

C:\> $store.Add($cert)

C:\> $store.Close()

C:\> $store_name = [System.Security.Cryptography.X509Certificates.StoreName]::TrustedPeople

C:\> $store_location = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine

C:\> $store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location

C:\> $store.Open("MaxAllowed")

C:\> $store.Add($cert)

C:\> $store.Close()

C:\> $username = "username" //username為windows managed noed之ansible user用戶名

C:\> $password = ConvertTo-SecureString -String "password" -AsPlainText -Force //password為windows managed noed之ansible user password

C:\> $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password

C:\> $thumbprint = (Get-ChildItem -Path cert:\LocalMachine\root | Where-Object { $_.Subject -eq "CN=$username" }).Thumbprint

C:\> New-Item -Path WSMan:\localhost\ClientCertificate `
-Subject "$username@localhost" `
-URI * `
-Issuer $thumbprint `
-Credential $credential `
-Force

4. 輸入完畢後若看到下列訊息代表憑證 mapping 成功:

WSManConfig: Microsoft.WSMan.Management\.....
Type Keys Name
---- ---- ----
Container {URI=*,Issuer=..... ClientCertificate_.....

5. 確認 service configuration 資訊:

C:\> winrm get winrm/config/ServiceC:\> winrm get winrm/config/Winrs

6. 在 control node 的 hosts file 編輯主機資訊:

[host_group]
host_IP
[host_group:vars]
ansible_user=remote_login_user
ansible_connection=winrm
ansible_winrm_transport=certificate
ansible_winrm_server_cert_validation=ignore
ansible_port=5986
ansible_winrm_cert_pem=/path/to/cert.pem
ansible_winrm_cert_key_pem=/path/to/cert_key.pem

7. 測試連線:

$ ansible host_group -m win_ping

若回應 “ping”: ”pong” 則連線成功 !

註: certificate 連線設定完成後可將 managed node 裡的 cert.pem 及 ConfigureRemotingForAnsible.ps1 檔案刪除,不影響後續 Ansible 操作。

--

--