U2F is (yet another) 2/multi factor standard. Hopefully this time this one will stick. Yubikey have a nice explanation of how this works
Specifications are available at http://fidoalliance.org/specifications/download/ Google has added support for the U2F keys already and now @zekjur has a patch against OpenSSH6.7p1 to add support for U2F.
There’s a bug entry up at https://bugzilla.mindrot.org/show_bug.cgi?id=2319 for this. NOTE: This code hasn’t been peer reviewed AFAIK and i’m not sure about how they’re using the appid/origin part of the U2F specs here.
Unfortunately there seems to be an issue with U2F AND PAM support, so we’ll build OpenSSH without PAM support and run it along side the current install.
So here’s how we build this sucker on a debian/ubuntu based box:
First we need some build dependancies. The ubuntu packages you’ll need are:
libtool gtk-doc-tools pkg-config libjson0-dev libhidapi-hidraw0 libjson0-dev libhidapi-dev autoconf zlib1g-dev gengetopt help2man libssl-dev build-essential
We’ll need libu2f-host, which will give us the U2F USB host support we need on the client side. Obviously we’ll need the client to support this as well, so you’ll have to build this locally as well. For win64 users, have some cygwin64 built binaries (Although, the key registration seems to be broken with this binary, whoops)
Grab the master branch of libu2f-host from: https://github.com/Yubico/libu2f-host and build with
make ; sudo make install
Next grab the openssh6.7p1 source (Don’t forget to verify the source..) and apply the patch attached to the bug at https://bugzilla.mindrot.org/show_bug.cgi?id=2319 (You want the diff/raw unifed links..)
Copy the patch to the openssh-6.7p1 directory and patch with
patch -p1 <patchfilename. It should patch without any errors.
After patching, run
rm configure to get rid of the pre-u2f patch configure file and then run
autoconf -i to rebuild it.
Run the configure script with
./configure --with-u2f (and with any other options you want/need, remembering that with the current patch, PAM may be broken)
make ; sudo make install. By default this will install to /usr/local/ so be careful if you’re already running your sshd from there.
If we’re not replacing our normal sshd, edit /usr/local/etc/ssh/sshd_config and change the Port option to whatever port you’d like.
AuthenticationMethods password,u2f to the sshd_config file. (Replacing “password” with “publickey,password” or whatever you currently use. This will still look for publickeys in ~/.ssh/authorized_keys but it WON’T use any PAM auth methods)
Tweak the config however else you’d like.
Fire up the new sshd with
/usr/local/sbin/sshd, then on the client side plug in your U2F key (after you’ve built the client with U2F support, as above) and run
ssh -o U2FMode=registration my.server.example -p newport > /tmp/u2f-key.pub
Login with your usual credentials and touch the U2F key when prompted. It will error out with a “Permission denied” and dump the registration info into /tmp/u2f-key.pub. The contents of this file need to go into the users ~/.ssh/authorized_keys file on the server.
Once you’ve done then, you should be able to ssh to the new sshd port with your password/publickey and it will ask you to touch your U2F security key when appropriate. Do so and it should log you in. Yay!