April 2012 Archives

I will be attending the Ubuntu Developer Summit (UDS) next week in Oakland, CA.  This event brings people from around the world together in one place every six months to discuss and plan for the next release of Ubuntu.  The May 2012 UDS is for Ubuntu-Q which will eventually be named and become Ubuntu 12.10 when it is released in October (2012-10).

I’ve attended two UDS in person prior to this, one held at Google (Mountain View) for Ubuntu Jaunty (9.04) and one in Dallas for Ubuntu Lucid (10.04). UDS wanders around the world to mix it up and get input from a wide variety of contributors. I’m not a fan of flying long distances, so I tend to wait until UDS comes to within a couple hours of my home in Los Angeles.

My primary involvement at UDS is to contribute my perspectives to the plans for Ubuntu as it relates to running on Amazon EC2 and interacting with other features of AWS, though I also have interest in general Ubuntu server functionality.  I’ve been running Ubuntu on servers since 2005, and Ubuntu servers on EC2 since 2007.

I am grateful to Canonical for sponsoring my trip to and stay at UDS as they do for many community members.  I continue to be impressed by how Ubuntu is developed in such an open fashion with Canonical’s support.

All community members interested in learning about how Ubuntu is developed and/or interested in helping give input to the future of Ubuntu are welcome to participate in UDS. You can either attend in person as I will be, or you can participate online.  Be sure to register (free) at the UDS site.

Taking a full week off for UDS is a little much for me, so I’ll be attending three full days (Wed-Fri). Will I see you there or online? What feedback and suggestions would you have for running Ubuntu on EC2?

The ssh protocol uses two different keys to keep you secure:

  1. The user ssh key is the one we normally think of. This authenticates us to the remote host, proving that we are who we say we are and allowing us to log in.

  2. The ssh host key gets less attention, but is also important. This authenticates the remote host to our local computer and proves that the ssh session is encrypted so that nobody can be listening in.

Every time you see a prompt like the following, ssh is checking the host key and asking you to make sure that your session is going to be encrypted securely.

The authenticity of host 'ec2-...' can't be established.
ECDSA key fingerprint is ca:79:72:ea:23:94:5e:f5:f0:b8:c0:5a:17:8c:6f:a8.
Are you sure you want to continue connecting (yes/no)?

If you answer “yes” without verifying that the remote ssh host key fingerprint is the same, then you are basically saying:

I don’t need this ssh session encrypted. It’s fine for any man-in-the-middle to intercept the communication.

Ouch! (But a lot of people do this.)

Note: If you have a line like the following in your ssh config file, then you are automatically answering “yes” to this prompt for every ssh connection.

# DON'T DO THIS!
StrictHostKeyChecking false

Care about security

Since you do care about security and privacy, you want to verify that you are talking to the right server using encryption and that no man-in-the-middle can intercept your session.

There are a couple approaches you can take to check the fingerprint for a new Amazon EC2 instance. The first is to wait for the console output to be available from the instance, retrieve it, and verify that the ssh host key fingerprint in the console output is the same as the one which is being presented to you in the prompt.

Scott Moser has written a blog post describing how to verify ssh keys on EC2 instances. It’s worth reading so that you understand the principles and the official way to do this.

The rest of this article is going to present a different approach that lets you in to your new instance quickly and securely.

Passing ssh host key to new EC2 instance

Instead of letting the new EC2 instance generate its own ssh host key and waiting for it to communicate the fingerprint through the EC2 console output, we can generate the new ssh host key on our local system and pass it to the new instance.

Using this approach, we already know the public side of the ssh key so we don’t have to wait for it to become available through the console (which can take minutes).

Generate a new ssh host key for the new EC2 instance.

tmpdir=$(mktemp -d /tmp/ssh-host-key.XXXXXX)
keyfile=$tmpdir/ssh_host_ecdsa_key
ssh-keygen -q -t ecdsa -N "" -C "" -f $keyfile

Create the user-data script that will set the ssh host key.

userdatafile=$tmpdir/set-ssh-host-key.user-data
cat <<EOF >$userdatafile
#!/bin/bash -xeu
cat <<EOKEY >/etc/ssh/ssh_host_ecdsa_key
$(cat $keyfile)
EOKEY
cat <<EOKEY >/etc/ssh/ssh_host_ecdsa_key.pub
$(cat $keyfile.pub)
EOKEY
EOF

