From the Canyon Edge -- :-Dustin
Showing posts with label ssh-import-id. Show all posts
Showing posts with label ssh-import-id. Show all posts

Friday, February 16, 2018

10 Amazing Years of Ubuntu and Canonical

February 2008, Canonical's office in Lexington, MA
10 years ago today, I joined Canonical, on the very earliest version of the Ubuntu Server Team!

And in the decade since, I've had the tremendous privilege to work with so many amazing people, and the opportunity to contribute so much open source software to the Ubuntu ecosystem.

Marking the occasion, I've reflected about much of my work over that time period and thought I'd put down in writing a few of the things I'm most proud of (in chronological order)...  Maybe one day, my daughters will read this and think their daddy was a real geek :-)

1. update-motd / motd.ubuntu.com (September 2008)

Throughout the history of UNIX, the "message of the day" was always manually edited and updated by the local system administrator.  Until Ubuntu's message-of-the-day.  In fact, I received an email from Dennis Ritchie and Jon "maddog" Hall, confirming this, in April 2010.  This started as a feature request for the Landscape team, but has turned out to be tremendously useful and informative to all Ubuntu users.  Just last year, we launched motd.ubuntu.com, which provides even more dynamic information about important security vulnerabilities and general news from the Ubuntu ecosystem.  Mathias Gug help me with the design and publication.

2. manpages.ubuntu.com (September 2008)

This was the first public open source project I worked on, in my spare time at Canonical.  I had a local copy of the Ubuntu archive and I was thinking about what sorts of automated jobs I could run on it.  So I wrote some scripts that extracted the manpages out of each one, formatted them as HTML, and published into a structured set of web directories.  10 years later, it's still up and running, serving thousands of hits per day.  In fact, this was one of the ways we were able to shrink the Ubuntu minimal image, but removing the manpages, since they're readable online.  Colin Watson and Kees Cook helped me with the initial implementation, and Matthew Nuzum helped with the CSS and Ubuntu theme in the HTML.

3. Byobu (December 2008)

If you know me at all, you know my passion for the command line UI/UX that is "Byobu".  Byobu was born as the "screen-profiles" project, over lunch at Google in Mountain View, in December of 2008, at the Ubuntu Developer Summit.  Around the lunch table, several of us (including Nick Barcet, Dave Walker, Michael Halcrow, and others), shared our tips and tricks from our own ~/.screenrc configuration files.  In Cape Town, February 2010, at the suggestion of Gustavo Niemeyer, I ported Byobu from Screen to Tmux.  Since Ubuntu Servers don't generally have GUIs, Byobu is designed to be a really nice interface to the Ubuntu command line environment.

4. eCryptfs / Ubuntu Encrypted Home Directories (October 2009)

I was familiar with eCryptfs from its inception in 2005, in the IBM Linux Technology Center's Security Team, sitting next to Michael Halcrow who was the original author.  When I moved to Canonical, I helped Michael maintain the userspace portion of eCryptfs (ecryptfs-utils) and I shepherded into Ubuntu.  eCryptfs was super powerful, with hundreds of options and supported configurations, but all of that proved far to difficult for users at large.  So I set out to simplify it drastically, with an opinionated set of basic defaults.  I started with a simple command to mount a "Private" directory inside of your home directory, where you could stash your secrets.  A few months later, on a long flight to Paris, I managed to hack a new PAM module, pam_ecryptfs.c, that actually encrypted your entire home directory!  This was pretty revolutionary at the time -- predating Apple's FileVault or Microsoft's Bitlocker, even.  Today, tens of millions of Ubuntu users have used eCryptfs to secure their personal data.  I worked closely with Tyler Hicks, Kees Cook, Jamie Strandboge, Michael Halcrow, Colin Watson, and Martin Pitt on this project over the years.

5. ssh-import-id (March 2010)

With the explosion of virtual machines and cloud instances in 2009 / 2010, I found myself constantly copying public SSH keys around.  Moreover, given Canonical's globally distributed nature, I also regularly found myself asking someone for their public SSH keys, so that I could give them access to an instance, perhaps for some pair programming or assistance debugging.  As it turns out, everyone I worked with, had a Launchpad.net account, and had their public SSH keys available there.  So I created (at first) a simple shell script to securely fetch and install those keys.  Scott Moser helped clean up that earliest implementation.  Eventually, I met Casey Marshall, who helped rewrite it entirely in Python.  Moreover, we contacted the maintainers of Github, and asked them to expose user public SSH keys by the API -- which they did!  Now, ssh-import-id is integrated directly into Ubuntu's new subiquity installer and used by many other tools, such as cloud-init and MAAS.

