Ansible + Windows - Beating the second hop with CredSSP |

March 20, 2017

Ansible + Windows - Beating the second hop with CredSSP

WinRM - Transport protocols

As I alluded to in my previous post, there are a number of different transport protocols to use with winrm, and it was quite good fortune that the docs had caught up as I was playing with them all. The last one on my list was CredSSP, which is probably the best authentication method in my mind!


CredSSP is a transport protocol that allows us to overcome the ‘second hop’ problem of authenticating to a remote resource from the target server. This means that we can authenticate from Server A, to ‘Server B’, and then delegate the credentials to further servers for whatever means. Please note, all information regarding CredSSP below also applies to PowerShell remoting as well as Ansible!

For example:

               auths ✓                  delegate creds ✓
                                             .-----------> active directory
Server A ------------------> Server B  ------------------> remote file share
                                             '-----------> Server C

Because CredSSP works with local accounts, active directory accounts, has no annoying setup requirements like Kerberos and can delegate credentials… It’s pretty much the ideal protocol to use!

And if you like tables, here’s one from the Windows docs:

Option Local Accounts Active Directory Accounts Credential Delegation
Basic Yes No No
Certificate Yes No No
Kerberos No Yes Yes
CredSSP Yes Yes Yes


So, what’s the catch? Well we need to enable CredSSP to be used on each host before we can use it. Luckily for us, this is as simple as running a PowerShell cmdlet.

Setup - Ansible host

Firstly, to add CredSSP support, we need the pywinrm[credssp] python module (pip install pywinrm[credssp]). Next, change the the transport protocol for the host group - ansible_winrm_transport: "credssp".

Setup - Windows hosts

To support CredSSP on the actual Windows hosts, the easiest way without a doubt, is to use the Enable-WSManCredSSP cmdlet. This does the following:

Enables CredSSP on the client. The WS-Management setting \Client\Auth\CredSSP is set to true. Sets the Windows CredSSP policy AllowFreshCredentials to WSMan/Delegate on the client. Note: These settings allow the client to delegate explicit credentials to a server when server authentication is achieved. Source

CredSSP Client

Firstly, we must set up the host to allow delegation of credentials to other hosts. This is called being a CredSSP client, and when we do this, we have to specify what hosts we wish to allow delegation to.

Enable-WSManCredSSP -Role Client -DelegateComputer *.mydomain.local

The above makes use of the * wildcard, enabling delegation of credentials to any hosts that have the domain name mydomain.local Please note, if you use the above example, you will have to explicitly specify the domain name when you connect to the host, even if your DNS configuration automatically resolves it. Alternatively, we could allow, *srv*, or even * - But it’s generally best practice to limit this which hosts we can send potentially elevated credentials to.

CredSSP server

The other part to this is setting up host(s) as a CredSSP server.

Enable-WSManCredSSP -Role Server

This simply allows the host to receive delegated credentials. This time we don’t have to specify -DelegateComputer.

And obviously, we can Automate this setup by using NTLM initially then swapping over to CredSSP.

Ansible in Docker

Because I’m a sucker for Docker, I’ve thrown together a minimal Alpine-based image. This way I can just pull down the latest version and not worry about dependencies!

If you want to play, just docker run --it --name ansible -v ansible_config:/etc/ansible absolutejam/ansible /bin/ash.

© James Booth 2017