PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

AzurePublicIPAddresses Version 0.7 released

I have just released a new version of my AzurePublicIPAddresses PowerShell module. With this release (version 0.7), support for the UK data centers has been introduced.

You can learn more about using the module from my blog post, Working with Azure’s public IP addresses. James Bannan has put together a post, Update User Defined Routes for Azure Datacenters with Azure Automation, where he talks about updating user defined routes using the information from my module.

The module can be obtained via the PowerShell Gallery or from GitHub.

Kieran Jacobsen

Read More
PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

Microsoft Releases PowerShell to Linux and OS X!

The Announcement

On Friday I woke to the remarkable news that PowerShell has been open sourced, and made available on Linux and Mac. You should read the PowerShell Team’s Announcement, and Jeffrey Snover’s announcement. There is an excellent video on Channel 9, PowerShell on Linux and Open Source.


I want to first start by congratulating everyone over at Microsoft, in particular the PowerShell Team and Jeffrey Snover.  I have been an avid user of PowerShell since the codename Monad days and it has been one of the few technology constants in my 10 years in the industry (the other being Active Directory).

It has been a long road since the original Monad Manifesto to reach this milestone, and it could not have been accomplished without Jeffrey’s amazing efforts. Don Jones posted up an excellent article on just why this is such an important accomplishment, you should also read the PowerShell Team's post: Windows PowerShell is now “PowerShell”: An Open Source Project with Linux support – How did we do it?.

This wasn’t an unexpected announcement, in fact, it was quite expected. I never doubted that this accouncement would never occur, to me it wasn't a matter of IF PowerShell would become open source, but WHEN.

Like almost everyone I was in the dark that this was happening, but I had a gut feeling things were close. There were plenty of clues and signs that this was about to happen: .Net Core, Nano Server, Bash on Windows and even the inclusion of Pester in Windows 10. Still, I wasn’t quite expecting to wake up on Friday to the news.

What Was Announced

Microsoft announced that from PowerShell would be run as an open source project, and that an intial alpha release would be made available. This release is version 6.0 and is currently available PowerShell Core, for Windows, Ubuntu, Centos and Mac OS X, with more platforms expected in the future.

So what is PowerShell Core? Core is a cut down version of PowerShell, designed to run on top of the .Net Framework Core edition. We have already seen PowerShell Core in releases of Windows Nano Server. Core edition does not support all of the functionality that the Desktop version will contain.

It is worth noting that this is an alpha release, and as such, you should treat it, and have suitable expectations. This isn’t a production ready release, and likely isn’t going to be for a while yet.

Changes to Remoting

One of the big items in the announcement is the changes to the PowerShell Remoting Protocol (MS-PSRP). Currently the MS-PSRP only supports WinRM, however with PowerShell 6.0, support for SSH will be introduced.

This isn't executing commands over SSH, what is actually occuring is that the objects forming our request are serialized into XML, transmitted over SSH, and then de-serialized. SSH is used as a transport layer for the remoting protocol, mush like WinRM is currently used. SSH is not replacing WinRM, just providing another option for administrators to use.

What this does mean is that you will start to be able to manage your Windows servers from your Macbook, and your Linux servers from your Windows 10 machine. 

I had a significant number of issues with WinRM. From its poor performance to its insecure defaults, and I am hoping that the inclusion of SSH support should start to make a difference. If nothing else, it provides a number of new and interesting ways to design and manage our environments.

What’s Missing?

This is a PowerShell Core release, it is based upon the .Net Core, and as such, some things are just simply not going to be there. It should also be obvious that things like WIM and CIM are not supported and will not be available. Get-EventLog isn't there either, as it doesn't fit with the Linux log file model.

Security Impacts!

Security teams should begin to familiarise themselves with not only PowerShell 6.0 and its remoting changes now, but also with Nano Server prior to their release. With a cross pollination of administration teams, that is, Windows and Linux administrators managing each other's eco systems, we are going to see changes in our network architecture and security requirements. SSH connections from a Windows system will begin to move from the abnormal to the normal.