6. Orchestra / MAAS (August 2011)

In 2009, Canonical purchased 5 Dell laptops, which was the Ubuntu Server team's first "cloud".  These laptops were our very first lab for deploying and testing Eucalyptus clouds.  I was responsible for those machines at my house for a while, and I automated their installation with PXE, TFTP, DHCP, DNS, and a ton of nasty debian-installer preseed data.  That said -- it worked!  As it turned out, Scott Moser and Mathias Gug had both created similar setups at their houses for the same reason.  I was mentoring a new hire at Canonical, named Andres Rodriquez at the time, and he took over our part-time hacks and we worked together to create the Orchestra project.  Orchestra, itself was short lived.  It was severely limited by Cobbler as a foundation technology.  So the Orchestra project was killed by Canonical.  But, six months later, a new project was created, based on the same general concept -- physical machine provisioning at scale -- with an entire squad of engineers led by...Andres Rodriguez :-)  MAAS today is easily one of the most important projects the Ubuntu ecosystem and one of the most successful products in Canonical's portfolio.

7. pollinate / pollen / entropy.ubuntu.com (February 2014)

In 2013, I set out to secure Ubuntu at large from a set of attacks ranging from insufficient entropy at first boot.  This was especially problematic in virtual machine instances, in public clouds, where every instance is, by design, exactly identical to many others.  Moreover, the first thing that instance does, is usually ... generate SSH keys.  This isn't hypothetical -- it's quite real.  Raspberry Pi's running Debian were deemed susceptible to this exact problem in November 2015.  So designed and implemented a client (shell script that runs at boot, and fetches some entropy from one to many sources), as well as a high-performance server (golang).  The client is the 'pollinate' script, which runs on the first boot of every Ubuntu server, and the server is the cluster of physical machines processing hundreds of requests per minute at entropy.ubuntu.com.  Many people helped review the design and implementation, including Kees Cook, Jamie Strandboge, Seth Arnold, Tyler Hicks, James Troup, Scott Moser, Steve Langasek, Gustavo Niemeyer, and others.

8. The Orange Box (May 2014)

In December of 2011, in my regular 1:1 with my manager, Mark Shuttleworth, I told him about these new "Intel NUCs", which I had bought and placed them around my house.  I had 3, each of which was running Ubuntu, and attached to a TV around the house, as a media player (music, videos, pictures, etc).  In their spare time, though, they were OpenStack Nova nodes, capable of running a couple of virtual machines.  Mark immediately asked, "How many of those could you fit into a suitcase?"  Within 24 hours, Mark had reached out to the good folks at TranquilPC and introduced me to my new mission -- designing the Orange Box.  I worked with the Tranquil folks through Christmas, and we took our first delivery of 5 of these boxes in January of 2014.  Each chassis held 10 little Intel NUC servers, and a switch, as well as a few peripherals.  Effectively, it's a small data center that travels.  We spend the next 4 months working on the hardware under wraps and then unveiled them at the OpenStack Summit in Atlanta in May 2014.  We've gone through a couple of iterations on the hardware and software over the last 4 years, and these machines continue to deliver tremendous value, from live demos on the booth, to customer workshops on premises, or simply accelerating our own developer productivity by "shipping them a lab in a suitcase".  I worked extensively with Dan Poler on this project, over the course of a couple of years.

9. Hollywood (December 2014)

Perhaps the highlight of my professional career came in October of 2016.  Watching Saturday Night Live with my wife Kim, we were laughing at a skit that poked fun at another of my favorite shows, Mr. Robot.  On the computer screen behind the main character, I clearly spotted Hollywood!  Hollywood is just a silly, fun little project I created on a plane one day, mostly to amuse Kim.  But now, it's been used in Saturday Night LiveNBC Dateline News, and an Experian TV commercials!  Even Jess Frazelle created a Docker container

10. petname / golang-petname / python-petname (January 2015)

From "warty warthog" to "bionic beaver", we've always had a focus on fun, and user experience here in Ubuntu.  How hard is it to talk to your colleague about your Amazon EC2 instance, "i-83ab39f93e"?  Or your container "adfxkenw"?  We set out to make something a little more user-friendly with our "petnames".  Petnames are randomly generated "adjective-animal" names, which are easy to pronounce, spell, and remember.  I curated and created libraries that are easily usable in Shell, Golang, and Python.  With the help of colleagues like Stephane Graber and Andres Rodriguez, we now use these in many places in the Ubuntu ecosystem, such as LXD and MAAS.

