authorized_keys file and explicit enabling of PubkeyAuthentication in the sshd_config file. Once these settings are corrected, you can authenticate securely without a password.
Understanding the OpenSSH Server on Windows
Windows 10 version 1809 and later, as well as Windows 11, include an optional OpenSSH Server feature. Unlike Linux, where this is often pre-configured with sensible defaults, the Windows implementation requires manual verification of several components. If you attempt to connect using a private key and receive a "Permission denied" or "Publickey authentication failed" error, the issue almost always lies in how the server validates the incoming key against the user's profile.
The core mechanism relies on the sshd.exe service reading a configuration file located at C:\ProgramData\ssh\sshd_config. This file dictates which authentication methods are allowed. By default, many installations may have PubkeyAuthentication set to no or commented out, effectively disabling key-based logins even if your client has the correct key installed.
Verifying Service Status and Permissions
Before editing configuration files, ensure the underlying service is running and has the necessary privileges to access user directories. The OpenSSH server runs under the SYSTEM account by default, which allows it to read all user profiles, but it must be able to write logs and manage the SSH host keys.
- Open PowerShell as Administrator.
- Run
Get-Service sshdto check the status. It should showRunning. - If the service is stopped, start it with
Start-Service sshd. - Ensure the startup type is set to automatic using
Set-Service -Name sshd -StartupType 'Automatic'.
If the service fails to start, check the event viewer or the log file at C:\ProgramData\ssh\logs\sshd.log for immediate errors. This log provides critical insights into why the daemon might refuse connections, including issues with invalid host keys or permission denials on the configuration directory itself.
Configuring sshd_config for Key Authentication
The most common cause of failure is an incorrect or missing directive in the main configuration file. You must edit C:\ProgramData\ssh\sshd_config with administrative privileges. Locate the line that specifies PubkeyAuthentication.
# PubkeyAuthentication yes
PubkeyAuthentication yes
Ensure that this line is not commented out (remove the # symbol) and is explicitly set to yes. Additionally, verify that PasswordAuthentication is configured according to your security policy, though this does not directly affect key login success. After making changes, you must restart the SSH service for them to take effect:
Restart-Service sshd
If you are experiencing issues with older configurations or migration from legacy systems, refer to Pageant Fails to Generate OpenSSH Config for troubleshooting related agent and configuration generation problems.
Setting Up authorized_keys Correctly
Even with the server configured correctly, the client's public key must be placed in the correct location with the correct permissions. On Windows, each user has their own SSH directory structure. For the current user, this is typically %USERPROFILE%\.ssh\.
- Navigate to
%USERPROFILE%\.ssh\. - Create a file named
authorized_keysif it does not exist. - Append your public key (from
id_rsa.puborid_ed25519.pub) to this file. Each key must be on a single line.
Permissions are strict on Windows. The SYSTEM and Administrators groups must have Full Control, while other users should have no access or only Read & Execute. If the permissions are too open, sshd will ignore the file for security reasons. You can set these permissions via the GUI or PowerShell:
icacls "$env:USERPROFILE\.ssh\authorized_keys" /inheritance:r /grant SYSTEM:(F) /grant Administrators:(F)
This command removes inherited permissions and grants full control only to SYSTEM and Administrators, ensuring the integrity of the authentication process.
Testing the Connection
Once the configuration and key files are set, test the connection from a client machine. Use the verbose flag to see exactly where the authentication fails:
ssh -v username@windows_host_ip
In the verbose output, look for the line Offering public key followed by Server accepts key. If the server rejects the key, check the sshd.log on the Windows machine for detailed rejection reasons, such as key format errors or mismatched usernames.
For advanced scenarios involving proxy chains or persistent connections, consider reviewing Setting Persistent Reverse SSH SOCKS Proxies on Windows to understand how SSH tunnels interact with Windows network stacks.
Frequently Asked Questions
Why does SSH still ask for a password after enabling PubkeyAuthentication?
If the server falls back to password authentication, it usually means the public key was not found in the authorized_keys file or the file permissions were rejected. Verify that the key exists in the correct user's .ssh directory and that the permissions match the requirements outlined above. Ensure you are connecting with the exact username that owns the authorized_keys file.
Can I use PuTTY keys (.ppk) with the native Windows OpenSSH server?
No, the native Windows OpenSSH server expects keys in the standard OpenSSH format (PEM or SSH2). PuTTY uses its own proprietary format. You must convert your .ppk file to an OpenSSH compatible key using PuTTYgen before adding it to the authorized_keys file on the Windows server.
How do I reset the SSH host keys on Windows?
If you suspect host key mismatches are causing connection issues, delete the files in C:\ProgramData\ssh\ssh_host_*_key and C:\ProgramData\ssh\ssh_host_*_key.pub. Then, restart the sshd service. The service will automatically regenerate new host keys upon next startup.
Is it safe to disable PasswordAuthentication entirely?
Disabling PasswordAuthentication enhances security by preventing brute-force attacks against weak passwords. However, ensure that you have a reliable method for key management and that you have an alternative way to access the machine (like RDP) if you lock yourself out due to misconfigured keys.
What if I get a "Connection refused" error instead of an authentication error?
A "Connection refused" error indicates that the SSH service is not listening on port 22 or is blocked by a firewall. Check that the sshd service is running and that Windows Firewall allows inbound traffic on TCP port 22. Run Test-NetConnection -ComputerName localhost -Port 22 from the server itself to verify local accessibility.