Run an EC2 instance, say Ubuntu 11.10 Oneiric, passing in the user-data script. Make a note of the new instance id.

ec2-run-instances --key $USER --user-data-file $userdatafile ami-4dad7424
instanceid=i-...

Wait for the instance to get a public DNS name and make a note of it.

ec2-describe-instances $instanceid
host=ec2-...compute-1.amazonaws.com

Add new public ssh host key to our local ssh known_hosts after removing any leftover key (e.g., from previous EC2 instance at same IP address).

knownhosts=$HOME/.ssh/known_hosts
ssh-keygen -R $host -f $knownhosts
ssh-keygen -R $(dig +short $host) -f $knownhosts
(
  echo -n "$host "; cat $keyfile.pub
  echo -n "$(dig +short $host) "; cat $keyfile.pub
) >> $knownhosts

When the instance starts running and the user-data script has executed, you can ssh in to the server without being prompted to verify the fingerprint

ssh ubuntu@$host

Don’t forget to clean up and to terminate your test instance.

rm -rf $tmpdir
ec2-terminate-instances $instanceid

Caveat

There is one big drawback in the above sample implementation of this approach. We have placed secret information (the private ssh host key) into the EC2 user-data, which I generally recommend against.

Any user who can log in to the instance or who can cause the instance to request a URL and get the output, can retrieve the user-data. You might think this is unlikely to happen, but I’d rather avoid or minimize unnecessary risk.

In a production implementation of this approach, I would take steps like the following:

  1. Upload the new ssh host key to S3 in a private object.

  2. Generate an authenticated URL to the S3 object and have that URL expire in, say, 10 minutes.

  3. In the user-data script, download the ssh host key with the authenticated, expiring S3 URL.

Now, there is a short window of exposure and you don’t have to worry about protecting the user-data after the URL has expired.

Amazon Web Services is such a huge, complex service with so many products and features that sometimes very simple but powerful features fall through the cracks when you’re reading the extensive documentation.

One of these features, which has been around for a very long time, is the ability to use AWS to seed (serve) downloadable files using the BitTorrent™ protocol. You don’t need to run EC2 instances and set up software. In fact, you don’t need to do anything except upload your files to S3 and make them publicly available.

Any file available for normal HTTP download in S3 is also available for download through a torrent. All you need to do is append the string ?torrent to the end of the URL and Amazon S3 takes care of the rest.

Steps

Let’s walk through uploading a file to S3 and accessing it with a torrent client using Ubuntu as our local system. This approach uses s3cmd to upload the file to S3, but any other S3 software can get the job done, too.

  1. Install the useful s3cmd tool and set up a configuration file for it. This is a one time step:

    sudo apt-get install s3cmd
    s3cmd --configure
    

    The configure phase will prompt for your AWS access key id and AWS secret access key. These are stored in $HOME/.s3cmd which you should protect. You can press [Enter] for the encryption password and GPG program. I prefer “Yes” for using the HTTPS protocol, especially if I am using s3cmd from outside of EC2.

  2. Create an S3 bucket and upload the file with public access:

    bucket=YOURBUCKETNAME
    filename=FILETOUPLOAD
    basename=$(basename $filename)
    s3cmd mb s3://$bucket
    s3cmd put --acl-public $filename s3://$bucket/$basename
    
  3. Display the URLs which can be used to access the file through normal web download and through a torrent:

    cat <<EOM
    web:     http://$bucket.s3.amazonaws.com/$basename
    torrent: http://$bucket.s3.amazonaws.com/$basename?torrent
    EOM
    

Notes

  1. The above process makes your file publicly available to anybody in the world. Don’t use this for anything you wish to keep private.

  2. You will pay standard S3 network charges for all downloads from S3 including the initial torrent seeding. You do not pay for network transfers between torrent peers once folks are serving the file chunks to each other.

  3. You cannot throttle the rate or frequency of downloads from S3. You can turn off access to prevent further downloads, but monitoring accesses and usage is not entirely real time.

  4. If your file is not popular enough for other torrent peers to be actively serving it, then every person who downloads it will transfer the entire content from S3’s torrent servers.

  5. There is no way to force people to use the Torrent URL. If they know what they are doing, they can easily remove “?torrent” and download the entire file direct from S3, perhaps resulting in a higher cost to you.

Ubuntu AMIs

Ubuntu AMIs for EC2:


AWS Jobs

AWS Jobs