If you've read this post, thank you for indulging me in a nostalgic little trip down memory lane!  I've had an amazing time designing, implementing, creating, and innovating with some of the most amazing people in the entire technology industry.  And here's to a productive, fun future!

Cheers,
:-Dustin

Friday, February 17, 2017

HOWTO: Automatically import your public SSH keys into LXD Instances

Just another reason why LXD is so awesome...

You can easily configure your own cloud-init configuration into your LXD instance profile.

In my case, I want cloud-init to automatically ssh-import-id kirkland, to fetch my keys from Launchpad.  Alternatively, I could use gh:dustinkirkland to fetch my keys from Github.

Here's how!

First, edit your default LXD profile (or any other, for that matter):

$ lxc profile edit default

Then, add the config snippet, like this:

config:
  user.vendor-data: |
    #cloud-config
    users:
      - name: root
        ssh-import-id: gh:dustinkirkland
        shell: /bin/bash
description: Default LXD profile
devices:
  eth0:
    name: eth0
    nictype: bridged
    parent: lxdbr0
    type: nic
name: default

Save and quit in your interactive editor, and then launch a new instance:

$ lxc launch ubuntu:x
Creating amazed-manatee
Starting amazed-manatee

Find your instance's IP address:

$ lxc list
+----------------+---------+----------------------+----------------------------------------------+------------+-----------+
|      NAME      |  STATE  |         IPV4         |                     IPV6                     |    TYPE    | SNAPSHOTS |
+----------------+---------+----------------------+----------------------------------------------+------------+-----------+
| amazed-manatee | RUNNING | 10.163.22.135 (eth0) | fdce:be5e:b787:f7d2:216:3eff:fe1c:773 (eth0) | PERSISTENT | 0         |
+----------------+---------+----------------------+----------------------------------------------+------------+-----------+

And now SSH in!

$ ssh ubuntu@10.163.22.135
$ ssh -6 ubuntu@fdce:be5e:b787:f7d2:216:3eff:fe1c:773

Enjoy!
:-Dustin

Friday, February 15, 2013

ssh-import-id now supports -r|--remove keys

As a brief followup to my recent post about ssh-import-id now supporting Github in addition to Launchpad, I should also mention that I've also added a new feature for removing keys that were previously imported.

Here's an example, importing kirkland's public keys from Launchpad.

kirkland@x220:~$ ssh-import-id lp:kirkland
2013-02-15 14:53:46,092 INFO Authorized key ['4096', 'd3:dd:e4:72:25:18:f3:ea:93:10:1a:5b:9f:bc:ef:5e', 'kirkland@x220', '(RSA)']
2013-02-15 14:53:46,101 INFO Authorized key ['2048', '69:57:f9:b6:11:73:48:ae:11:10:b5:18:26:7c:15:9d', 'kirkland@mac', '(RSA)']
2013-02-15 14:53:46,102 INFO Authorized [2] SSH keys

And now let's remove those keys...

kirkland@x220:~$ ssh-import-id -r lp:kirkland
2013-02-15 14:53:49,528 INFO Removed labeled key ['4096', 'd3:dd:e4:72:25:18:f3:ea:93:10:1a:5b:9f:bc:ef:5e', 'kirkland@x220', '(RSA)']
2013-02-15 14:53:49,532 INFO Removed labeled key ['2048', '69:57:f9:b6:11:73:48:ae:11:10:b5:18:26:7c:15:9d', 'kirkland@mac', '(RSA)']
2013-02-15 14:53:49,532 INFO Removed [2] SSH keys

Neat!

So the way this works is that ssh-import-id now adds a comment to the end of each line it adds to your ~/.authorized_keys file, "tagging" the keys that it adds.  When removing keys, it simply looks for keys tagged accordingly.

Enjoy!

:-Dustin

Tuesday, February 5, 2013

ssh-import-id now supports Github!

tl;dr

As of ssh-import-id 3.0, you can now import SSH public keys from both Launchpad and Github using lp:$USER and gh:$USER like this:

$ ssh-import-id lp:kirkland gh:cmars
2013-02-05 17:54:15,638 INFO Authorized key ['4096', 'd3:dd:e4:72:25:18:f3:ea:93:10:1a:5b:9f:bc:ef:5e', 'kirkland@x220', '(RSA)']
2013-02-05 17:54:15,647 INFO Authorized key ['2048', '69:57:f9:b6:11:73:48:ae:11:10:b5:18:26:7c:15:9d', 'kirkland@mac', '(RSA)']
2013-02-05 17:54:22,125 INFO Authorized key ['2048', '84:df:01:9f:da:d3:ef:7d:a0:44:17:ff:ab:30:15:22', 'cmars@github/2114943', '(RSA)']
2013-02-05 17:54:22,134 INFO Authorized key ['2048', 'ab:6a:0c:99:09:49:0b:8f:2a:12:e2:f3:3d:c7:a9:79', 'cmars@github/3263683', '(RSA)']
2013-02-05 17:54:22,135 INFO Authorized [4] new SSH keys
This is now available in Ubuntu Raring 13.04, backported to all other supported Ubuntu releases in this PPA, in the upstream source tarballs, and now installable through pip from pypi!

