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
(pubkeyauthentication
in /etc/sshd_config
).
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 -y
to 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:
ssh -i ~/.ssh/id_rsa abruce@[windows-host]
In that command the -i
option specifies the private key to use.
In my /etc/sshd_config
file I had disabled
PasswordAuthentication
and 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_keys
file (and set permission to 0600
as required by the SSH
server).
Fixing this problem was a bit of a rabbit hole as Windows helpfully makes things pretty difficult in terms of user context and permissions and Cygwin had also helpfully fudged up some of the NT permissions on my home directory.
My Solution
So here is my Recipe Which Worked:-
Setup a separate user for Cygwin SSHD service.
Technically this probably isn’t necessary because by default Cygwin
uses the
Local System
account 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
cygsshd
and made it an Administrator. -
Set User Rights.
I then also added specific user rights (permissions) via the
secpol.msc
Local 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/passwd
for 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
cygsshd
user I created above:
In the above replacessh-host-config -y --user cygsshd --pwd [the_password]
[the_password]
with the Windows password you assigned to thecygsshd
user. This command runs with all of the default values other than then--user
option. -
Start the Cygwin SSH Server.
The Cygwin SSH Server is installed as a Windows Service by the
ssh-host-config
command. 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 seteuid
problem
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
cygsshd
Windows user. - Run the SSH Server manually:
/usr/sbin/sshd -ddd
seteuid
problem and (second!) that my
C:\Users\abruce
homd 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:
-
Take Ownership.
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:
cd /cygdrive/c/Users/abruce
- 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.Caveats
Note 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/passwd
as domain logins
are handled differently. YMMV.
Leave a Reply