System administration
PowerShell
Server Administration
DevOps

Connect to Windows via SSH like in Linux

Tutorial
The most depressing thing for me is to connect to Windows hosts. I'm not an opponent or a fan of Microsoft and their's products. Every product has its own purpose. But it is really painful for me to connect to Windows servers, because of 2 points: it is hard to configure (Hi WinRM with HTTPS), and it is really unstable (Hello RDP to VMs across the ocean).

Fortunately, I found the project Win32-OpenSSH. I realized that I want to share my experience with it. I believe it will help somebody and save a lot of nerves.



Installation ways:

  1. Manually
  2. Via Chocolatey package
  3. Via Ansible, let us say the role jborean93.win_openssh

I will explain the manual way because other ones are obvious.

I must note, this project is on beta stage and it isn't recommended to use it in production.

Well, let's download latest release. Currently it is 7.9.0.0p1-beta. It also has 32 and 64 bit versions.

Then unpack it to C:\Program Files\OpenSSH.

Important: It is necessary to grant write access to SYSTEM and Administers group only.

Futher, install services via shell script install-sshd.ps1 which is located in the OpenSSH directory

powershell.exe -ExecutionPolicy Bypass -File install-sshd.ps1

Let's allow incoming connections on 22 port:

New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

Note: applet New-NetFirewallRule is for Windows Server 2012 and above only. For older or desktop OS, you can use the following command:

netsh advfirewall firewall add rule name=sshd dir=in action=allow protocol=TCP localport=22

Start the service:

net start sshd

This will automatically generate host keys under %programdata%\ssh if they don't already exist.

You can set up the service auto-start by command:

Set-Service sshd -StartupType Automatic

Also, you can change default shell (it is cmd by default after install):

New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

Note: you must define absolut path.

What's next?

We can configure sshd_config, which is located in C:\ProgramData\ssh.
E.g.:

PasswordAuthentication no
PubkeyAuthentication yes

Then we create .ssh directory inside the user directory (C:\Users\<user_directory>) and authorized_keys file inside it. We can paste public keys into this file.
Important: the only user in which directory it is, must have write permissions for this file.
By the way, if you can't fix it, you can disable permissions check via config:

StrictModes no

Also, directory C:\Program Files\OpenSSH contains 2 scripts (FixHostFilePermissions.ps1, FixUserFilePermissions.ps1), which should but not obliged fix permissions, including authorized_keys permissions, but they don't.

Don't forget to restart sshd service to apply changes.

ru-mbp-666:infrastructure$ ssh Administrator@192.168.1.10 -i ~/.ssh/id_rsa
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS C:\Users\Administrator> Get-Host

Name             : ConsoleHost
Version          : 5.1.14393.2791
InstanceId       : 653210bd-6f58-445e-80a0-66f66666f6f6
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

PS C:\Users\Administrator>

Personal pros/cons.

Pros:

  • Standart way to connect to any server (Windows/Linux)
    When you have a few Windows host, it's inconvenient:
    So, here we go via ssh, but here via RDP,
    and generally speaking, it is the best-practice with bastions, firstly ssh-tunnel, then RDP via the tunnel. Oh kill me baby one more time.
  • Easy to configure
    I think it is obvious.
  • Connection speed to remote host
    Without GUI we save up host resources, and size of transmitted data

Cons:

  • It can't replace RDP in some cases.
    Not the all things you can do via PowerShell. I mean the cases when GUI is required.

Links:

Project on Github
Ansible docs
+6
2.3k 1
Leave a comment
Top of the day