Background

It's been almost 3 years now since I introduced ssh-import-id here on this blog.  I have a Google Alert setup to watch ssh-import-id and I'm delighted to see that it seems to be quite popular and heavily used!

As a brief reintroduction, ssh-import-id is similar to the ssh-copy-id command.  Whereas ssh-copy-id pushes your public key into a remote ~/.ssh/authorized_keys file, ssh-import-id pulls a public key into the local ~/.ssh/authorized_keys.  Especially in cloud instances, it's a great way to securely, easily, and conveniently retrieve and install your own SSH public key, or perhaps that of a friend or colleague.

When I initially wrote it, it was really just a simple shell script wrapper around wget, with some error checking, that would pull public keys over an SSL connection from Launchpad.net.  All of my network friends and colleagues had active, authenticated accounts at Launchpad.net, and everyone had to upload their public GPG keys and public SSH keys to Launchpad in order to get any work done.  This was really easy, since all keys are available as flat text at a very predictable URL pattern: https://launchpad.net/~%s/+sshkeys.

I have always wanted ssh-import-id to be able to pull keys from servers other than Launchpad.  The tool has long supported defining a $URL in your environment or in /etc/ssh/ssh_import_id at the system level.  There just aren't really any other good, authenticated SSH public key servers.

Github

A few days ago, my friend and Gazzang colleague Casey Marshall noticed that Github had actually recently added support to their API which exposes public SSH keys!  This was just awesome :-)  It would take a bit of effort to support, though, as the output format differs between Launchpad (raw text) and Github (JSON).

So this past Saturday on a beautiful evening in Austin, TX (when neither of us should really have been hacking), we both independently initiated our own implementation adding support for Github keys in ssh-import-id :-)  A bit of duplicated effort?  Yeah, oh well...  But we both took a similar approach: let's port this puppy from shell to Python so that we can take advantage of JSON parsing (our alternative was awk!).

Python

My approach was pretty elementary...  I basically implemented a line-by-line, function-by-function port from Shell to Python, since I knew, from a regression standpoint, this would be stable, solid code.  But Casey is undoubtedly the better programmer between the two of us :-)  He took a much more Pythonic approach, implementing each of the protocol handlers as sub commands.

Once we caught up with one another online around midnight Saturday night, we realized that we really duplicating efforts.  So we decided to team up on the problem!  Casey had a much more elegant design, complete with a setup.py and uploadable to pypi.python.org.  Meanwhile, I have maintained the source code and the package in Ubuntu for nearly 3 years and I understood the complex set of legacy compatibility I needed to preserve, as well as several years worth of gotchas and bugs-fixed.  So I took Casey's implementation, whole hog, and went to work on a bunch of little things to get it whipped into shape for upload to Ubuntu.

Portability

Given that Github is now supported in addition to Launchpad, there may actually be some interest in the tool beyond Ubuntu.  Non-Ubuntu users can now install ssh-import-id directly from pypi.python.org!

$ sudo pip install ssh-import-id
Downloading/unpacking ssh-import-id
  Running setup.py egg_info for package ssh-import-id
    
Requirement already satisfied (use --upgrade to upgrade): argparse in /usr/lib/python2.7 (from ssh-import-id)
Downloading/unpacking Requests >=1.1.0 (from ssh-import-id)
  Running setup.py egg_info for package Requests
    
Installing collected packages: ssh-import-id, Requests
  Running setup.py install for ssh-import-id
    
    changing mode of /usr/local/bin/ssh-import-id-lp to 775
    changing mode of /usr/local/bin/ssh-import-id to 775
    changing mode of /usr/local/bin/ssh-import-id-gh to 775
  Running setup.py install for Requests
    
Successfully installed ssh-import-id Requests
Cleaning up...

Other New Features

We've added a few other new features in the 3.x series...
  1. We now detect duplicate keys by their size/fingerprint/type, and avoid adding duplicates
  2. We also now support a -r|--remove option, which you can use to prune keys from ~/.ssh/authorized_keys file that were added by ssh-import-id
Please report bugs as you find them here!  And please use StackExchange for questions!  Enjoy ;-)

