WinRM with non-domain joined machine using Certs

This topic contains 35 replies, has 7 voices, and was last updated by  Vic 7 months, 2 weeks ago.

  • Author
    Posts
  • #9735

    Old Cole
    Participant

    Morning all,

    Background:
    Hyper-V server running in a Workgroup (as it hosts the DC)
    Client workstation domain joined

    Requirement
    Use WinRM from workstation to Hyper-V server so that the VMs can be suspended and the server shutdown. Password should not be stored and process needs to be scheduled

    Solution
    WinRM and therefore PowerShell have the ability to use client certificate mapping for mutual trust allowing a remote session to run under the context of a local user on the non-domain joined server.

    Problem
    I'm struggling to configure the pre-reqs as it doesn't seem a topic that is particularly well covered, the best information I have found is from http://blogs.msdn.com/b/wmi/archive/2009/03/23/how-to-use-wsman-config-provider-for-certificate-authentication.aspx

    Does anyone know the certificate store that needs to contain the user certificate for mapping? I envisaged I would need the user certificate on the domain joined workstation to be exported and placed in the certificate store of the non-domain joined server. That cert would then be mapped to a local user account on the server. When establishing a remote session from the workstation I'd reference the thumbprint of the cert (local to the workstation for the user) and provide it to the server which would see that it was mapped to a local user and therefore the remote session would run under this context? However, analysing the blog instructions (referenced above) this doesn't seem to be the case.

    Paul

  • #9737

    Don Jones
    Keymaster

    Anything on the remote machine would need to be in the computer store, I'd imagine. But this is one scenario I've never set up – it might actually be worth you opening a support ticket with MS, and then doing a writeup.

  • #9742

    Dave Wyatt
    Moderator

    I got this working in a test environment, but it took a lot of fiddling. Here are the two "gotchas" that I remember from my setup:

    • The basic "User" certificate template didn't work; WSMan was complaining about the contents of the Subject Alternative Name field. I had to create a new certificate template that only contained the User Principal Name in the SAN field.
    • The user's certificate does have to be imported on the computer you're connecting to. I got it working by importing the certificate into "Trusted People" in the Local Machine store. (I didn't find documentation for this anywhere, but it seemed like a reasonable guess, and it worked).

    Other than that, the steps in the blog post you linked are reasonably accurate. I wouldn't recommend setting a "Subject" value with wildcards, as the blog showed in the example (unless you want basically anyone with the right type of certificate to be able to administer your machine with WinRM). The command I used to create the mapping (minus the actual certificate thumbprint, because I don't feel like typing that all out), was:

    New-Item -Path WSMan:\localhost\ClientCertificate -Subject 'dlwyatt@testdomain.local' -URI * -Issuer '' -Credential (Get-Credential) -Force
    

    Once that was done (along with all the usual steps to set up WinRM with an HTTPS listener and open up Windows Firewall on port 5986), I was able to issue these commands from my client computer:

    $session = New-PSSession -ComputerName Win2008VM -UseSSL -CertificateThumbprint 
    Enter-PSSession $session
    

    Oddly, I was not able to run "Enter-PSSession -ComputerName Win2008VM -UseSSL -CertificateThumbprint "; I got back a Kerberos error. I'm not sure why New-PSSession worked and Enter-PSSession didn't.

  • #9743

    Dave Wyatt
    Moderator

    I went through the process again on different VMs, to see if I missed anything in the last post. The only other tricky point was that I had to import the certificate for the CA that signed the HTTPS certificate of the target computer into the user's "Trusted Root Certification Authorities" store. If it was imported in any other place (either in the local machine store, or in the "Intermediate Certification Authorities" user store), I'd still get errors to the effect of "the SSL certificate is signed by an untrusted authority."

    Also, (though this won't affect you in your workgroup scenario), I couldn't create a certificate mapping with the credentials of a domain account (I tried this when testing a "PS Remoting to a computer in an untrusted domain" scenario). WSMan would only let me set up a ClientCertificate mapping using a local account's credentials.

  • #9744

    Don Jones
    Keymaster

    Dave, any interest in doing a write-up of the procedure? I'd like to add it (crediting you, of course) to "Secrets of PowerShell Remoting," since it's one of the rarer use cases right now, and not really well documented.

  • #9745

    Dave Wyatt
    Moderator

    Sure, I can do that. It'll be fairly short, since you already have a full section on setting up an HTTPS Listener in that book.

    Do you have a document template you'd like me to use, or should I just get the content into Word and let you format it later?

  • #9746

    Don Jones
    Keymaster

    A Word doc is fine. I'll have to merge it into the main document, which isn't done in Word (I use Pages; it makes it easier to produce the EPUB format in addition to PDF).

  • #9747

    Old Cole
    Participant

    [quote=9742]I got this working in a test environment, but it took a lot of fiddling...
    [/quote]

    Thanks Dave, now I know someone has got it to work and the way you described it makes a lot of sense. I will give this a go shortly and report back.

    Paul

  • #9748

    Dave Wyatt
    Moderator

    Strange. While I was going through all this again for the write-up, I couldn't reproduce the certificate errors I had last night. I was able to authenticate successfully with a certificate based on the plain v1 "User" template that ships with AD CS. That makes the process much simpler (since any old Client Authentication certificate with a UPN in the Subject Alternative Name field should work), but now I don't know why I had those errors last night.

    The error I was receiving (and now cannot reproduce) was ERROR_WSMAN_CLIENT_INVALID_CERT_DNS_OR_UPN: The WinRM client cannot process the request. If you are using a machine certificate, it must contain a DNS name in the Subject Alternative Name extension or in the Subject Name field, and no UPN name. If you are using a user certificate, the Subject Alternative Name extension must contain a UPN name and must not contain a DNS name. Change the certificate structure and try the request again.

    When I received the errors, I was using a v2 certificate based on the "User" template which contained both the UPN and the Email Name attributes in the Subject Alternative Name extension. Today, I was able to use three different certificate templates successfully (including the same one from last night).

  • #9749

    Dave Wyatt
    Moderator

    Here's a draft of the process. It probably needs some polishing (and testing on clean systems, different operating systems / PowerShell versions, etc), but the basic content of what worked in my lab is there. As time allows, I'll rebuild my VMs to perform some of those tests from scratch.

    Since I couldn't reproduce the certificate errors, I removed the section on creating a new certificate template for WinRM authentication (which made the document about 1/3 shorter). If that content turns out to be required, I still have the original document.

  • #9759

    Dave Wyatt
    Moderator

    Just finished retesting on clean installations. Everything worked fine (no certificate errors with the User template). The only explanation I can think of is that maybe I copied and pasted the wrong thumbprint on my first attempt the other night.

  • #9775

    Old Cole
    Participant

    Dave,

    I've tried this for myself and it isn't working. On connection from remote machine to non-domain joined PC I get the following error:

    New-PSSession : [Computer] Connecting to remote server Computer failed with the
    following error message : WS-Management cannot process the request. The
    operation failed because of an HTTP error. The HTTP error (12185) is: . For
    more information, see the about_Remote_Troubleshooting Help topic.
    At line:1 char:12

    Could you please screenshot the client certificate calling out the subject field and subject alternate name for comparison?

    Paul

  • #9778

    Dave Wyatt
    Moderator

    Looks like error 12185 is ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY. It's probably the SSL cert that's missing its key and not the client cert, but you should check both.

  • #9779

    Dave Wyatt
    Moderator

    Now that I'm back at my home computer, I can post these screenshots you requested. The three "ClientCert" screenshots come from the "Certificates – Current User" console on the client computer. "SSLCert" and "ClientTrust" screenshots are from the "Certificates – Local Computer" console of the remote computer. The ClientTrust.PNG screenshot is there for contrast with ClientCert1.PNG, showing that the client computer has the private key, and the remote computer doesn't need it.

  • #9781

    Old Cole
    Participant

    Dave,

    Many thanks for taking the screenshots as it has helped me to determine that the user cert on domain joined machine doesn't have the private key. I need to look at the CA templates. For reference this cert was generated automatically through auto-enrolment using a Windows 2012 Server Essentials deployment.

    Paul

  • #9796

    Lery
    Participant

    This was certainly an interesting read and I learned something from it. From a beginners perspective I was trying to think about how to accomplish this. How come you cannot just set the trustedhosts file on the workgroup computer? Something like:

    set-item wsman:\localhost\Client\TrustedHosts -value
    set-item wsman:\localhost\Client\TrustedHosts -value 192.168.x.x

    Now from my workgroup machine, I should be able to run my command on the Hyper-V server using -credential parameter.

  • #9797

    Don Jones
    Keymaster

    Here's why. Let's call the initiating machine CLIENT, and the remote target SERVER.

    With your suggestion, which is functional, CLIENT won't care if it's actually connecting to SERVER. That's what TrustedHosts does: tells CLIENT, "hey, don't worry about someone spoofing the target, just connect and send off the credential." A bit like laying your car keys on the lawn and hoping for the best.

    Also, with your suggestion, you have to provide a credential that the remote machine will recognize. That's transmitted in clear text, unless an NTLM negotiation happens.

    Your suggestion also doesn't give SERVER any real control over who can connect. Anyone capable of providing a username and password could so so.

    With the certificate-based approach that's been discussed, CLIENT does indeed know that SERVER is actually SERVER, because the server certificate says so. Also, SERVER can authenticate CLIENT based on a client certificate mapping, so you don't have to send off a credential. The credential isn't sent in the clear, thanks both to the certificate and to the SSL channel.

    So the certificate approach is more secure from a number of perspectives. It's a much better long-term, production-quality approach, although it obviously does take more work to set up. Not that your suggestion is wrong at all – it just doesn't meet some of the security requirements that the above discussion revolved around. Your approach is easier, and if all I needed to do was temporarily connect (maybe to a new server that I was going to add to the domain), I'd totally go that route.

  • #9798

    Lery
    Participant

    [quote=9797]Here’s why. Let’s call the initiating machine CLIENT, and the remote target SERVER.
    With your suggestion, which is functional, CLIENT won’t care if it’s actually connecting to SERVER. That’s what TrustedHosts does: tells CLIENT, “hey, don’t worry about someone spoofing the target, just connect and send off the credential.” A bit like laying your car keys on the lawn and hoping for the best.
    Also, with your suggestion, you have to provide a credential that the remote machine will recognize. That’s transmitted in clear text, unless an NTLM negotiation happens.
    Your suggestion also doesn’t give SERVER any real control over who can connect. Anyone capable of providing a username and password could so so.
    With the certificate-based approach that’s been discussed, CLIENT does indeed know that SERVER is actually SERVER, because the server certificate says so. Also, SERVER can authenticate CLIENT based on a client certificate mapping, so you don’t have to send off a credential. The credential isn’t sent in the clear, thanks both to the certificate and to the SSL channel.
    So the certificate approach is more secure from a number of perspectives. It’s a much better long-term, production-quality approach, although it obviously does take more work to set up. Not that your suggestion is wrong at all – it just doesn’t meet some of the security requirements that the above discussion revolved around. Your approach is easier, and if all I needed to do was temporarily connect (maybe to a new server that I was going to add to the domain), I’d totally go that route.
    [/quote]

    Well it's good to know that I'm not completely crazy 🙂 I was also thinking that my approach would only be run in a test/development network only.

  • #9799

    Don Jones
    Keymaster

    Yup, and in a test/dev environment I'd do exactly that. This whole discussion has been about a production environment, and I'm really glad to see someone thinking about the security of that – certificates are totally the way to go.

    FWIW, ***EVERYONE*** should have at least a basic PKI set up to issue SSL certs to servers, and ideally to issue client certs to clients. Certs play a huge, and growing, role in IT, especially Microsoft IT. If you're not up on AD CS, get up on it.

  • #9805

    Old Cole
    Participant

    [quote=9799]FWIW, ***EVERYONE*** should have at least a basic PKI set up to issue SSL certs to servers, and ideally to issue client certs to clients. Certs play a huge, and growing, role in IT, especially Microsoft IT. If you’re not up on AD CS, get up on it.
    [/quote]

    Couldn't agree more Don. Four years ago I knew very little about PKI beyond SSL certificates on websites. I forced myself to learn because I hated our Exchange certificates generating an error and wanted to know how I could stop this from happening. I discovered UCC certs and SAN names and from there my knowledge has slowly expanded to now be driving the requirements for an internal PKI infrastructure. LDAP look-ups on domain controllers, TLS for secure email exchange, network security in 802.1x, everything to do with mobility, code-signing, stop setting execution policy in PowerShell to unsigned and use remote signed, etc, etc. It's all PKI and happening now, the beauty of AD is that lots of the complexity can be made transparent to the end user, as long as the AD IT Pro knows the possibilities.

    Paul

  • #9807

    Old Cole
    Participant

    [quote=9797]With the certificate-based approach that’s been discussed, CLIENT does indeed know that SERVER is actually SERVER, because the server certificate says so. Also, SERVER can authenticate CLIENT based on a client certificate mapping, so you don’t have to send off a credential. The credential isn’t sent in the clear, thanks both to the certificate and to the SSL channel.[/quote]

    Further benefit is the script on the CLIENT doesn't need an embedded password or secure-string encrypted text file to lookup the password, this is important if I want to run it as a task or call it from a service. The account on the target server can have an ultra long and complex password which changes frequently as I don't need to know it for my script to work.

    It is also an alternative to using CredSSP for overcoming "second hop" issues. CredSSP, as I understand it, passes the credentials of the user on the CLIENT machine to SERVER allowing the SERVER to authenticate as the CLIENT user for onward calls. Using SSL and mapping means I am using the credentials of the local user on the SERVER, the SERVER does not know the CLIENT users credentials. I am interested in this option for administering servers in a DMZ environment.

    Paul

  • #9814

    Old Cole
    Participant

    [quote=9749]Here’s a draft of the process. It probably needs some polishing (and testing on clean systems, different operating systems / PowerShell versions, etc), but the basic content of what worked in my lab is there.[/quote]

    Dave,

    I finally have this working, so many thanks for the input. I've discovered that the -Subject text in New-Item appears to be case sensitive so if the cert were issued with a SAN stating a principal name of Name@DOMAIN.local it needs to be entered exactly as appears in the cert. Maybe a troubleshooting step in the doc could be to use -Subject * to rule out everything else then experiment with changing the Subject. To do this you need to clear previous mappings:

    get-childitem -path wsman:\localhost\clientcertificate | %{remove-item $_.pspath}

    Then issue the New-Item cmdlet again revising the -Subject value.

    One of thing is it might be a good idea to use a specific account on the SERVER for mapping rather than BUILTIN\Administrator just to make things a bit clearer and avoid ambiguity?

    I hope you don't take this in a negatively because your doc is excellent and has helped me get this working when no other such instructions appear anywhere else on the Internet.

    Paul

  • #9819

    Dave Wyatt
    Moderator

    [quote=9814]I’ve discovered that the -Subject text in New-Item appears to be case sensitive so if the cert were issued with a SAN stating a principal name of Name@DOMAIN.local it needs to be entered exactly as appears in the cert.
    [/quote]

    That's strange; I'm not seeing the same behavior. I just tried removing the client mapping and recreating it with different combinations of capital and lowercase letters, and it worked every time (including the very annoying 'DlWyAtT@tEsTdOmAiN.lOcAl'). Are you sure there wasn't just a typo the first time?

    If you haven't done so yet, check the "Windows Remote Management\Operational" event log. There should be errors there from when the failed connections were attempted, and there might be more details on what happened.

  • #9843

    Old Cole
    Participant

    Dave,

    Re-tried this evening and it would seem I was making a mistake in the command and that it is NOT case sensitive. I can only assume a trailing space or something in notepad where I was manipulating the -subject parameter.

    Again thanks for writing the doc

    Paul

  • #9846

    Dave Wyatt
    Moderator

    No problem! This might be useful for my company, as well. In some places, we use SSH with certificate authentication for this same type of scenario (scheduled tasks authenticating to workgroup machines), but going with PS Remoting instead is an option now.

  • #13655

    Jason Colotario
    Participant

    Hi Gents,

    I am a little late in the game so to speak. I am excited that cert mapping is an option for remoting to untrusted domain(s) as I definitely want to avoid sending any credentials clear text – even if CredSSP establishes the SSL/TLS session prior to employing NTLM to send the creds. It is essential that MITM attacks are avoided – as many know, in cloud infrastructures, Admin creds are usually consistent across each box with regular credential rotations.

    Dave – thank you for your write up, it will help all us budding Admins out there do things "the right way". I do have a question: When creating the cert for client machine is it "ok" to use tool such as openssl or should I use AD CS to create a self-signed cert for both CLIENT and SERVER? When setting up PS remoting in my test environment, I created the SERVER cert and private key on my client machine and installed it on SERVER. Is it absolutely necessary to use AD CS in addition to traditional PKI? I could potentially use a class-2 CA if a self-signed cert presents concerns.

    Don – I watched your 2013 PS Summit presentation on PS remoting – that was my first glimpse on it, thank you.

    Best regards,

    Jason

  • #13656

    Dave Wyatt
    Moderator

    Any valid certificate should be fine, so long as it has the right hostnames / key usage / etc. ADCS is just what I had handy in my lab when I did the tests and screenshots.

  • #17813

    Jason Colotario
    Participant

    Hello,

    Is it also possible to use a wild card for each cert, eg *.domain.com? The flexibility would be great with "n" number of targets to manage.

    Best regards,

    Jason

  • #17814

    Dave Wyatt
    Moderator

    Are you talking about using a wildcard in the -Subject parameter of this command?

    New-Item -Path WSMan:\localhost\ClientCertificate -Subject "dlwyatt@testdomain.local" -URI * -Issuer "" -Credential (Get-Credential) -Force
    

    If so, you technically can use a wildcard there, but you might be creating a security vulnerability by doing so. For instance, if the subject were "*@testdomain.local", anyone who had a certificate with a matching name (issued by the correct CA) would be allowed to authenticate using this mapping.

  • #17833

    Jason Colotario
    Participant

    Hi Dave,

    Yes I was thinking of using wild card for Subject.

    Separate question:

    In our preliminary remoting tests we used the FQDN: winrm create winrm/config/listener?Address=*+Transport=HTTPS `@`{Hostname=`"`hostname.domain.com`"`; CertificateThumbprint=`"`cc 5v 76 89 ff 56 88 88 88 88 88 88 ff gg hh 44`"`}

    *fictitious hex above*

    Is it possible to use wild card FQDN *.domain.com when connecting to any target (thumbprint remains unique).

    Thanks again for your help,

    Jason

  • #17834

    Dave Wyatt
    Moderator

    I haven't tried that, personally. If you use a certificate that doesn't have a CN matching the hostname, you'd normally have to use some extra command-line options on the client side to connect (New-PSSessionOption -SkipCNCheck). I'm not sure if that also applies to wildcard certificates.

  • #23006

    Xperia Wise
    Participant

    I also made several testcases to test the access to a domain joined machine and a workgroup machine. WinRM to the domain joined machine was working as expected but the access to a workgroup machine never worked. At least on one machine the authentication was past the certificate validation but failed then with an url error. The winrm log only shows the error but no explanation why it went wrong. All the machines were running Windows Server 2008 R2 SP1 or W2012 R2 and the firewall was set to off. How to enable a more verbose winrm log?

  • #36024

    Jason Colotario
    Participant

    Hello,

    Server 2012 R2: Getting "Access is Denied" when running command/syntax below. The thumbprint and computer name are fictitious. I've been able to get this to work from Win7 to Server 2008 R2, however Server 2102 R2 doesn't like it. I've already set the firewall to allow inbound traffic over 5986.

    Invoke-command -computername comp1 -SessionOption (New-PSsessionOption
    -SkipCACheck -SkipCNCheck) -ScriptBlock {hostname} -CertificateThumbprint 0a7b559945678899445566bbggffjjtt

    Error:
    Comp1] Connecting to remote server Comp1 failed with the following error message
    The WinRM client cannot process the request. The destination computer (Comp1:5986) returned an
    access denied' error. Specify one of the authentication mechanisms supported by the server. If Kerberos mechanism is
    sed, verify that the client computer and the destination computer are joined to a domain. Possible authentication
    echanisms reported by server: Negotiate For more information, see the about_Remote_Troubleshooting Help topic.
    + CategoryInfo : OpenError: (Comp1:String) [], PSRemotingTransportException
    + FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken

  • #36126

    Jason Colotario
    Participant

    Update: I got cert mapping to work from Win7 client to Server 2008 R2 target, however from Win7 client to Win 2012 R2, it appears WinRM has had a major overhaul and does not allow cert mapped connections unless requestor and requestee are within the same subnet!!!

    I've ensure the appropriate firewall exception is enabled for WinRM over HTTPS. I've ensure my client does not have a firewall enabled.

    Has anyone else had this issue and are there any solutions?

  • #54403

    Jason Colotario
    Participant

    I am able to connect using cert-auth, however when I connect, it shows the user path on the command prompt of the user that originally created/installed the SSL cert for remoting under his own account. How can we configure the remote session/connection so that the user path shows the correct user path for anyone connecting to the target?

    Best regards,

    Jason

  • #68662

    Vic
    Participant

    I have been through the steps in the eBook (very helpful btw – thank you) for setting up certificate authentication. The use case is I want to be able to connect (ultimately from Ansible) to WinRM to a newly provisioned EC2 instance (we are blocked from using AWS tools or this would be much easier) in order to change the hostname, install some agents, then join the domain. Presumably after the domain join, we will use kerberos authentication, but for the short time that the VM is not domain joined I need to securely connect to it in order to complete several automation tasks. I would rather not use username/password, so have been testing auth with certificates. I have validated that WinRM works over ssl if I pass username and password. However, when I try to use cert authentication I get the following, which seems to indicate a problem with my user certificate.

    "If you are using a user certificate, the Subject Alternative Name extension must contain a UPN name and must not contain a DNS name. Change the certificate structure and try the request again."

    There is a local account on each new EC2 instance (vmadmin). The certificate that I am attempting to use was signed by our own CA, and the trust chain is trusted on both WinRM client and the remote VM. The certificate is in the client's user store and the remote VM's trusted people.
    — Subject: CN = vmadmin
    — Key Usage: Digital Signature, Key Encipherment, Data Encipherment(b0)
    — Enhanced Key Usage: Server Authentication (1.3.6.1.5.5.7.3.1), Client Authentication (1.3.6.1.5.5.7.3.2)
    — Subject Alternative Name: Other Name: Principal Name=vmadmin@localhost

    I don't want to continue guessing at what the certificate should look like, so if someone has this working and could provide me the details I would really appreciate it.

You must be logged in to reply to this topic.