WinRM w/ self-signed certificate in 4 steps

Targeted environment: Windows Server 2008 or Windows Server 2008 R2

You’ll be self-signing with makecert from the Windows 7.1 SDK. The certificate tool is a single executable, specifically at %PROGRAMFILES%Microsoft SDKsWindowsv7.1Binmakecert.exe, per default. You’ll need it – copy it to the server unless you already have the SDK installed on it.

Secondly, you’ve got a domain name, mydomain.com. Otherwise, just substitute the IP in the following instructions.

Without further ado; on the SERVER:

  1. First, create the self-signed certificate with the regular cmd.exe:

    makecert -sk "mydomain.com" -ss My -sr localMachine -r -n "CN=mydomain.com, O=Jayway Stockholm AB, L=Drottninggatan 108 Stockholm" -a sha1 -eku "1.3.6.1.5.5.7.3.1"
    (flags ref)

    Substituting your own values.

    This command will create a certificate for Server Authentication and save it in the certificate store for the local machine.

    With powershell, get the thumbprint is for the generated certificate

    ls cert:LocalMachinemy

    It’ll look like this: 87B1C1818F1828958524A598B4131757EBAF4D35

  2. Now, configure winrm (PowerShell needs escaping, so use cmd.exe):

    winrm create winrm/config/listener?Address=IP:8.8.8.8+Transport=HTTPS @{Hostname="mydomain.com";CertificateThumbprint="87B1C1818F1828958524A598B4131757EBAF4D35";Port="5986"}

    Again, substitute your variables.

  3. Open port 5986, inbound TCP for all programs (and potentially restricted to your CI-server by IP), by going to Start > Administrative Tools > Windows Firewall with Advanced Security

  4. Now, from the CLIENT, PowerShell:

    Answer the password dialog box, and you’re in! Try running “whoami” to see the user name

That’s it. Congratulations. If you stay at this for a small-scale deployment you have OK security on your communication with WinRM! However, do check out some more details:

More details

On makecert and how to switch certificate for one signed by a trusted certificate authority.

makecert switches

  1. -sk says what the Subject Key name should be. This is like the ‘user name for keys, i.e. a uniquely identifiable name for your key in the key store.

  2. -ss is the store’s name. It’s most often either My or Root depending on what you’re using your certificate for.

  3. -sr is really just if it’s a user-local store or the machine store that you are saving the key to. Has either value currentUser or localMachine.

  4. -r is for self-signing which is what we want.

  5. -sn stands for Subject Name and in this case our subject (what we want to authenticate and encrypt access to) is our domain.

  6. -a stands for Algorithm – default is md5 which is not much more secure than a 4-digit pin code on a post-it taped to an old man’s wallet. Ref: Attacking MD5, ref 2

Changing Certificates

Let’s discuss what you do when you get a trusted-CA-signed certificate

Justification

So this works nicely for a while, until someone captures you laptop because you forgot it on the tube. Suddenly you can’t revoke the certificate and you’re in a world of pain of managing your keys (to be honest, this has never happened to me and this is already 1000x better than no authentication or basic unencrypted authentication!). Also, you grew a bit and have a few more servers to manage. Fine, let’s upgrade WinRM’s HTTPS certificate.

First, get the new one. I am personally involved in StartSSL.org, since I like the idea of free, community-driven crypto over the default server-taxation style type of certificates – this will also integrate finely with browser-based X.509 certificates if you’re planning on adding an STS to your infrastructure and authenticating users with certificates rather than username/password combos

However, the world is a harsh place and we want real humans in front of bots to verify our identity for ultra security. We’ve used geotrust previously and have no real complaints.

Too long, didn’t read

Use certreq.exe to generate the request, and install it on the server.

Once installed and visible through ls cert://localmachine/my in PowerShell, copy its thumbprint.

Then, you update the listener’s binding (SERVER):

winrm set winrm/config/listener?Address=IP:8.8.8.8+Transport=HTTPS @{Hostname="mydomain.com";CertificateThumbprint="CB7434F35E3EA11D49D209F41BB16E96B472D30E";Port="5986"}

The set operation idempotently changes the listener’s configuration to the hash presented inside the @{} hash syntax.

Now try it out (CLIENT):

etsn -cn mydomain.com -Credential MyMachineNameYourUserName -UseSSL

What on earth is etsn?

See for yourself! Get-Alias etsn in PowerShell

This Post Has One Comment

  1. I was very pleased to find this blog and to follow its recommendations, but I found that WinRM doesn’t permit defining a HTTPS binding using a self-signed certificate … as evidenced by failure of the winrm create command, explicit objection to self-signed certificates in the output of winrm qc -transport:https and the advice at http://technet.microsoft.com/en-us/library/cc782312.aspx

    Is that also your experience, or did you work around it somehow with the attributes of the certificate you created? (I admit I created mine a different way … http://serverfault.com/a/510127/79782)

Leave a Reply

Close Menu