An SSH public keyserver

Posted by Chris Ball Mon, 15 Sep 2008 05:36:00 GMT

I spent a few nights working on a web site recently — it's a public OpenSSH keyserver, in the style of the OpenPGP keyservers, and it's up now. I'd like to attempt to persuade you all to consider uploading your public SSH keys to http://sshkeys.net/, for a few reasons:

  • If you publish your public key, it's going to be easy for people setting up accounts for you in the future to find it, with a simple wget sshkeys.net/you@yourdomain.com.

  • If you manage machines, having your potential users upload keys to the site should save your time by making sure they get past problems like uploading the wrong file, since the site will tell them if they try to upload anything other than a public key.

  • There should be side benefits of having a large repository of SSH public keys: I think we would have detected the recent Debian/OpenSSL randomness bug sooner if we'd been on the lookout for unexpected duplicate keys, for example.

I used Django for the site and it was shockingly effortless, to the point where I didn't have to write any SQL or interact with the database manually. I wrote the following model, which says that there are Addresses, Keys, and combinations of Address and Key that have some extra fields like whether they've been verified against the supplied e-mail address or not:

class Address (models.Model):
    address = models.CharField(max_length=255)
    def __unicode__(self):
        return self.address

class SSHKey (models.Model):
    owners = models.ManyToManyField(Address, through='AddressKey')
    keytext = models.CharField(max_length=1024)
    def __unicode__(self):
        return self.keytext

class AddressKey:
    address = models.ForeignKey(Address)
    sshkey = models.ForeignKey(SSHKey)
    date_added = models.DateTimeField('date added')
    verified = models.BooleanField(default=False)
    token = models.CharField(max_length=40)
    token_sent = models.DateTimeField()

After that, it all just worked. The gap between having it all working in the Admin interface (time taken: 3 hours) and having it all working with production views was much larger, though. The Admin interface is full of beautiful widgets that are not at all re-usable in your production site.

The full code's available over at github (under AGPLv3). I'd be very happy to get patches to make it smarter, and let me know if you find any bugs. Thanks!

Tags , , ,  | 23 comments