:-Dustin

Wednesday, February 1, 2012

ssh-import-id gaining some steam


My Google Alerts and IRC highlights have been firing almost daily with references to ssh-import-id, a handy utility I co-authored with my buddy Scott Moser a couple of years ago.

That's quite exciting to me actually, as I find the tool really, really useful, and I wish more people knew about it.  I tried in vain to contribute it to the OpenSSH project, as a complement to ssh-copy-id, but it never landed there.  Oh well.  There's rarely a day that goes by that I don't use it, actually.  I frequently use virtual machines in public clouds;  usually EC2 but not exclusively.  I often want to share that machine with a colleague.  Rather than sharing a password, I simply:

$ ssh-import-id edygarcia sergio-pena
INFO: Successfully authorized [edygarcia] 
INFO: Successfully authorized [sergio-pena]

And now, I just share the hostname or IP with Eddie and Sergio and they can SSH into this machine and authenticate using their SSH keypair.

Reviewing what actually happened...

  1. ssh-import-id looped over each of the arguments on the command line, which are typically Launchpad user IDs
  2. Fetched each user's public keys from https://launchpad.net/~/+sshkeys
  3. Validated each key's syntax
  4. And concatenated the results to the local ~/.ssh/authorized_keys file
The methodology is secure in that:
  • I know what each of my colleague's Launchpad IDs are, and that's easier to remember than their SSH fingerprints
  • I know that they had to authenticate with Launchpad to upload their SSH public keys
  • I know that the communication between my system and Launchpad was authenticated and private as it used https with a valid SSL certificate
Note that I've uploaded a couple of minor fixes to ssh-import-id in the last 2 weeks that more accurately validates the contents of the public keys retrieved from Launchpad (thanks, Soren for one of those).

You can always grab the latest version from ppa:launchpad/ssh-import-id, though perhaps I should SRU some of these changes to Lucid/Natty/Oneiric.  Anyone willing to test and validate those SRUs, if I propose and upload them?

Cheers,
:-Dustin

Monday, February 7, 2011

Update on errno, ssh-import-id, and bikeshed

If you read my post from earlier today about run-one, you might notice that I used a new source and binary package to publish the run-one utility.  This is a new practice that I'm going to use for stand-alone tools like this.

errno

It's worth mentioning that the errno utility has also moved out of ubuntu-dev-tools, at the strong request of the maintainer of ubuntu-dev-tools.  I tried (in vain) to get errno into various other packages and upstream projects, and failed in all cases.  As of Natty, you can:

 apt-get install errno

For older releases:

 sudo apt-add-repository ppa:errno/ppa
 sudo apt-get update
 sudo apt-get install errno

As a reminder, you can use errno in these ways:

 $ errno font
 EBFONT          59      /* Bad font file format */
 $ errno 36
 ENAMETOOLONG    36      /* File name too long */
 $ errno EPERM
 EPERM            1      /* Operation not permitted */


You can find the sources with:

 bzr branch lp:errno

And the launchpad project is at http://launchpad.net/errno.

ssh-import-id

Similarly, the maintainer of the openssh package in Ubuntu urged the removal of the ssh-import-id utility.  Once again, I offered the tool to the upstream openssh project, to no avail.  So ssh-import-id now lives in its own source and binary packages.  As of Natty, you can:

 apt-get install ssh-import-id


For older releases:

 sudo apt-add-repository ppa:ssh-import-id/ppa
 sudo apt-get update
 sudo apt-get install ssh-import-id


As a reminder, you can use ssh-import-id in this way:

  $ ssh-import-id kirkland smoser
 INFO: Successfully authorized [kirkland]
 INFO: Successfully authorized [smoser]

You can find sources with:

 bzr branch lp:ssh-import-id

And the launchpad project is at http://launchpad.net/ssh-import-id.
bikeshed

"So why didn't you just use bikeshed?"  Great question!  When I showed run-one to one of my colleagues, he said, "Neat, I'd use that, where can I get it?"  And I pointed him to install bikeshed, to which he responded, "Oh, well, I just want run-one, but not all the other cruft you put into bikeshed."  :-)

I tried not to be offended, but in the end, he was right.  I thought about splitting bikeshed into a series of bikeshed-$FOO binary packages.  This wasn't ideal, though, in my opinion, from the perspective of developing code or handling bugs/questions.

Thus, I've decided to create a new Launchpad project and team, and Ubuntu package for each of these stand-alone utilities.

I'll continue to use bikeshed to incubate new tools, and as soon as they're ready to stand alone, then I'll split them out to their own branch/project/team/package.

Cheers,
:-Dustin

Printfriendly