Wednesday, September 28, 2011

Setting up a secure WinRM / PowerShell environment

For the last couple of weeks, I have been working with a team to plan out WS-MAN (a.k.a. Windows Management Framework) layout for ongoing support and administration.   I am not going to go into too much details of the entire project, but share some tidbits with you.

The goal of my project was to setup a secure Windows management framework for number of sysadmin type who will use PowerShell to perform day to day administration of many (many) servers running Windows Server 2003 and Windows 2008 R2  (and plethora of Roles, Features and third party applications).   I should mention that the Admins are in a different network than the servers they are managing and they are managing resources that are part of number of resource domains  (Mostly still Active Directory 2003 Forest/Domain scenario).  All these resource domains trust the domain those admins are users of.

Some key points to consider

-All the communication has to be secure (HTTPS)
-All servers will have "Allsigned"  execution Policy
-You know what goes with above?  Yep, Code Signing with certificate
-No Communication over HTTP
-Also no direct communication to all the servers, so a Admin/Jump Server has to be in place.
-Scripts has to be checked in via a code management software (like TFS)

Before I go on, I want to mention one thing.   I had a wrong impression on "TrustedHosts" setting in WinRM.  I really thought it was as cool as it sounded like to me.  Sigh!

Well, I wanted "TrustedHosts" configuration to be a way to restrict who I want in or not.  In my scenario, especially its being a Domain environment, TrustedHosts doesn't really have much role to play.  I would like for somebody to tell me otherwise.

So to tackle WinRM over HTTPS, I had to run

Enable HTTPS:
WinRM QuickConfig -Transport:HTTPS

->  I got an error saying cannot create a WinRM listener. Machine doesn't have an appropriate certificate.  A Certificate must have a CN matching the hostname.

I had to take care of that by adding a certificate for the server (CN matching the hostname).  Since we have an Enterprise Root Certificate Authority in place, I could easily use that to generate my cert  (Setting up a Certificate Authority is way simpler than it sound).   Of course, you can also use one of those well known CA (e.g. Verisign, GeoTrust etc).

After installing the certificate with hostname.mycorp.com, my "Enable HTTPS" command went without a hitch.

By default, WinRM uses Port 5985 (HTTP) for transport.   Even though your authentication still secure (uses Kerberos), rest of your communication are done over HTTP and not very secure.

If you want to only allow HTTPS communication and disable HTTP option:

Disable HTTP:
WinRM delete winrm/config/listener?Address=*+Transport=HTTP

Now that you have WinRM talking over TCP/5986 (HTTPS), and both your server and your client trust the CA that issued those certificate, you have a way to restrict who can get to your box or not.

After some concern brought up to the table, we also decided to make our (Admins) job a little harder.  We decided not to allow everybody (Admins) access the entire farm from their workstation.  Instead, they will go via a Jump Server type solution (which will be known as the management server).   So we will only allow TCP/5986 traffic to those mgmt servers, and then to the entire farm.  Another words, and admin will have to open an interactive session with the mgmt server and run his/her script that will go out to the rest.   Code Signing option will be integrated with whatever IDE we choose to go with running from the mgmt server.




1 comment:

  1. Hi there,

    I know this is an old post but I just have a question about how TFS comes into play here.

    Is it just so that the scripts are able to be versioned/validated/approved?

    It doesn't sound necessary from the above but obviously it would potentially provide more security by making sure the script wasn't changed to include something malicious.

    Kind regards,
    David

    ReplyDelete