PowerShell is already a highly desirable target for attackers, with more instances of attacks using PowerShell on a daily basis. With the move to include PowerShell on Linux systems, especially servers, the attraction of PowerShell to attacks is likely to increase. The ability to move from a Windows client to that lovely Red Hat farm makes PowerShell an awesome attacker and Red Team tool. Some in the security industry are already calling PowerShell the next Flash or Java for cross platform hacking.

I guess the other thing we need to consider is that a significant number of people are probably pouring over the PowerShell source code with the intention of finding vulnerabilities. Whilst the chances are probably small that someone might find a significant issue, there is still the possibility.

Other Investments to Watch

Looking through the known issues document, and also the PowerShell Teams announcement, two items stood out to me:

  • The ability to write CMDLets in Python and other languages
  • Unix-style wildcard expansion

Getting Started

The best place to start is the PowerShell Home Page, after that, the PowerShell GitHub repository is your next stop.

Windows

It is worth noting that installing PowerShell 6.0 will not replace your existing PowerShell version, it is installed side-by-side. It is also worth noting that this installs Core edition and not Desktop edition.

Simply grab the right MSI, and run the installer

Linux

There are official guides for Centos 7, Ubuntu 14.04 and Ubuntu 16.04. The Centos guide should also work for Red Hat.

There are also two great guides:

Mac OS X

You can find Microsoft's instructions for installing here, for more detail check out The IT Hollow's guide, Install PowerShell on Mac.

Other Install Options

There are a bunch of other ways you can get started with PowerShell 6.0:

Once you have PowerShell installed, take a look at some of the demos available.

If you are new to PowerShell and are coming from a Linux or Unix background, check out: A Unix Persons Guide to PowerShell.

Contributing

The great part of any open source project is that we can all play our own part and contribute. You don’t need to be a developer to contribute either, I often contribute to projects by helping out with documentation, or cleaning up simple default configuration files and example usage.

If you feel like contributing, start by reading the contribution guidelines. I also recommend you take a look at the governance process. The Governance process includes how to raise issues, make contributions, and participate in the design process via RFCs. The documents also provide information on the roles and responsibilities of everyone involved in the project.

I recently spent some time working on some issues with the documentation of the PSScriptAnalyzer. The contribution process is similar to that of PowerShell, and it was super simple and easy to create a pull request and work with the PowerShell Team. I would like to point out that if your pull request is large, you may need to sign the Contribution License Agreement, don’t worry, it isn’t difficult and only takes a few seconds to complete. The agreement just covers that the work you are completing is yours and not of anyone else.

Tool Updates

Update your development tools! Virtual Studio Code (and the PowerShell extension), PSScriptAnalyzer and the ISE Steroids have all been updated to include support for PowerShell 6.0.

More Information

With all of this you should be well on your way to working with PowerShell on Linux and Mac OS X! Good luck and don't forget to share your experiences!

Kieran Jacobsen

Read More
PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

PowerShell 5, DSC, SABnzbd and Sonarr (Part 1)

I have been trying to do a lot more with PowerShell DSC of late, including writing my own DSC resources.

Last week, I decided to write some resources for SABnzbd and Sonarr. Why? Well firstly for practice, but also because no one else has looked at building up packages for these apps (there wasn’t even Chocolatey packages).

I am not going to go into detail on implementing classes in PowerShell, instead checkout:

SABnzbd

The module cSABnzbd contains a single resource: cSABnzbdInstall. This resource specifying:

  • Ensure: <String> { Ensure | Absent }
  • ServiceCredential: <PSCredential>

If you opt for Ensure to be “Present”, then the resource will install and update SABnzbd. That is right, as new versions are released, it will be automatically updated.

The ServiceCredential allows for us to control what account the SABnzbd services run as. If not specified, LocalHost will be used.

GetLatestVersion()

SABnzbd hosts both its source code and its binary releases in GitHub. This is great! GitHub provides a simple REST API that allows us to very easily and dynamically get the latest release for a project.

