Introduction
I have started learning Ansible with the help of various blogs and Pluralsight videos. My focus is on using Ansible to configure Windows.
Ansible uses WinRM to connect to Windows servers and I was having some trouble connecting from my CentOS Ansible VM to either Windows 2012 R2 or 2016 that were standalone servers, so Workgroup and not joined to Active Directory.
After too many attempts to get Ansible to connect to the 2012 R2 VM I thought I would document how to get the connection going.
Environment
This has been tested with the following:
- Ansible 2.7.4 running on CentOS 7. Server is called ansible
- Target server of Windows Server 2012 R2 fully patched. No configuration changes made to the OS. Server is called control
- Target server of Windows Server 2016 fully patched. No configuration changes made to the OS. Server is called server2
- All VMs nested in VMware Workstation 15. NAT on the NIC and Workstation handling DHCP
- Confirmed I can ping the two Windows servers from CentOS by name
Ansible has been setup with a simple inventory file:
—
[servers]
server1
server2
Then the variables for connecting to the Windows servers:
ansible_user: Administrator
ansible_password: “Password1”
ansible_port: 5985
ansible_connection: winrm
So connect to Windows over WinRM on port 5985 using the username/password of Administrator/Password
Initial Test
To test functionality I am going to use the Ansible module win_ping. As the documentation says this simply checks management connectivity of a windows host.
Running ansible gives the following result:
[ansible@control]$ ansible servers -i inventory.yml -m win_ping
server1 ¦ UNREACHABLE! => {
“changed”: false,
“msg”: “plaintext: the specified credentials were rejected by the server”,
“unreachable”: true
}
server2 ¦ UNREACHABLE! => {
“changed”: false,
“msg”: “plaintext: the specified credentials were rejected by the server”,
“unreachable”: true
}
So something is wrong here. It’s not the credentials as I know they are correct. It must be some other authentication issue.
The Solution
The root of the problem is that we are sending credentials in plaintext over the unencrypted WinRM port 5985. As this was a lab I just wanted to easily test, so I was willing to do this. Do not do this in production!
The fix is a couple of WinRM configuration changes in the Windows servers. In an elevated command prompt type the following commands:
C:\Windows\system32>winrm set winrm/config/service/auth ‘@{Basic=”true”}’
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
C:\Windows\system32>winrm set winrm/config/service ‘@{AllowUnencrypted=”true”}’
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 = true
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
The first command sets WinRM to Basic Authentication and the second allows unencrypted traffic.
Running Ansible again:
[ansible@control]$ ansible servers -i inventory.yml -m win_ping
server1 ¦ SUCCESS! => {
“changed”: false,
“ping”: “pong”
}
server2 ¦ SUCCESS! => {
“changed”: false,
“ping”: “pong”
}
We can now access the servers over WinRM.
Wrap Up
As I said above this is not how to run this in production. Normally you would use encrypted traffic to a domain joined server using a proper authentication method such as Kerberos or CredSSP.
In the next post I am going to look at further authentication options for Ansible and WinRM.
来自 <https://www.vgemba.net/ansible/Ansible-WinRM-Workgroup/>
Ansible管理Windows
winserver2019 | UNREACHABLE! => {
“changed”: false,
“msg”: “plaintext: the specified credentials were rejected by the server”,
“unreachable”: true
}
>winrm get winrm/config
Config
MaxEnvelopeSizekb = 500
MaxTimeoutms = 60000
MaxBatchItems = 32000
MaxProviderRequests = 4294967295
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false
Auth
Basic = true
Digest = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts
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 = false
CredSSP = false
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 set winrm/config/service ‘@{AllowUnencrypted=”true”}’
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 = true
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
# ansible winserver2019 -m win_ping
winserver2019 | SUCCESS => {
“changed”: false,
“ping”: “pong”
}