Nodejitsu

Save time managing and deploying your node.js app. Code faster with jitsu and npm

Announcing doorkeeper

About the author

Name
Location
Worldwide
nodejitsu nodejitsu

Working at Nodejitsu has taught me few important things. One of them is that
when running at scale, nothing is easy anymore. Small problems might become
huge and escalate surprisingly quickly. Things I didn't even think about before
wind up being a challenge.

One of those things I didn't even think about before is managing SSH keys
(authorized_keys) across machines. As easy as "just fetch them from somewhere with curl" seems, it doesn't scale up to thousands of servers.

Needless to say, I was really happy to see that Joyent implemented a solution
for this problem, called SmartLogin.
SmartLogin is implemented using PubKeyPlugin patch.
However, Joyent's solutions has two downsides:

  • only runs on SmartOS,
  • patch was never merged into OpenSSH upstream.

At Nodejitsu we still run some Linux servers in our network, mainly for
handling services like Redis and CouchDB. Maintaining a floating patch for
OpenSSH is out of the question due to security implications.

Enter: AuthorizedKeysCommand

While PubKeyPlugin patch never got merged into OpenSSH, a similar patch
adding AuthorizedKeysCommand
option was actually released in OpenSSH 6.2.
How it works is, when OpenSSH daemon receives a login try, it spawns a command
with first parameter being the username and expects output in syntax of
authorized_keys file. It then checks if the supplied key matches any of outputted keys.

Enter: doorkeeper

I decided to took a stub at a command which would use composer
service and fetch keys saved in our database.
It was simple enough, since composer has /keys endpoint, which outputs all
all keys for all users.

This resulted in this project.

Try it out!

You should give doorkeeper a try! You're going to need a Linux server with
OpenSSH 6.2 installed. If it isn't installed, you can fetch source code and
install it manually:

curl http://ftp5.usa.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-6.2p1.tar.gz | tar -zx  
cd openssh-6.2p1  
./configure --prefix=/usr --sysconfdir=/etc/ssh
make  
sudo make install  

Then, to configure doorkeeper, edit /etc/ssh/sshd_config to contain
following entries:

AuthorizedKeysCommand /usr/bin/doorkeeper  
AuthorizedKeysCommandUser root  

Replace AuthorizedKeysCommand value with path to your installation of doorkeeper
and AuthorizedKeysCommandUser value with user you want doorkeeper to run as.

You need a composer instance running
with your keys in it. You can either use baton to add them (baton addkey) or
use the POST /users/:username/keys endpoint with body in the following format:

{
  "key": "ssh-rsa ..."
}

If you have quill installed and configured in the context of user doorkeeper
is running as, doorkeeper needs no configuration. If you don't, you can
put config in the following places: /etc/doorkeeper, $HOME/.quillconf or
/root/.quillconf, in the following format:

{
  "remoteHost": "<your composer host>",
  "port": <your composer port>
}

You can test your installation by simply executing doorkeeper. It should
output all the keys present in composer.

Now, if you feel confident, restart SSH service. If everything is properly
configured, it should start using doorkeeper to source keys.

If you run into any problems with installing doorkeeper, feel free to e-mail
me at maciej@nodejitsu.com or tweet at @maciejmalecki.