If we want to get information on the latest release for a particular repository, we simply perform a get request on https://api.github.com/repos/{owner}/{repo}/releases/latest. The response will contain things like the version name, the release date and the assets in the release. The GitHub API doesn’t need any authentication credentials or tokens; these requests can be performed anonymously.

Performing the API request for sabnzbd the URL for us would be https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest, and the returned information looks like:

The function is pretty simple:

Get()

The Get() function is quite easy to implement. We simply need to call Get-Package, and sets the result against the ensure parameter. We then return the object as required. The result is:

Test()

The Test() is also pretty simple. We use Get-Package again to see if the package is installed or not.

If Ensure = ‘Present’, then we need to check:

  1. If no package was returned, then return false
  2. If it is installed, compare the installed version to the version number returned using GetLatestVersion()

If Ensure = ‘Absent’, then we simply compare $Package to $null.

Set()

Now the Set() function is more complex.

If Ensure = ‘Present’, then we need to:

  1. Find the latest .exe in the release information using GetLatestVersion()
  2. Download the file, this is listed under the assets (look for a .exe).
  3. Silently run setup using the /S switch
  4. Install and start the services (optionally running under the user account specified with ServiceCredential).

If we don’t want SABnzbd installed, then we simply call the uninstall.exe.

Using and Configuring SABnzbd

You should be able to access SABnzbd via http://localhost:8080. When you connect the first time, you will be stepped through the initial setup wizard. I haven’t included any resources for specifying any settings like servers, scheduling or custom folders, you can do this as you would normally do. For more help, try the User Manual.

Getting the module

The module can be found on:

You will need PowerShell 5 or greater installed due to the use of Classes. 

If you encounter any issues, please raise an issue on the GitHub page.

In the next post we will take a look at Sonarr.

Kieran Jacobsen

Read More
PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

Working with Azure’s public IP addresses

If you have spent much time working with Microsoft Azure, Amazon AWS or any public cloud provider, you have probably started to wonder about how many public IPv4 addresses they have. Whilst we know there is a limit to the number of addresses, and that we have reached these limits, it still seems like there are quite a few to go around.

I recently had the need to get a listing of all the Azure subnets, and whilst I did this, I thought it would be good to make a reusable PowerShell module to assist.

Microsoft makes this process pretty easy, providing an XML file under the Microsoft Download Center title: Microsoft Azure Datacenter IP Ranges. There are a few things to note about this file:

  • It contains all compute (including SQL),
  • It is updated on Wednesday (Pacific Time), but changes are effective from the following Monday (Pacific Time), and,
  • The file will contain only production Azure DCs, for instance, at the time of writing the German and Canadian DCs are not contained in the file.

I have developed a PowerShell module that simplifies working with this file by developing CMDLets that:

  1. Allowing for automated downloads of the file, and,
  2. Allow for specific DCs to be extracted

Get-MicrosoftAzureDatacenterIPRangeFile provides us with a method to simply and easily access the XML document. If called without parameters, we will get the XML document returned, however we can opt to save the file to disk for future processing.

Then we have Get-MicrosoftAzureDatacenterIPRange. With this CMDLet, we can get a list of objects containing the subnets (in CIDR format) for a specific DC or for all of the DCs. You can specify the path to a previously downloaded file, or it can download the file for us (and keep it in memory).

The module can be found on:

I have tested this module against PowerShell 5, however there should be no issue with earlier versions (I recommend PowerShell 3 or higher). If you encounter any issues, please raise an issue on the GitHub page.

Just in case you were wondering, Azure has approximately 1700 subnets, or around 5.8 million IPv4 addresses!

Kieran Jacobsen

Read More
PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

PushOver and PowerShell

Pushover is an exceptional method for integrating notifications into our PowerShell scripts and workflows. Pushover gives us a simple method to send notifications to devices. I discovered Pushover in 2012, and have been maintaining a PowerShell module ever since.

The purpose of my PowerShell module is to allow you to:

  • Send Pushover notifications,
  • Test API, user, group and device tokens; and,
  • Retrieve the details of a notification receipts.

