Installing OpenSSL to enable an SFTP server on Windows Server 2022

Windows Server for a long time only supported an FTPS server (FTP over SSL/TLS) via the included Internet Information Server. But FTPS in not very firewall friendly and is rather difficult to configure.
SFTP (FTP over SSH) is currently considered the best option to use, and is recognized by (nearly) all firewalls out of the box. If not, only port 22 needs to be opened up.

You can install OpenSSL on a computer using the GUI, but for easy repicability we will use powershell commands. Second, we will install everything form the online source. You could adapt the commands to use the windows server 2022 installation media.

First lets check if it’s not already installed:


Get-Service -Name “sshd”

If the answer is like below, it’s already installed, so skip the installation part.

Status   Name               DisplayName                           
------   ----               -----------                           
Running  sshd               OpenSSH SSH Server    

Retrieve installed an not intalled capabilities/options

Get-WindowsCapability -Online | Where Name -Like “OpenSSH*”

This will reveal the real names we must use in further commands:

Name  : OpenSSH.Client~~~~0.0.1.0
State : Installed

Name  : OpenSSH.Server~~~~0.0.1.0
State : Installed

If it’s not installed you can install it by:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
if you also want the clienttools:
dd-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

The installed service will not automatically start if you do not tell it so. So let’s do that, and also start it for the very first time in one go:

Get-Service -Name “sshd” | Set-Service -StartupType Automatic -PassThru | Start-Service -PassThru

Common changes to the OpenSSL config file.

The OpenSSL config file, is located in %ProgramData%\ssh\sshd_config (being c:\ProgramData\ssh\sshd_config.)
You can make changes in this file like changing commented out #Port 22 to Port 2223 (removing the # at the front), to tell OpenSSH to use port 2223 for example.
After every change to this file, you will need to restart OpenSSH with the powershell command:
Restart-Service “sshd”

Inspecting the usage of port 22 to see if opensll is running and listening, we use a powershell command. It returns the processid owning the port, and we translate that to the process name for readability:

Get-NetTCPConnection -LocalPort 22 | select Local*, State, @{n=”ProcessName”;e={(Get-Process -Id $_.OwningProcess).ProcessName}}, @{n=”ProcessPath”;e={(Get-Process -Id $_.OwningProcess).Path}} | ft -Auto

It returns:

LocalAddress LocalPort       State ProcessName ProcessPath                         
------------ ---------       ----- ----------- -----------                         
::                  22      Listen sshd        C:\Windows\System32\OpenSSH\sshd.exe
192.168.1.75        22 Established sshd        C:\Windows\System32\OpenSSH\sshd.exe
0.0.0.0             22      Listen sshd        C:\Windows\System32\OpenSSH\sshd.exe

Only Allow SFTP and not SSH into a system

After a default installation, both sftp and ssh have been enabled. So, after setting up security (see further) a users may use both. In our case, we want to ristrict this to only allow SFTP, and only allow access to one folder on the system, to which sftp access will be possible::

#Locate this line and place below:

# override default of no subsystems
#Added to allow not ssh and only sftp
#Force the use of the openssl internal sftp server
ForceCommand internal-sftp

#Restricht the sftp server to c:\sftproot
Subsystem sftp sftp-server.exe -d "c:\sftproot"
#Make this the rootdirectory, when accessing by SFtp
ChrootDirectory c:\sftproot 
#

Allow or deny connections

The OpenSSH server in windows is configured in this file. It also allows you to connect it’s unix style of configuration to the windows styte of security. You can use windows security to tie op windows groups to this file based security. To do so you will use the directives DenyUsers, AllowUsers, DenyGroups and AllowGroups in de configuration file.
Note that these directives are processed top to bottom in the configuration file. If one of them is processed, and you will get access or are denied access, other directives will not be processed anymore.

Also, place DenyUsers, AllowUsers, DenyGroups and AllowGroups before the Match Group Administrators directive for the same reason.

Examples:

DenyUsers     contoso\admin@192.168.2.23
DenyUsers     contoso\*
AllowGroups   contoso\sshusers contoso\serveroperators

Or:

AllowUsers    localuser@192.168.2.23
AllowGroups   sshusers

Remark: Specify account name in lowercase only. Specify domain accounts in UPN format, replacing @ with ? to avoid conflcts with regular Linux expressions (Example: mve@aca.nl -> mve?aca*)

Restrict SFPT acces to a subfolder only

Use the ChrootDirectory directive to reach this goal.
This directive is only supported with sftp sessions. A remote session into cmd.exe wouldn’t honor the ChrootDirectory. To set up a sftp-only chroot server, set ForceCommand to internal-sftp. You may also set up scp with chroot, by implementing a custom shell that would only allow scp and sftp.

Logging

It’s considered good practice to use logging of the connections to your server. OpenSSH supports ETW (Event Tracing for Windows) based logging and file based logging. If you want to use file based logging, It’s controlled by the SyslogFacility and LogLevel directives in the configuration file. The logfiles will be save to the %ProgramData%\ssh\logs directory if you add below lines to your windows OpenSSL configuration file. If you leave out the Syslogfacility line, it will use ETW. But when using file based logging, you are responsible for cleanup!

SyslogFacility LOCAL0
LogLevel Debug 3

More Information

See https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_server_configuration for more information.