Cygwin SSHD PubKey Authentication
This is an older topic for me – SSH Server (sshd) on Windows 10.
There’s a built-in Windows feature for this (Windows 1809 and newer)
but in my case I need to run lots of
bash commands that the Windows
SSH server doesn’t support. (For that matter – the OpenSSHD project
didn’t meet my needs for the same reason – it uses a Windows Command shell
and it’s not convenient to spawn off a Cygwin bash shell from it.)
So today’s article is on how I fixed this problem.
The Cygwin SSH Server
Cygwin has a perfectly good SSH Server – you install it with:
ssh-host-config and generally everything sets up fine…
until I tried to use public key authentication
That actually turned out to be…challenging even in late 2020.
What was the problem?
- I initially ran the standard Cygwin SSHD setup with absolutely no deviation
from the defaults (in fact, I used
ssh-host-config -yto accept the defaults).
- I was able to login remotely as a regular user using password authentication.
- When I tried to use public key authentication I received the dreaded
(see this article for an example).
"seteuid :operation not permitted"
So the failing command for me was:
In that command the
ssh -i ~/.ssh/id_rsa abruce@[windows-host]
-ioption specifies the private key to use. In my
/etc/sshd_configfile I had disabled
PasswordAuthenticationand restarted the Cygwin SSH server – this means that there was no fallback if the public key authentication failed. I had also copied my corresponding public key (
~/.ssh/id_rsa.pub) to the Windows box and placed it in the
~/.ssh/authorized_keysfile (and set permission to
0600as required by the SSH server).
My SolutionSo here is my Recipe Which Worked:
Setup a separate user for Cygwin SSHD service.
Technically this probably isn’t necessary because by default Cygwin
Local Systemaccount to run the service; this account already has loads of permissions granted to it. However, IMO creating a separate user specifically for the Cygwin SSHD service made it easier for me to identify exactly which permissions I needed to set.
Create the Windows user.
I created a Windows user named
cygsshdand made it an Administrator.
Set User Rights.
I then also added specific user rights (permissions) via the
secpol.mscLocal Security Policy snapin tool. (You can run that command from an Elevated Command Prompt.) Inside the tool, expand the Local Policies / User Rights Assignment and set the following permissions for the new account:
Act as part of the operating system
Create a token object
Log on as a service
Replace a process level token
Remove Unnecessary Rights.
My new user should not be permitted to login
from the network or via Remote Desktop (Terminal Services). So
I explicitly deny these rights:
Deny access to this computer from the network
Deny log on through Remote Desktop Services
- Reboot! OK – this should not be truly necessary but I kept running into strange permission issues and rebooting did magically fix my problems. I’d do it again just to save aggravation.
- Create the Windows user. I created a Windows user named
Prepare Cygwin for your remote SSH users.
To keep things simple, let’s treat Cygwin like we would a Linux box – we need to have entries in
/etc/passwdfor our users. (See my Caveats section below.)
In my case I just have one local user that I want to login via SSH so I used the following from an Elevated Cygwin shell:
mkpasswd -l -u abruce >> /etc/passwd
I ran the same command for my Cygwin SSHD service user (
cygsshd) but it probably isn’t necessary. Here’s the command for that user:
mkpasswd -l -u cygsshd >> /etc/passwd
Rerun Cygwin SSH Server Setup.
For this I simply specified to use the
cygsshduser I created above:
In the above replace
ssh-host-config -y --user cygsshd --pwd [the_password]
[the_password]with the Windows password you assigned to the
cygsshduser. This command runs with all of the default values other than then
Start the Cygwin SSH Server.
The Cygwin SSH Server is installed as a Windows Service by the
ssh-host-configcommand. Start that service and verify it runs correctly.
Troubleshoot the process.
Running the above recipe should have been all that was necessary.
It was not. While my actions “fixed” the
I initially had – I still could not login as my local user. The errors
were that my Windows “home” directory (
C:\Users\abruce in my
case) had “bad ownership or modes”. There is a
great article on this but the problem was that the first listed command (
chmod go-w ~/)
failed with a Permission Denied error.
First Step: Run the SSH Server in Debug Mode. The first step in debugging any SSH Server failure is to run the SSH Server in debug mode. Here’s how:
- Stop the Cygwin SSH Service if it is running.
- Open a Cygwin shell as the
- Run the SSH Server manually:
seteuidproblem and (second!) that my
C:\Users\abrucehomd directory permissions had “bad ownership or modes.”
So my second set of problems turned out to be Windows Permissions on my own home directory!
For some reason the owner of
C:\Users\abruce was actually the Windows
SYSTEM account. I fixed by using Windows Explorer to get the
Security properties on that account:
First – Windows reported that security permissions were “mis-ordered”
– but because my user account wasn’t the owner and didn’t have control
of my home directory I couldn’t fix it. So I had to use the “Change Owner”
function from the Windows Explorer advanced security properties. There
were a lot of subfolders (like
Application Data) that failed for me to take ownership but this turned out to be just an annoyance and not a blocker.
- Grant Full Control. Once I had ownership of my home directory I promptly let Windows “fix” the “mis-ordered” security permissions and then I took Full Control of my home directory and all lower-level folders. Again – I got a number of errors during this process as when I took ownership these popup errors turned out not to be blockers. (Thanks, Microsoft.)
Verify Cygwin Permission on the home directory.
After doing both the above steps – I *still* had the same “bad ownership
or modes” message. Fudge! The final step turned out to be that my actual
Cygwin Permissions on my own home folder were incorrect (I assure
you I never set those permissions on my own – go figure). The answer? Run
the following from an Elevated Cygwin shell (so you have admin privileges):
- Change to the directory. In my case:
- Set the directory permissions using the Cygwin command:
chmod 0750 .
- Change to the directory. In my case:
Success!After performing all of the above steps I could finally login to my Cygwin SSH server - running as a Windows Service - using Public Key authentication.
CaveatsNote in this article I'm just working with local users - if you have a domain setup then things will be different. For example, you wouldn't necessarily have an entry for your users in
/etc/passwdas domain logins are handled differently. YMMV.