I have kept the module and the CMDLets as simple as possible. Sending a notification is a simple as specifying an API token, a user token, and a message. Pushover supports a whole lot of other functionality, and the Send-Pushover CMDLet supports:

  • Users and Group tokens,
  • Device names,
  • Priority levels (including lowest, low, normal, high and emergency),
  • Message titles,
  • A URL,
  • Custom date and time stamps; and,
  • Custom sounds.

When submitting a notification, we get the following back:

  • A response code,
  • A request identifier; and,
  • A Boolean request response code. I recommend in your scripts validating against this success property.

Most of the time, Pushover notifications are pretty straight forward. It is important to note that emergency messages, are different. Pushover will continue to notify a user until they acknowledge it. If you are sending something that is this important, you want to know if someone actually cares about it.

When a user accepts the notification, Pushover records the who, when and where. We can make use of this information either through a callback URL in a request, or through the receipt ID returned.

Now we have a variety of tokens, API, user groups and devices. How do we know if they are all valid? You can verify these are all valid using the Test-Pushover CMDLet.

Right now I haven’t included any support for Pushover’s subscription, group or licensing features. This isn’t due to any difficulties, but more that I haven’t needed these. Of course, I am always happy to have a pull request submitted for this!

You can get module from GitHub or via the PowerShell Gallery.

Kieran Jacobsen

Read More
PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

SYSLOG, PowerShell, Pester and the PowerShell Gallery

Out of all of the content on this site, my posts about integrating SYSLOG and PowerShell are by far the most popular. Whilst this might seem peculiar to some, I can definitely see the value that this would bring to an enterprise environment.

I first wrote about my initial integration attempts back in 2014. In fact that post, Sending SYSLOG messages from PowerShell, had been the reigning champ as most popular until very recently, losing its title to my work on MS15-034 and my comments on Skype for Business.

In early 2015, a number of bugs were found in the formatting of the UDP messages it sent. I invested time and energy into resolving these issues, resulting in RFC 3164 and RFC 5424 compliant messages being sent. I discussed the process of resolving them in the post, Revisting SYSLOG in PowerShell.

Well, a few weeks ago, it came to my attention that I hadn’t quite ironed out all of the bugs. I spent some time, worked through some possible fixes and implemented them. The issue turned out that when selecting the hostname to send, there was a chance it would send either the wrong IP address, not a blank hostname. It didn’t take long to come up with some new logic (which I still believe could be better), but I wanted to shake the code and determine if there were any others hiding out.

Pester

The best way to repeatedly test PowerShell functions, CMDLets, modules and scripts is through the use of Pester. I will admit, that I hadn’t, until this point, taken a look at Pester and this seemed like a great opportunity.

I started with the low hanging fruit. How about we check the input validation is correct? This shook out some validation bugs, and whilst there I realized I could implement parameter sets to improve things.

Now came the hard part. How do I validate the format of the messages that I am sending?

Well, firstly we need to mock some of the CMDLets that are used, to ensure our output is predictable. Things like Get-Date need to be mocked so we can control the messages being sent. I would also modify some of the environment variables for that execution to ensure things like hostnames were predictable.

But the messages are still sent over UDP, how do we look inside them?

The easiest method I found, well it was a bit of a pain, but it produces repeatable and testable outcomes. I would start by setting up a job using New-Job that had a basic UDP listener. The code simply waits for a UDP packet to come in, and returns as output the contents of that packet. Once I have something listening, all I need to do is run my command, and then get the output (of the now completed job) which will contain the SYSLOG message sent.

It is messy, but it allowed me to shake out another logic issue, which has to be a good thing.

A New Name and a New Home

With all of this work, one last thing has always bugged me about the module, the Name! Whilst PowerShellSyslog is simple and descriptive, it has always felt a little bit crude. Now I suck at coming up with names, so I stuck with what seems to be a habit now and stuck Posh- in front of what it actually does. The module and the GitHub repository have now been renamed to Posh-SYSLOG.

I have been attempting, where possible to move my major GitHub repositories to the PoshSecurity banner. As such, I have moved the Posh-SYSLOG to here: https://github.com/poshsecurity/Posh-SYSLOG

