PowerShell remoting with SSH public key authentication
Enable PowerShell Core 6 remoting with SSH transport
Latest posts by Dan Franciscus (see all)
- SolarWinds Server Performance and Configuration Bundle - Tue, Jun 18 2019
- SolarWinds Patch Manager: Updating Windows and third-party software - Tue, Apr 30 2019
- Monitor file changes in Windows with PowerShell and pswatch - Fri, Feb 1 2019
If you have been following the developments over the last year on PowerShell Core, you'll know that the PowerShell team has been hard at work. Not only are they quickly approaching the release of the production version of PowerShell Core, but they have also been working constantly on several projects. These include Desired State Configuration, the PowerShell Visual Studio Code extension, and the topic of this article: porting OpenSSH to Windows.
SSH has long been the remoting mainstay in the Linux world. In client scenarios, PuTTY on Windows is the most common use of SSH, as it allows a Windows user to SSH into a Linux system. There are other third-party solutions providing an SSH server on Windows, but having a Microsoft team officially providing it will make it easier to adopt.
Although Windows PowerShell users are used to WinRM as their remoting protocol with PowerShell, it makes a lot of sense to enable Windows to use SSH. The ability to use SSH provides a common user experience for Linux users to connect to Windows systems remotely and vice versa. In my opinion, in the not-so-distant future, SSH will likely become the remoting protocol of choice for Windows users as well.
Installing the OpenSSH package ^
Currently, there are two ways to install OpenSSH on Windows documented on GitHub. I recommend using Chocolatey because it is much simpler and automates a few of the necessary tasks for you.
In PowerShell or cmd, this command will install both the client tools and server component. To install just the client tools, remove the ‑param argument. Among other tasks, it opens the proper firewall ports and sets or starts the sshd and ssh-agent services:
choco install openssh -params '"/SSHServerFeature /KeyBasedAuthenticationFeature"' –y
Now our local computer is ready to remote to open hosts with SSH and have other hosts connect to it.
SSH on Windows with password authentication ^
In these examples my username is "dan" and my SSH server is "remotehost." When attempting to remote into a host with a password for a local user, you can simply run:
After you run this, it will prompt you to type in your password. If successful, you will gain access to the shell.
Fortunately, you are also able to use an Active Directory domain account with SSH as well. You can use either "DOMAIN\dan" or dan@domain.
ssh –l dan@domain remotehost
Notice I have to specify the -l parameter (login name) when using the dan@domain syntax because it conflicts with the standard dan@remotehost use of SSH.
SSH with key authentication ^
While authenticating via SSH supports using a password, it is more secure to use a key. To set up a key, you first have to generate it from your client and provide a passphrase. In this example, I use the defaults "id_rsa" as the file and RSA as the type:
This results in two files now created in c:\users\dan\.ssh: id_rsa and id_rsa.pub.
Please note you need to ensure you are the only user who has access to the id_rsa private key on the file system for security purposes.
Ensure the ssh-agent service is started:
Next, we need to add our key with the ssh-agent service:
PS C:\> ssh-add.exe C:\users\dan\.ssh\id_rsa
Enter passphrase for C:\users\dan\.ssh\id_rsa:
Identity added: C:\users\dan\.ssh\id_rsa (C:\users\dan\.ssh\id_rsa)
Setting up an SSH server on Windows ^
Now that we've set up our SSH client with its key, we need to ensure the server can authenticate the user with that key.
The first task we need to do is copy the public key of our client to the "C:\users\dan\.ssh\authorized_keys" file on the server. If the ".ssh" directory does not exist on the server yet, we will need to create it and apply the proper NTFS permissions. The user account associated with the key, the system account, and the sshd service (which only needs read access) should be the only accounts given permissions.
If you have admin access on both systems, you can simply use PowerShell to copy the contents of your public key to the SSH server:
PS C:\> cat c:\users\dan\.ssh\id_rsa.pub | Add-Content '\\remotehost\c$\users\dan\.ssh\authorized_keys'
Finally, we log in via SSH to our "remotehost" server from our Windows client, specifying the ‑i parameter and our private key:
By default, I enter into cmd, but I can easily open PowerShell Core:
PowerShell Core as a subsystem on the SSH server ^
One additional configuration you may want is making PowerShell Core a subsystem when using Enter-PSSession to your Windows server. To do this, you edit the "sshd_config" file located on your server currently at "C:\Program Files\OpenSSH-Win64." Remember this is subject to change if you update to a newer version of PowerShell Core.
In addition, it is important to note that this will only allow PowerShell remoting cmdlets (Enter-PSSession, Invoke-Command, etc.) to drop directly into PowerShell. It does not work with using ssh.exe to connect from the client.
# override default of no subsystems
Subsystem powershell C:\Program Files\PowerShell\220.127.116.11\powershell.exe -sshs -NoLogo -NoProfile
Here, I am using PowerShell remoting from my client into my Windows Server with a local account named "dan." Notice that ‑HostName uses a specific parameter set that defaults to SSH as the protocol. The command also automatically uses my key to authenticate and enters directly into PowerShell Core on my SSH server. The use of ‑ComputerName will result in using WinRM as the protocol as most Windows users are familiar with.
I hope this article introduces Windows users to using OpenSSH on the Windows platform. With the future releases of PowerShell Core and OpenSSH, exciting times for Windows are ahead! Please keep in mind some of these instructions are subject to change with the production release of OpenSSH.