Repository: ansible/ansible
Pull request: document the required variables for using Windows certificates
##### SUMMARY

As originally stated in [this issue](https://github.com/ansible/ansible/issues/16243), there is no documentation on the variables to use when authenticating to Windows via WinRM using certificates.

There is also a long run-on sentence that I simplified.

Fixes #16243


##### ISSUE TYPE
 - Docs Pull Request


##### COMPONENT NAME
intro_windows documentation


##### ANSIBLE VERSION
2.4

Problem statement:
Client certificate authentication with WinRM needs documentation
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### ANSIBLE VERSION

<!--- Paste verbatim output from “ansible --version” between quotes below -->

v2.1
##### CONFIGURATION

<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

``` yaml
ansible_winrm_transport: certificate
ansible_winrm_cert_pem: /home/XXX/ansible/certs/winrm_client_cert.pem
ansible_winrm_cert_key_pem: /home/XXX/ansible/certs/winrm_client_cert.key
```
##### OS / ENVIRONMENT

<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->

RHEL 6.8
python-2.6.6
pywinrm-0.2.0
ansible-2.1.0.0
Windows 10
##### SUMMARY

<!--- Explain the problem briefly -->

I cannot make certificate authentication work with WinRM and Windows 10.

After generating the right files, adding them to the Certificate store on Windows 10 and providing them to Ansible/pywinrm I get the below error nevertheless:

```
[dag@moria crombeen]$ ansible-playbook -l windows1 certificate.yml 

PLAY [all] *********************************************************************

TASK [win_copy] ****************************************************************
Enter PEM pass phrase:
fatal: [windows1]: UNREACHABLE! => {"changed": false, "msg": "certificate: the specified credentials were rejected by the server", "unreachable": true}
        to retry, use: --limit @certificate.retry

PLAY RECAP *********************************************************************
windows1                   : ok=0    changed=0    unreachable=1    failed=0   
```

According to this page, this only works on Windows 10 when using certificates generated through
ADCS (Active Directory Certificate Services) and not OpenSSL. Since I do not have access to ADCS I cannot verify whether this is exactly the problem, or something else is wrong.

Hints from issue discussion:
Ansible/pywinrm cert auth are working just fine:

hosts

```
[win]
winclient-cert ansible_host=winclient.ansible.vagrant

[win:vars]
ansible_connection=winrm
ansible_winrm_transport=certificate
ansible_winrm_cert_pem=/Users/mdavis/Downloads/testguy_cert.pem
ansible_winrm_cert_key_pem=/Users/mdavis/Downloads/testguy_key.pem
ansible_winrm_server_cert_validation=ignore
```

```
(ansiblev2) mdavis-mac:win-domain mdavis$ ansible winclient-cert -i hosts -m win_ping
winclient-cert | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
```

I assume you're talking about [Matt Wrock's recent blog post on winrm cert auth](http://www.hurryupandwait.io/blog/certificate-password-less-based-authentication-in-winrm). I have  an OpenSSL-generated client cert, and it works fine. It's been awhile since I set up the receiving side from scratch (and I've since lost the OpenSSL CA config I used), but It's definitely possible to make it work- there's no magic there, X509 is X509. There's a bunch of stuff that happens under the covers with ADCS (automatic CA trust via domain, canned cert templates with the right shape, etc) that you have to do manually with OpenSSL, and you have to tweak the OpenSSL CA config to get it to generate the correct output versions and attributes. 

This is one of the other reasons I've been procrastinating documenting cert auth for Ansible/WinRM, because saying, "go generate yourself a client cert" is just the beginning. Getting Ansible/pyinwm to do the right thing is quite simple, but getting the certs generated and Windows configured right to accept them (esp if you're not using the built-in CA) is a big hassle. Oh, and by the way, even if you get it working, it still sucks. :)

Well, the only reason for me to be looking at client certificates was because `raw` would be working, but that has proven not to be the case. `raw` is still broken (for certain workloads) when used with local user accounts (incl. Administrator). Which is _weird_...