GitHub creates redirects when you move or rename a repository, so all of your current links and working copies should continue to work.

It’s worth noting that if you are manually importing the module via “import-module PowerShellSyslog”, you will need to update this to reflect the new module name.

Easier Installation via the PowerShell Gallery

PowerShell 5 brings a bunch of improvements and new features. One feature that I am so excited about is the Package Management functionality, as it provides new deployment options for not only conventional installed applications but also for PowerShell modules and scripts. The PowerShell Gallery allows administrators and developers to download, install and share modules and scripts.

I have made Posh-SYSLOG available via the gallery here. I will be working to ensure that the gallery is kept up-to-date with the GitHub repo. If you want to install via the gallery, simply type “install-module –name Posh-SYSLOG”.

Future and Thanks

If you are using the module, and find an issue, please feel free to raise an issue on GitHub, I will respond as quickly as possible. I want to ensure this module is the community’s preferred module for connecting to SYSLOG and are happy for any questions, comments or feedback.

I want to thank all of those who have already provided feedback and have provided assistance in testing.

Kieran Jacobsen

Read More
Security, PowerShell Kieran Jacobsen Security, PowerShell Kieran Jacobsen

White-listing Tor in CloudFlare with PowerShell

CloudFlare has been one of those technologies that has dramatically improved the Internet since its arrival. CloudFlare provides a number of amazing features, from DDOS protection, traffic analytics, performance optimizations and even free SSL! To top it all off, CloudFlare off the majority of their features for an amazing price – FREE!

Unfortunately, there are a group of users who have suffered with the rapid adaption of websites being protected by CloudFlare; Tor users. Whilst the majority of us receive the benefits of CloudFlare, it has made life for Tor users extremely miserable.

What is the issue with CloudFlare and Tor?

To understand the issues CloudFlare and Tor, we first need to understand how CloudFlare protects a website. When you visit a protected website, CloudFlare performs a risk assessment of your IP address. If CloudFlare decides that you are friendly, then you get to view the website. If it decides you are suspicious, then you will either be prompted with a CAPTCHA request or, in the extreme cases, it will deny access to the website.

The Tor is an interesting network, developed with the aim to protect privacy and defend against surveillance; the network has become a bit of a hive of scum and villainy. Due to the high use of Tor for malicious activity, CloudFlare is naturally suspicious of any connections coming from a Tor exit node, which results in a high risk assessment for all Tor users accessing protected websites.

A high risk assessment results in lots of CAPTCHA requests for Tor users to complete. Every protected page that a Tor user visits, will result in a CAPTCHA request, whilst most of us don’t mind completing these, consider how you would feel answering one every 15 to 20 minutes. It impacts productivity and your sanity.

What is the solution?

The trust of the matter is that there isn’t a simple solution, there isn’t a magic “trust Tor” button in the CloudFlare. It is down to individual website operators to white-list the Tor exit IP addresses; this isn’t trivial, requiring operators to maintain a white-list as the Tor network changes, adding new exit IP addresses that join the Tor network, whilst removing those that leave.

Now is the best time to point out the risks of white-listing. White-listing isn’t without its own risks! When you white-list an IP address in CloudFlare, you are telling it to ignore how risky the traffic coming from that address might be. Not all Tor users legitimately want to view the content of your website; some Tor users are malicious, they are out for blood. White-listing significantly changes the security protection of your site, and you need to be extremely aware of the risks it introduces.

Set and Forget White-Listing

Donncha O'Cearbhaill developed a Python based script with the aim of providing a “set and forget” mechanism for white-listing Tor exit IPs. Donncha’s Automatic CloudFlare Tor Exit Whitelister takes your CloudFlare API token and email address and does all the hard work. The script will grab the latest listing of the Tor exit IPs, and then updates CloudFlare’s white list as appropriate.

When I saw the script, my immediate reaction was “what an amazing idea”, my next was, “how could this be made more accessible to more website operators?

Turning to PowerShell

The obvious answer to encouraging more web site operators to white-list Tor exit nodes is to provide the process in more accessible formats. For Windows users, the best option is to provide the process as a PowerShell script.

