返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
Windows

Deploy OpenSSH service on Windows

Windows has finally learned to install OpenSSH shamelessly via the command line, but the settings interface is still laggy as hell. Well, at least it's better than before. However, the SSH connection still defaults to CMD—which genius's brain circuitry decided this user experience was acceptable?

曦远 (DealiAxy)约 22 分钟
目录21 个章节

Preface

A scholar separated for three days should be looked at with new eyes (士别三日当刮目相待).

I never imagined that after so many years, Windows would no longer be the system that was virtually useless without its graphical interface.

Windows 10/11 and Server 2019+ now come with a built-in OpenSSH Server, which can act as a jump server to connect to other Linux servers.

This scenario typically involves a Windows computer in an office that is kept running long-term, which is then accessed remotely via virtual networking (虚拟组网).

Operation Steps

Let me clarify something first. Most tutorials found online use graphical interface operations, and the Windows settings interface is truly garbage—it's laggy by itself, and clicking a few more times either freezes it or causes it to crash.

When trying to add the OpenSSH Server component in the optional features within Settings, it always gets stuck halfway and becomes unresponsive.

After diving into the official documentation, I managed to get everything done entirely through the command line. I have to admit, this PowerShell is pretty impressive.

Installing OpenSSH Server

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

This command is much faster than adding it through the Settings interface.

Start the Service and Set It to Start Automatically at Boot

Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'

Open Firewall Port (22)

For security reasons, it is recommended to change to a different port later.

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

Connection

At this point, everything is set up. You can directly log in using a local account or a Microsoft account, though it's recommended to use a local account.

Login with Local User + Password

ssh your_user@10.x.x.x

Login Using Keys

Generate a key pair on Linux (or use an existing one)

ssh-keygen -t rsa -b 4096

Add the public key content to the user's C:\Users\<your_user>\.ssh\authorized_keys file on Windows.

C:\Users\<your_user>\.ssh\authorized_keys

If you were on Linux, you’d be done here and could log in directly using the key without a password. However, Windows has a few quirks. Let’s go over them next.

Permissions

SSH has strict requirements for configuration file permissions. In Linux, it's straightforward—just use the chmod and chown commands.

But on Windows, it gets confusing. It seems like you can configure permissions through the graphical interface, but it looks quite complicated.

However, I still found a way to configure permissions via the command line.

# Set Directory Permissions: Only the User Themselves Can Read and Write
icacls .ssh /inheritance:r
icacls .ssh /grant:r USERNAME:F
icacls .ssh /remove "Authenticated Users" "Users" "Administrators" "System"
icacls .ssh /setowner USERNAME
# Set authorized_keys Permissions
cd .ssh
icacls authorized_keys /inheritance:r
icacls authorized_keys /grant:r Username:F
icacls authorized_keys /remove "Authenticated Users" "Users" "Administrators" "System"
icacls authorized_keys /setowner Username

Configuration

The path for sshd_config on Windows is C:\ProgramData\ssh\sshd_config.

As mentioned earlier, there are a slight gotcha with SSH key authentication on Windows. Let's take a look at this configuration file.

# This is the sshd server system-wide configuration file. See  `sshd_config(5)` for more information.
# sshd_config(5) for more information.
# The Strategy Used for Options in the Default sshd_config Shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key
# Ciphers and Keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication Configuration

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes
# The default setting checks both `.ssh/authorized_keys` and `.ssh/authorized_keys2`
# But this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile	.ssh/authorized_keys

#AuthorizedPrincipalsFile none
# For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Do Not Read the User's ~/.rhosts and ~/.shosts Files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
# GSSAPI options
#GSSAPIAuthentication no

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
# Banner (Banner)
# Override default of no subsystems
Subsystem	sftp	sftp-server.exe
# Example of overriding settings on a per-user basis
# Match User anoncvs
# AllowTcpForwarding no
# PermitTTY no
#	ForceCommand cvs server

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys


First, uncomment PubkeyAuthentication yes. Although PubkeyAuthentication is enabled by default, it is recommended to uncomment it explicitly to prevent it from becoming disabled due to changes in some system default settings.

Then there's a major gotcha with Match Group administrators.

If the logged-in user belongs to the administrators group, the system will not use ~/.ssh/authorized_keys. Instead, it will force the use of C:\ProgramData\ssh\administrators_authorized_keys.

Generally, Windows users are administrators, so the configuration written to C:\Users\username\.ssh\authorized_keys will be ineffective.

The correct method is to write the public key to C:\ProgramData\ssh\administrators_authorized_keys.

It's also best to set the correct permissions in the configuration:

cd 'C:\ProgramData\ssh'
New-Item -ItemType File -Path .\administrators_authorized_keys -Force
icacls .\administrators_authorized_keys /inheritance:r
icacls .\administrators_authorized_keys /grant:r "Administrators:F"

Change Default Port

The default is port 22, which is not very secure as it's easily discoverable with a simple scan.

Port Range Introduction

  • 1025 ~ 49151 is the registered port range (many services register to use this range)
  • 49152 ~ 65535 is the dynamic/private port range (recommended to choose from here)

Check Port Usage

You can pick any available port in the private range.

However, it’s a good idea to check for existing usage first. For example:

netstat -aon | findstr ":60222"

Adding a Firewall Rule

Remember to add the rule after modifying it.

New-NetFirewallRule -Name "OpenSSH Custom Port" `
  -DisplayName "OpenSSH Custom Port (60222)" `
  -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 60222

Restart SSH Service

Restart-Service sshd

User Experience

The command-line experience in Windows is still quite limited.

After enabling the SSH Server, connecting to it actually leads to CMD.

However, switching to PowerShell isn't difficult.

Here is a method found online (untested).

Method 1:Modify the Registry

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

Restart the service Restart-Service sshd

Method 2: Set up login shell for a single user

If you don't want to affect other users in the system (e.g., for security isolation), you can edit sshd_config and add the following content:

Match User username
    ForceCommand powershell.exe

Method 3, Temporary Switch

After connecting, type powershell or pwsh (if PowerShell 7 is installed).

Summary

Done, although I connected via SSH, the value of Windows is essentially to serve as a springboard for connecting to Linux…

References

_EOF_

Deploy OpenSSH service on Windows

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…