Windows Server Setup Ssh Server

Table of Contents

Installing the Server

This will install the SSH server, start the service, and then whitelist the SSH port. Starting the service will automatically create all the SSH files in %ProgramData%/ssh.

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# Start the sshd service
Start-Service sshd

# OPTIONAL but recommended:
Set-Service -Name sshd -StartupType 'Automatic'

# Confirm the Firewall rule is configured. It should be created automatically by setup. Run the following to verify
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) {
    Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
    New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
} else {
    Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists."
}

Enforcing PubKey Authentication

If you're remoting into a non-administrative user, you can place yourpub keys in %userprofile%/.ssh/authorize_keys.

Users that are a part of the "Administrators" group need their public keys in this file:

%ProgramData%\ssh\administrators_authorized_keys

The "administrators_authorized_keys" file must only have read/write privledges for the Administrators Group and SYSTEM user. You can set those settings by using this Powershell snippet from the concurrency blog

$acl = Get-Acl C:\ProgramData\ssh\administrators_authorized_keys
$acl.SetAccessRuleProtection($true, $false)
$administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule("Administrators","FullControl","Allow")
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule("SYSTEM","FullControl","Allow")
$acl.SetAccessRule($administratorsRule)
$acl.SetAccessRule($systemRule)
$acl | Set-Acl

After this, you can edit the %ProgramData%/ssh/sshd_config file to change the default ssh port, disallow password authentication, etc. If you change the default SSH port, be sure to whitelist the port in the firewall.

# Remove the previous firwall rule for port 22 before creating this one
New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 2222

Changing the Default SSH Shell

Create this registry key with the path of the shell you want to use. You can set it to third party shells like Cygwin.bat, git bash, etc.

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

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

# Default to Cygwin
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\cygwin64\Cygwin.bat" -PropertyType String -Force