So I sat down, learn some Python, and then worked on developing a PowerShell script with similar functionality as Donncha’s. This was a super fun and interesting process. In the end, I deliberately tried to stick a similar logic flow, similar parameters are supported (via parameter liases), and the scripts default output is similar. I added some additional verbose and debug options and added progress bars for long operations. I haven’t included support for specifying the CloudFlare API token and email address via environment variables.

The final result can be found over at GitHub, at https://github.com/poshsecurity/PowerShell-CloudFlare-Tor-Whitelist. All of the functionality is provided by the Set-CloudFlareWhiteList.ps1 script.

Please feel free to raise pull requests, issues, or provide any feedback that you may have.

Usage

I have included comment based help, with examples on how to make use of the script. There are three common usage methods.

  1. Specifying a CloudFlare token and email. This will white-list exit node IP addresses across all of the domains in your CloudFlare account
  2. Specifying a CloudFlare token, email and a DNS zone. This will white-list exit node IP addresses for a specific DNS zone.
  3. Specify a Token, email and optionally a DNS zone, and the -ClearFlags parameter. Remove all Tor specific rules for all domains in your CloudFlare account, or for a specific DNS Zone.

Finishing Up

I want to thank Donncha for his work in developing the original Python script. Without his work, I wouldn’t have been able to develop mine.

If you want to find out more about CloudFlare, Troy Hunt has put together a terrific PluralSight course, Getting Started with CloudFlare™ Security. He covers the basics including migration, SSL configuration and even HSTS.

Kieran Jacobsen

Read More
Security, PowerShell Kieran Jacobsen Security, PowerShell Kieran Jacobsen

Why Remoting vs SSH vs RDP Shouldn’t Be A Thing

Microsoft recently announced that they would be introducing SSH support in the coming Windows Server release. It has taken three attempts by the teams within Microsoft to gain the necessary approval to do this, and finally, third time is the charm. Hats off to those within Microsoft who have had the courage to keep to their guns with this one and get SSH included. You truly have made a positive improvement.

The introduction of SSH opens up a world of possibilities for administrators, developers and integrators; unfortunately, there seems to be quite a few in the industry that don’t share in the excitement. 

I think some people misunderstood why people were so excited. Some went so far as accusing a few of us of shouting “Death to Remoting”. I don’t see this as the death of Remoting, it is naïve to think that SSH will replace Remoting; SSH will compliment Remoting and solve a number of challenges which currently exist with Remoting.

Native support for SSH both as a client and as a server opens up a number of functions and tasks which until recently were only achievable via third party utilities, modules and just plain hacky code. Carlos Perez and I have both written PowerShell modules (his is better), that integrate with SSH, Posh-SSH and SSHFunctions respectively. We wrote these to bridge a number of gaps, gaps that will/should be removed with native SSH support. 

This is a new world for administrators and developers alike, be that those who work primarily in the Microsoft space, as well as those working with Linux.

Remoting –ne SSH –ne RDP

It should be painfully clear, but I want to make it absolutely crystal clear; Remoting does not equal SSH, SSH does not equal RDP and RDP does not equal Remoting.

Each of these protocols have a different aim:

  • Remoting (or WinRM) is roughly a remote management protocol
  • SSH provides a Secure Shell for text based management
  • RDP provides remote GUI access for GUI management

We really shouldn’t get these confused, each of them have different goals and aims, and as administrators/developers you need to know each one, when each one is appropriate to use and when each one is inappropriate.

Remoting

Remoting is an implementation of the WS-Management, which is an open, SOAP based protocol for the management of things like servers, workstations, devices and applications. The WS-Management standard was developed by a bunch of smart people at AMD, DELL, Intel, Microsoft and Sun back in 2005.

Unfortunately, WS-Management didn’t really take off, with only 4 major implementations found on Wikipedia: Windows Remote Management (WinRM), an implementation in SUSE Linux Enterprise, a European research project and finally Intel’s Active Management Technology. It is easy to speculate why WS-Management didn’t take off, the most obvious is the heavy overheads of SOAP web services. SOAP was big back in the 2000s, it isn’t as popular now and with good reason.

