SSH Server on Windows 10

Did you know you can run SSH server on a Windows machine and SSH into it?

SSH Server on Windows 10

One of my pet peeves with Windows was a lack of support for SSH. SSHing into a Linux machine is such a seamless experience. I never had that with Windows. Apparently, Win10 has supported OpenSSH server for a while, and I just never knew about it. Setting it up is not trivial, so I decided to document it here.

Why?

My ultimate goal is to implement this: https://docs.gitlab.com/runner/executors/custom_examples/libvirt.html Right now I have several different VMs running for a variety of projects but they spend most of their time just sitting there waiting for jobs. I want to be able to spin them up on demand. I've also had some issues with residuals where one job does something to the system that then affects the next job to run on that VM. Switching to this model will ensure that each job starts with a fresh slate every time. Part of the challenge is that it uses SSH, so you have to be able to SSH into Windows running in the VM.

Initial Setup

So I am going to install OpenSSH Server on a Win 10 Virtual Machine. I created it from a Win10 ISO and created a local user account. First I need to know its IP and make sure you can ping it from the host. If you open a cmd window on the guest, then ipconfig will give you the IP address. You can then try pinging it from your host however it probably won't work because by default Windows Firewall blocks pings for some reason.

Allowing Ping Responses in Windows

I'm sure there are other ways to do this, but I find just opening Windows Firewall settings in the GUI to be the easiest. Just type Windows Defender Firewall into the search bar. If you look at the inbound rules, You'll see 2 rules named "File and Printer Sharing (Echo Request - ICMPv4-In). Just right-click on both of them and enable them. At that point, you should be able to ping the VM from the host.

Installing OpenSSH Server

Search for "Manage Optional Features". Click on add a feature.

Then search for OpenSSH Server and install it.

Opening a Port in the Firewall

I know I previously used the GUI for the firewall, but here I found a Powershell command to do it for me. Simply open Powershell as an admin and run the following, or use the GUI if you prefer.

New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH SSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -Program "C:\Windows\System32\OpenSSH\sshd.exe"

Starting the Server

The SSH server is now installed and the port is open, but it isn't running. To start it, type services into the search to open the services window. Find the Open SSH Server service and right click on it and open the properties window. Then you can press the start button to set it now and set the startup type to automatic, so it will start when Windows boots up.

First Connection

At this point, from the host you should be able to ssh into the Windows box. It will prompt you for your Windows password. That should give you a cmd prompt on the Windows machine.

Refining the Setup

There are a few things we can do to refine this and make it better.

Changing the Default Shell

Initially, the shell defaults to cmd. We can switch it to use GitBash using the PowerShell command below (probably needs to run as administrator).

New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\Git\bin\bash.exe" -PropertyType String -Force

Setting up SSH Keys

If we set up SSH keys then we can ssh into our Windows box without entering our password. The first step is to create an SSH key. There are plenty of instructions out there on how to do that. Once you have a key, typically in Linux you can use the ssh-copy-id command. That doesn't work with Windows for some reason.

First we need the public key. We copy that to the clipboard on the host. Then in the guest, we need to create an administrators_authorized_keys file and paste the public key into it. Then copy that into C:\Program Data\ssh .

Next we need to set the appropriate permissions on that file. We can do that with the following PowerShell command (executed as admin).

icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"

Testing

Now you should be able to ssh into the Windows VM without entering your password and should get a Git Bash Prompt.

References

Here are some references:
https://winscp.net/eng/docs/guide_windows_openssh_server

OpenSSH Server configuration for Windows
Learn about the Windows-specific configuration options for OpenSSH Server on Windows Server and Windows.