在和windows server通信前
ansible主機條件
如果使用ansible和windows通信和使用windows模塊的話,需要滿足以下條件:
1,ansible目前可以在微軟的支持或者擴展支持下管理windows版本。ansible可以管理的桌面系統包括win7,8.1,10。server系統包括server 2008,2008 R2, 2012 R2,2016和2019
2,ansible需要PowerShell 3.0和.NET 4.0以上才可以安裝上
3,WinRM 監聽需要被創建或者激活,詳情如下:
注意:這些是ansible連接的基本需求,部分ansible模塊需要額外的需求,比如更新版本的操作系統或者PowerShell版本。詳情查看官方文檔。
powershell & .NET 升級 (暫略)
powershell 查看版本:$PSVersionTable
or get-host
PS 3.0 會有點bug.
WinRM設置
一旦PowerShell被升級到最新3.0版本,還需要配置WinRM來使得Ansible能夠連接主機。WinRM有兩個主要的組件來管理與ansible的通信接口。listener和service configuration settings.
腳本ConfigureRemotingForAnsible.ps1可以被用於一些基本設置。這個腳本設置了HTTP&HTTPS的自簽名Listener並且是能了服務里的Basic認證選項。
- 在執行這個腳本的時候如果遇到cannot be loaded because running scripts is disabled on this system這個錯誤,需要執行
Set-ExecutionPolicy RemoteSigned
。
如果使用ConfigureRemotingForAnsible.ps1這個腳本,執行以下腳本:
$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
有兩個參數(like -EnableCredSSP and -ForceNewSSLCert)能夠在這個腳本中設置,這個腳本的上面有介紹。
這個ConfigureRemotingForAnsible.ps1腳本是用來培訓和實驗的目的並且不應該用於生產環境, 因為它使能的設置(比如Basic認證)本身就不安全。
WinRM Listener
WinRM監聽一個或多個端口的請求,每個端口必須有一個listener創建和配置。
可以通過以下命令查看WinRM服務listener的運行情況。
winrm enumerate winrm/config/Listener
會有類似如下的輸出:
Listener
Address = *
Transport = HTTP
Port = 5985
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0.2.15%6, fe80::5efe:192.168.56.155%8, fe80::
ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7
Listener
Address = *
Transport = HTTPS
Port = 5986
Hostname = SERVER2016
Enabled = true
URLPrefix = wsman
CertificateThumbprint = E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE
ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0.2.15%6, fe80::5efe:192.168.56.155%8, fe80::
ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7
在這個例子中有兩個listener被激活,一個是監聽HTTP 5985,另一個是HTTPS 5986。里面一些重要的配置選項:
Transport
: 推薦使用listener over HTTPS的方式,因為數據會被加密並且不需要其他配置。Port
: linstener監聽的端口,默認是5985 HTTP & 5986 HTTPS,這個端口可以按需更改,ansible端也改相應的主機變量ansible_port就可。URLPrefix
: 監聽的URL,默認是wsman。如果這個被改了,那么相應的ansible端的ansible_winrm_path也做相應更改。CertificateThumbprint
: 如果listener運行在HTTPS上,這個是windows Certificate Store的指紋用於創建連接。通過在PS中運行以下帶着指紋的命令可以得到這個認證的詳細信息:
$thumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE"
Get-ChildItem -Path cert:\LocalMachine\My -Recurse | Where-Object { $_.Thumbprint -eq $thumbprint } | Select-Object *
設置WinRM Listener
有三種方法設置WinRM listener:
- 使用
winrm quickconfig
配置HTTP或者winrm quickconfig -transport:https
配置HTTPS。這個是運行在域環境外一個linstener情況下最簡單的配置方式。這個過程還有一個好處就是可以自動為相應端口打開防火牆並且啟動WinRM服務。 - 使用組策略對象的情況。這個是最好的方式去創建一個Listener,在主機是域成員的時候。因為所有的配置都被自動配置好了並且不需要其他的輸入。關於組策略對象的信息,可以查看相關文檔。
- 使用powershell去創建一個特別的配置,這個過程可以通過以下的powershell命令去實現:
$selector_set = @{
Address = "*"
Transport = "HTTPS"
}
$value_set = @{
CertificateThumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE"
}
New-WSManInstance -ResourceURI "winrm/config/Listener" -SelectorSet $selector_set -ValueSet $value_set
powershell其他的命令可以參考:New-WSManInstance.
注:當創建一個HTTPS listener,需要有證書在LocalMachine\My
cerificate store里,否則大部分的命令都不會成功。
刪除WinRM Listener
- 刪除所有的listeners
Remove-Item -Path WSMan:\localhost\Listener\* -Recurse -Force
- 只刪除跑在HTTPS上的listeners
Get-ChildItem -Path WSMan:\localhost\Listener | Where-Object { $_.Keys -contains "Transport=HTTPS" } | Remove-Item -Recurse -Force
注:Keys
是一個字符串數組,所以可以包含不同的值。默認下Transport=
和Address=
包含的值對應着winrm/config/Listeners
中的值。
WinRM服務選項
有一系列的選項來配置WINRM服務組件,包含認證選項和內存設置。
使用這個命令來查看服務已配置選項:
winrm get winrm/config/Service
winrm get winrm/config/Winrs
然后會有一些類似下面的輸出:
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = false
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = true
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
Winrs
AllowRemoteShellAccess = true
IdleTimeout = 7200000
MaxConcurrentUsers = 2147483647
MaxShellRunTime = 2147483647
MaxProcessesPerShell = 2147483647
MaxMemoryPerShellMB = 2147483647
MaxShellsPerUser = 2147483647
雖然這些選項一般都很少更改,但是有一少部分能夠很簡單的影響winRM的運行並且有助於理解。
一些重要的選項:
Service\AllowUnencrypted:
這個選項決定了WinRM是否允許流量在沒有數據加密的HTTP下通過。信息只有在ansible_winrm_transport
選項是ntlm
,kerberos
或者credssp
的條件下才可以進行加密。默認情況下這個選項是true
,在調試WinRM消息的時候可以置位false
。Service\Auth\*:
這個標志位定義了認證選項是否被WinRM服務允許。默認情況下,Negotiate (NTLM)
和kerberos
是打開的。Service\Auth\CbtHardeningLevel:
_指定是否隧道綁定令牌沒有被驗證(None),驗證了但是不是必需的(Relaxed),或者是必須要被驗證的(Strict)。CBT(Channel Binding Token)只用在NTML和kerberos over HTTPS情況下。Service\CertificateThumbprint:
這是用於加密與CredSSP身份驗證一起使用的TLS通道的證書的指紋。默認情況下為空。當WinRM啟動的時候,一個自簽名證書被生成並且被用於TLS過程中。Winrs\MaxShellRunTime:
這是遠程命令被執行的最大時間,單位是毫秒。Winrs\MaxMemoryPerShellMB:
這是最大This is the maximum amount of memory allocated per shell, including the shell’s child processes.
Powershell下修改Service
設置的值:
# 替換winrm/config/Service后面的路徑{path}
Set-Item -Path WSMan:\localhost\Service\{path} -Value "value here"
# 例如, 啟動Service\Auth\CbtHardeningLevel
Set-Item -Path WSMan:\localhost\Service\Auth\CbtHardeningLevel -Value Strict
PowerShell下修改winrs
的值:
# 替換winrm/config/Winrs后面的路徑{path}
Set-Item -Path WSMan:\localhost\Shell\{path} -Value "value here"
# 例如,啟動Winrs\MaxShellRunTime
Set-Item -Path WSMan:\localhost\Shell\MaxShellRunTime -Value 2147483647
注:如果主機運行在域環境下的時候,一些選項被設置在組策略對象下,主機不能自己改動。如果設置是由組策略下發的,那么它會在value旁邊有[Source="GPO"]
的提示。
Windows SSH設置
Ansible 2.8為Windows主機添加了實驗性的SSH連接.
注:使用這個特性需要后果自負。在WINDOWS下使用SSH只是實驗性的,該功能在以后版本中可能不是向下兼容的。服務器端的組件是否能使用取決於ansible的版本。
安裝Win32-OpenSSH
第一步是安裝Win32-OpenSSH
到windows主機上。微軟提供的安裝方式對ansible來說太舊了。應該采用以下方式:
- 手動安裝服務,參考微軟官方文檔
- 使用
win_chocolatey
安裝
- name: install the Win32-OpenSSH service
win_chocolatey:
name: openssh
package_params: /SSHServerFeature
state: present
- 使用Ansible Galaxy role,比如jborean93.win_openssh:
# 需要先把role下載下來
# main.yml
- name: install Win32-OpenSSH service
hosts: windows
gather_facts: no
roles:
- role: jborean93.win_openssh
opt_openssh_setup_service: True
注:Win32-OpenSSH
仍然是一個持續更新改進的測試產品,如果你使用SSH作為和windows的交互選項,強烈建議你使用以上三種方式來安裝最新的版本。
配置Win32-OpenSSH
默認Win32-OpenSSH
會使用cmd.exe
作為shell,如果使用其他shell,用ansible任務去定義注冊表設置:
- name: set the default shell to PowerShell
win_regedit:
path: HKLM:\SOFTWARE\OpenSSH
name: DefaultShell
data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
type: string
state: present
# Or revert the settings back to the default, cmd
- name: set the default shell to cmd
win_regedit:
path: HKLM:\SOFTWARE\OpenSSH
name: DefaultShell
state: absent
Win32-OpenSSH認證
Win32-OpenSSH認證方式和linux上的相似。你可以使用純文本的密碼或者SSH公鑰,把公鑰添加用戶文件目錄下.ssh
文件夾的authorized_key
中。然后在sshd_config
文件中配置SSH服務,和在Linux中使用方式一樣。
當使用SSH密鑰驗證時,遠程會話沒有用戶的證書並且在嘗試連接網絡資源時會失敗,這個是已知的多跳或者credential delegation問題。有兩種解決方式:
- 設置
ansible_password
,使用明文密碼認證 - 在需要訪問遠程資源的用戶認證里使用
become
選項在任務里。
配置ansible端
使用ssh和windows交互需要配置兩個連接變量:
ansible_connection
置為ssh
ansible_shell_type
置為cmd
或者powershell
ansible_shell_type
變量需要和windows主機上的DefaultShell
相對應。如果DefaultShell
是默認,那就設置為cmd
,如果是Powershell就設置成powershell
SSH和windows結合的已知問題
windows上的SSH只是實驗環境,下面是一些已知問題:
- Win32-OpenSSH在版本
v7.9.0.0p1-Beta
之前的,不能使用powershell
作為shell類型。 - 雖然SCP可能好使,但是SFTP是文件傳輸或者編碼下載文件時的推薦方式。