Believe it or not, I like WS-Management and Remoting. Remoting supports two pieces of software to connect to each other, and efficiently exchange complex pieces of data, allowing administrators, developers and integrators to build rich pieces of software on top. 
Multifactor authentication is pretty limited with Remoting. While you can add two factor into RDP, remoting hasn’t had the same treatment. 

Server authentication in Remoting is typically a complex story. To start with, typical deployments will be based upon HTTP providing limited (read: no) authentication, if you want strong server authentication, then you need to switch to HTTPS. 

The switch to HTTPS for Remoting is where things start to fall apart. A typical Remoting HTTPS deployment will be based upon self-signed or internal PKI. If you stick with self-signed, you either need to manually trust each server’s certificate, or you can skip the CA trust checks. If you want proper certificates, typically you are going need to deploy a CA infrastructure, and then configure each server to use HTTPS; you can’t use Group Policy, it doesn’t support enabling HTTPS for Remoting. Finally, don’t turn off HTTP if you want to keep using the Windows Server Manager. If you want to understand how bad configuring HTTPS for Remoting is, check out the best guide available at Carlos’ Blog, WinRM SSL Certificate Deployment via GPO.

Remoting has unfortunately been missed when it goes for secure configuration guides, the same goes for things like IDS and IPS rules. Whilst there are obvious challenges for IDS/IPS scanning of Remoting traffic that is over HTTPS, thankfully we can apply a lot of the same policies and rules for IIS to Remoting.

I feel a little jaded by Microsoft’s release of a reference implementation of WS-Management for Linux. It should be obvious to Microsoft by now that big companies cannot force the open source community to implement the standards and solutions they want. I was kind of shocked to hear about this one.

Side note: How long till Remoting is RESTful?

SSH

SSH, or Secure Shell, is an encrypted protocol for the initiation of text-based shell sessions on remote machines and was originally developed to replace Telnet, RSH and REXEC. If you ask the average person what SSH is for, they will tell you it is what you manage Linux and Unix with.

Whilst it is possible to use SSH as an integration point into automation and management of remote endpoints, it doesn’t support the exchange of complex object types, it only supports strings. For those who haven’t tried using SSH for large amounts of remote command execution, the closest would be something like invoke-command. Don Jones explained it well, “It’s all text, all the way down to the turtles.” As he goes on to summarise, whilst text isn’t bad for automation, string manipulation isn’t good. I also feel that it is wise to point out that string manipulation is a great way to introduce security vulnerabilities as well.
SSH makes up for all of this, by being extremely secure. SSH supports multifactor authentication with support for both password and key authentication, something that Windows still hasn’t caught up to (natively). 

Server authentication, that is, the authentication of the server by the client (so we know we are connecting to the right server and we are not being MITM), is quite easy. Servers have a public and private key pair, we just need to verify the thumbprint of the public key, and then we can establish a trust relationship (from here to eternity if we so desire). 
Another advantage of SSH is we know extremely well what valid SSH traffic looks like. This is critical in protecting connections either leaving our networks perimeter or those entering from outside. If devices like our IPS and IDS systems know what a valid SSH packet looks like, then we can make an attempt to weed out the nefarious traffic.

Transferring files over SSH is extremely easy, fast and efficient. I have used SSH as a file transfer mechanism in a number of environments, be it at home, in financial institutions or even for backups and server migrations. In banking SSH is an industry standard, much like PGP/GPG for a reason.

In summary, SSH gives us a secure text session in a manner that is extremely easy and without a PKI, unfortunately it is pretty bad at the exchange of complex data.

Side note: Check out Mosh an SSH replacement (not available on Windows yet). I really like the idea’s behind Mosh and can’t wait to see where it goes. I would really love to see a synchronised state console like this one.

RDP

We should all by now, know what RDP is! RDP allows us to connect to remote devices and servers via a graphical session. RDP does remote graphical consoles really well, has a simple but quite reliable security model and supports some limited file transfer options.