Nevertheless client certificates may have their use (like SSH keys) for automated workloads. So documentation would be nice. I can see that it is not a priority.

Hi, can you please tell me how you generated your pem/key files ?

I tried to follow the tutorial on Matt Wrock's blog (link above) but I don't see the generation of any key file in there (only pem and pfx are genrated).

Where does this file come from ?


This is no longer relevant for me. CredSSP works better than client certificates.
It is part of the documentation.
- http://docs.ansible.com/ansible/intro_windows.html#authentication-options
- http://docs.ansible.com/ansible/intro_windows.html#credssp

So basically:
```yaml
ansible_winrm_transport: credssp
```
@nitzmahone Shall I close this one ? Or do we want to spend some effort on this despite the limitations ?
Hi,

I finally achieved to get pem/pfx/key using a cloudbase-init script that I modified to comment the removal of the temp dir containing the key file.

Now, cert auth work using ansible *BUT* now, since the solution doesn't provide any support for proxying such https connections (WinRM uses HTTPS), I have to handle NAT port based to access my proxyfied hosts...

My Ansible inventories will be really hard to maintain (I will have to regenerate them on the fly using some db+script).

I wish you would include the SOCKS5 support (for any Windows host remote connection) natively in Ansible so we would be able to handle various networks configurations with no hassle...

Regards
You can leave it open if you like- I'll still include some info in the new
docs about it, though it'll be lower priority than other stuff...

On Wed, Mar 15, 2017 at 7:10 AM, Dag Wieers <notifications@github.com>
wrote:

> @nitzmahone <https://github.com/nitzmahone> Shall I close this one ? Or
> do we want to spend some effort on this despite the limitations ?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/ansible/ansible/issues/16243#issuecomment-286752724>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AGdjzPny4XbnFGxeCxKPW-E_1DrTw6sxks5rl_FvgaJpZM4Iz4F3>
> .
>

@hehe2 socks-support is a complete new feature request, however you can socksify anything you like transparently (look at dante, dsocks or tsocks). So running this with ansible should work.
@dagwieers Well, I duno what would my hosts inventory look like using such tsocks/dsocks tool...

I mean, I can have IP overlapping on my remote network (behind the proxy) so I really think this would simplify the things a lot if that was already specified and handled "out of the box" in Ansible.

Sorry for the new feature request, it's not supposed to be put in here but since you can't have proxying using WinRM certificates auth whereas with ssh bastion it's quite straightforward to set-up, I really wanted to mention this limitation...

Anyway, I guess I'll have to use port based NAT for the moment...

Commit message: document the required variables for using certificates when authenticating to Windows

Patch to review:
diff --git a/docs/docsite/rst/intro_windows.rst b/docs/docsite/rst/intro_windows.rst
index 1e639c1abcd91d..6b757b7d5a8510 100644
--- a/docs/docsite/rst/intro_windows.rst
+++ b/docs/docsite/rst/intro_windows.rst
@@ -94,8 +94,12 @@ You can specify which authentication option you wish to use by setting it to the
 Certificate
 +++++++++++
 
-Certificate authentication is similar to SSH where a certificate is assigned to a local user and instead of using a password to authenticate a certificate is used instead.
+Certificate authentication is similar to SSH because it uses both a public and private key. This removes the need for using a password.
 
+This requires two variables that specify the path to both the PEM file containing the certificate and the related private key file.
+
+    ansible_winrm_cert_pem:
+    ansible_winrm_cert_key_pem:
 
 Kerberos
 ++++++++


Code review comments:
diff_hunk: @@ -94,8 +94,12 @@ You can specify which authentication option you wish to use by setting it to the
 Certificate
 +++++++++++
 
-Certificate authentication is similar to SSH where a certificate is assigned to a local user and instead of using a password to authenticate a certificate is used instead.
+Certificate authentication is similar to SSH because it uses both a public and private key. This removes the need for using a password.
path: docs/docsite/rst/intro_windows.rst
text: @user1:
Don't want to be pedantic but I think keeping the local user bit is important. You can use certificate auth for domain accounts and this change might give the wrong impression.