Setup OpenSSH (Cygwin) for public key authentication
It took me awhile to realize that my SSHD installation on my Windows 2012R2 was not ready yet to accept public key authentication, which is a key feature. If we want to automate some tasks we need passwordless authentication to our Windows 2012 R2 server.
By default sshd is running under Local System account and this is in conflict with implementation of public key authentication of OpenSSH in Cygwin. If you recollect from my last post, special account was created, called cyg_server:
*** Info: On Windows Server 2003, Windows Vista, and above, the *** Info: SYSTEM account cannot setuid to other users -- a capability *** Info: sshd requires. You need to have or to create a privileged *** Info: account. This script will help you do so. *** Info: It's not possible to use the LocalSystem account for services *** Info: that can change the user id without an explicit password *** Info: (such as passwordless logins [e.g. public key authentication] *** Info: via sshd) when having to create the user token from scratch. *** Info: For more information on this requirement, see *** Info: https://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1 *** Info: If you want to enable that functionality, it's required to create *** Info: a new account with special privileges (unless such an account *** Info: already exists). This account is then used to run these special *** Info: servers. *** Info: Note that creating a new user requires that the current account *** Info: have Administrator privileges itself. *** Info: No privileged account could be found. *** Info: This script plans to use 'cyg_server'. *** Info: 'cyg_server' will only be used by registered services. *** Query: Do you want to use a different name? (yes/no) no *** Query: Create new privileged user account 'ACMEHOST\cyg_server' (Cygwin name: 'cyg_server')? (yes/no) yes *** Info: Please enter a password for new user cyg_server. Please be sure *** Info: that this password matches the password rules given on your system. *** Info: Entering no password will exit the configuration. *** Query: Please enter the password: mysecret *** Query: Reenter: *** Info: User 'cyg_server' has been created with password 'mysecret'.
The important info is this:
*** Info: It’s not possible to use the LocalSystem account for services
*** Info: that can change the user id without an explicit password
*** Info: (such as passwordless logins [e.g. public key authentication]
*** Info: via sshd) when having to create the user token from scratch.
So, the first thing that we need to do is to stop “CYGWIN sshd” service and change logon account for the sshd service as shown on the following screenshots:
At this point you can not start the service yet, if you try you’ll find in /var/log/sshd.log the following error:
/var/empty must be owned by root and not group or world-writable.
What we need to do is to change owner of the directory /var/empty from SYSTEM to cyg_server. Open cygwin.bat and run:
// check current permissions $ ls -al /var/empty total 0 drwx------+ 1 SYSTEM ACMEHOST+None 0 Mar 6 12:10 . drwxr-xr-x+ 1 alesk ACMEHOST+None 0 Mar 6 12:10 .. or with: $ getfacl /var/empty # file: /var/empty # owner: SYSTEM # group: ACMEHOST+None user::rwx group::--- other:--- default:user::rwx default:group::r-x default:other:r-x // So I tried to change the owner to cyg_server: $ chown cyg_server /var/empty invalid user cyg_server // What? At first I didn't know why is cyg_server invalid, but then // I realized that I added only one (my) account in /etc/passwd, so I // need to append cyg_server user as well: $ mkpasswd -l -u cyg_server >> /etc/passwd // restared cygwin.bat shell and run $ chown ACMEHOST+cyg_server /var/empty Remember that by default username is prefixed by hostname. // if you ever wish to change back to Local System account, // all that is needed is to again change Service account // under which CYGWIN sshd is running and owner of /var/empty: $ chown SYSTEM /var/empty
At this point you should be able to start “CYGWIN sshd” service under local cyg_server account. The last thing you need to do is to test the connection with public key authentication. I used Mobaxterm for that on my workstation ACMEWKS, but you could as easily use Cygwin SSH on your workstation:
In MobaXterm window:
We need to generate some public-private keys. Note that in our case we need PK keys for passwordless authentication, so we didn't password protect rsa private key in the example that follows. [alesk.ACMEWKS] ? ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/mobaxterm/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/mobaxterm/.ssh/id_rsa. Your public key has been saved in /home/mobaxterm/.ssh/id_rsa.pub. The key fingerprint is: 9a:da:35:e8:ca:6a:14:e4:f0:8c:10:1c:21:41:fe:81 alesk@ACMEWKS The key's randomart image is: +--[ RSA 2048]----+ |**o | |=.o | |.E . | |. * . | | o S | | . + | | . + o | | .. + . . | | ...+.o | +-----------------+ Remember, that /home/mobxterm/.ssh is volatile, after you close the MobaXterm this directory is gone, so you should copy public/private keys to some local, permanent directory.... [alesk.ACMEWKS] ? ls -al /home/mobaxterm/.ssh total 5 drwx------ 1 alesk UsersGrp 0 Mar 5 15:46 . drwx------ 1 alesk UsersGrp 0 Mar 5 11:09 .. -rw------- 1 alesk UsersGrp 1675 Mar 5 15:46 id_rsa -rw-r--r-- 1 alesk UsersGrp 396 Mar 5 15:46 id_rsa.pub -rw-r--r-- 1 alesk UsersGrp 171 Mar 5 09:11 known_hosts [alesk.ACMEWKS] ? mkdir /cygdrive/g/ssh [alesk.ACMEWKS] ? cp /home/mobaxterm/.ssh/id_rsa* /cygdrive/g/ssh // copy public key to remote host [alesk.ACMEWKS] ? scp /cygdrive/g/ssh/id_rsa.pub alesk@ACMEHOST:~/.ssh // append previoulsy copied public key to authorized_keys on remote host $ ssh alesk@ACMEHOST 'cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys'
Now, we can try to connect from ACKMEWKS to ACMEHOST with PK authentication:
[alesk.ACMEWKS] ssh -i /cygdrive/g/ssh/id_rsa alesk@ACMEHOST
You should be logged on ACMEHOST without prompt for a password. Properly protect private key. Better yet, you should limit what someone can execute execute via passwordless ssh connection with the help of prefix in authorized_keys file for each public key (see this for an example).
And finally, you can troubleshoot ssh connection by turning on verbose mode (-v, -vvv), for example:
[alesk.ACMEWKS] ssh -vvv -i /cygdrive/g/ssh/id_rsa alesk@ACMEHOST