RDP is a heavy protocol on a network connection and for obvious reasons. Even with the advances in later RDP protocol versions, sending a graphical interface over the Internet can still be slow and laggy; combine this with file transfers, and you are in for a long wait.
There are a number of ways to add multifactor authentication to RDP, most notably solutions from DuoSec

Server authentication in RDP is actually pretty good. RDP comes by default with a self-signed certificate which does provide a degree of server authentication. You can step it up a notch by moving up to certificates issued from an enterprise CA. Configuration of RDP to use an enterprise CA is extremely simple, you can use group policy all the way. For a great write up on how to set it up, check out Carlos’ post, RDP TLS Certificate Deployment Using GPO.

RDP has been around for a long while, and a significant number of IDS and IPS products have developed rules to detect malicious traffic. Much like SSH, there are plenty of secure configuration guides for RDP from a number of trusted sources.

We need to reduce our reliance on RDP, not just because of how slow it is when managing cloud based infrastructure but also because it doesn’t support automation to any extent. RDP will always exist, there are times when we will need to run a GUI on a remote machine. 

Enter-PSSession

Enter-PSSession deserves a special mention. Providing functionality much like SSH, Enter-PSSEssion allows users to initiate a text based shell session with a remote device all over Remoting. Yes, in many ways it does provide a similar functionality to SSH, but from personal experience it can be a bit slow and clunky. 

Why is Enter-PSSession a bit slow and clunky? Well the best way to understand why, is once again by Don <link>. With Enter-PSSession, keystrokes are not transmitted in real-time, instead, each whole line is transmitted, executed, and then the results sent back to us. With all of the SOAP overheads, you can start to see where things get bogged down.

The right tool for the right job

Different tasks require different tools. You don’t use a sledge hammer to drive a screw, you need a screwdriver.

If you are running a graphical interface directly on a server (for an application that doesn’t support running remotely), then you need RDP. If you have to run the GUI on the box, you don’t have any other option but to run the GUI on the box via an RDP session. Obviously, in this case, Remoting, SSH and Enter-PSSession aren’t going to be much help here.

Want to configure a server, well, then PowerShell with Remoting is probably your best tool. You could use a text based console session with SSH or Enter-PSSession, but that might be a bit too much. If you were working with say configuration files, maybe jumping to a full text session might be worthwhile.

The final situation is a complex but common one. You have a single server, maybe its hosted by a provider like Azure; your client doesn’t have any reason to trust that server, there isn’t a shared PKI to support server authentication. SSH in this situation will shine, chances are it will be easier and more secure. Either you are going to switch down to HTTP, trust a self-signed certificate or tell PowerShell to ignore CA validation errors. This is a great time for SSH to shine.

Side Note: It would be nice to see a PowerShell CMDLet to help verify Remoting certificates and even configure trust.

In each of these situations, a different remote management protocol was required. Where as in the past, we had to make do with three options (PowerShell with Remoting, Enter-PSSession, RDP) we have now gained a fourth (SSH).

A Whole New World…

I want to point to a post by Mattias Geniar, How SSH In Windows Server Completely Changes The Game. Mattias has put together an exceptional post on why SSH is a game changer in his mind.  

I feel that the introduction of SSH opens up more administration possibilities, there is an SSH client for Android, from that I could be managing my servers in minutes something that I can’t easily do that right now (well there is the PowerShell web page thing). 

The introduction of SSH also opens up opportunities for Windows in environments that are currently predominately OSX/Linux/Unix, which has to help in the adoption of products like Nano (but alas Nano will miss out this time round) and the IOT versions of Windows.

Remoting isn’t going to go away just because SSH support has been introduced. I wasn’t rejoicing the death of Remoting when SSH support was announced, I was rejoicing that progress is being made in cleaning up the whole landscape, starting with compatibility and trust. I have always seen Remoting as a successful failure, we have proved the idea works, now it is time to start working on something that is better. I really hope to see a more improved remote management protocol coming out from Microsoft over the coming years, something that is actually cross platform and easy to integrate. Until then, we have three exceptional management protocols in tool kit to use.

Kieran Jacobsen

Read More