Amazon Elastic Compute Cloud
User Guide (API Version 2011-12-15)
Print this pageEmail this pageGo to the ForumsView the PDFShare this page on TwitterShare this page on FacebookBookmark this page on DeliciousSubmit this page to RedditSubmit this page to DiggDid this page help you?  Yes  No   Tell us about it...

Sharing AMIs Safely

Shared AMIs are AMIs that developers build and make available for other AWS developers to use. Building safe, secure, usable AMIs for public consumption is a fairly straightforward process if you follow a few simple guidelines.

For additional information about sharing AMIs safely, go to the following articles on the AWS Developer Resources website.

For information on building shared AMIs, see Protecting a Shared AMI (Linux/UNIX). For information on sharing AMIs, see Sharing AMIs.

Protecting a Shared AMI (Linux/UNIX)

Following these guidelines produces a better user experience, makes your users' instances less vulnerable to security issues, and helps protect you.

To build a shared AMI, follow these guidelines:


[Note]Note

These guidelines are written for Fedora distributions, but the principles apply to any AMI. You might need to modify the provided examples for other distributions. For other distributions, review their documentation or search the AWS forums in case someone else has done it already.

Update the AMI Tools at Boot Time

For AMIs backed by instance store, we recommend that your AMIs download and upgrade the Amazon EC2 AMI creation tools during startup. This ensures that new AMIs based on your shared AMIs will have the latest AMI tools.

To update the AMI tools at startup on Fedora

  • Add the following to rc.local:

    # Update the Amazon EC2 AMI creation tools
    echo " + Updating ec2-ami-tools"
    wget http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm && \
    rpm -Uvh ec2-ami-tools.noarch.rpm && \
    echo " + Updated ec2-ami-tools"

Use this method to automatically update other software on your image.

[Note]Note

When deciding which software to automatically update, consider the amount of WAN traffic that the update will generate (your users will be charged for it) and the risk of the update breaking other software on the AMI.

[Note]Note

The preceding procedure applies to Fedora distributions. For other distributions:

  • On most Red Hat systems, add these steps to your /etc/rc.d/rc.local script.

  • On Gentoo systems, add them to /etc/conf.d/local.local.

  • On Ubuntu systems, add them to /etc/rc.local.

  • On Debian, you might need to create a start up script in /etc/init.d and use update-rc.d <scriptname> defaults 99 (where <scriptname> is the name of the script you created) and add the steps to this script.

Disable Password-Based Logins for Root

Using a fixed root password for a public AMI is a security risk that can quickly become known. Even relying on users to change the password after the first login opens a small window of opportunity for potential abuse.

To solve this problem, disable password-based logins for the root user. Additionally, we recommend you randomize the root password at boot.

To disable password-based logins for root

  1. Open the /etc/ssh/sshd_config file with a text editor and locate the following line:

    #PermitRootLogin yes
  2. Change the line to:

    PermitRootLogin without-password

    The location of this configuration file might differ for your distribution, or if you are not running OpenSSH. If this is the case, consult the relevant documentation.

  3. To randomize the root password, add the following to your boot process:

    if [ -f "/root/firstrun" ] ; then
      dd if=/dev/urandom count=50|md5sum|passwd --stdin root
      rm -f /root/firstrun
    else
      echo "* Firstrun *" && touch /root/firstrun
    
    [Note]Note

    This step assumes that a /root/firstboot file is bundled with the image. If the file was not created, the root password will never be randomized and will be set to the default.

[Note]Note

If you are using a distribution other than Fedora, you might need to consult the documentation that accompanied the distribution.

Remove SSH Host Key Pairs

If you plan to share an AMI derived from a public AMI, remove the existing SSH host key pairs located in /etc/ssh. This forces SSH to generate new unique SSH key pairs when someone launches an instance using your AMI, improving security and reducing the likelihood of "man-in-the-middle" attacks.

The following list shows the SSH files to remove.

  • ssh_host_dsa_key

  • ssh_host_dsa_key.pub

  • ssh_host_key

  • ssh_host_key.pub

  • ssh_host_rsa_key

  • ssh_host_rsa_key.pub

[Important]Important

If you forget to remove the existing SSH host key pairs from your public AMI, our routine auditing process will notify you and all customers running instances of your AMI of the potential security risk. After a short grace period, we will mark the AMI private.

Install Public Key Credentials

After configuring the AMI to prevent logging in using a password, you must make sure users can log in using another mechanism.

Amazon EC2 allows users to specify a public-private key pair name when launching an instance. When a valid key pair name is provided to the RunInstances API call (or through the command line API tools), the public key (the portion of the key pair that Amazon EC2 retains on the server after a call to CreateKeyPair or ImportKeyPair) is made available to the instance through an HTTP query against the instance metadata.

To login through SSH, your AMI must retrieve the key value at boot and append it to /root/.ssh/authorized_keys (or the equivalent for any other user account on the AMI). Users will be able to launch instances of your AMI with a key pair and log in without requiring a root password.

if [ ! -d /root/.ssh ] ; then
        mkdir -p /root/.ssh
        chmod 700 /root/.ssh
fi
# Fetch public key using HTTP
curl http://169.254.169.254/latest//meta-data/public-keys/0/openssh-key > /tmp/my-key
if [ $? -eq 0 ] ; then
        cat /tmp/my-key >> /root/.ssh/authorized_keys
        chmod 700 /root/.ssh/authorized_keys
        rm /tmp/my-key
fi

This can be applied to any user account; you do not need to restrict it to root.

[Note]Note

Rebundling an instance based on this image includes the key with which it was launched. To prevent the key's inclusion, you must clear out (or delete) the authorized_keys file or exclude this file from rebundling.

Disabling sshd DNS Checks (optional)

Disabling sshd DNS checks slightly weakens your sshd security. However, if DNS resolution fails, SSH logins will still work. If you do not disable sshd checks, DNS resolution failures prevent all logins.

To disable sshd DNS checks

  1. Open the /etc/ssh/sshd_config file with a text editor and locate the following line:

    #UseDNS yes
  2. Change the line to:

    UseDNS no
[Note]Note

The location of this configuration file can differ for your distribution or if you are not running OpenSSH. If this is the case, consult the relevant documentation.

Identify Yourself

Currently, there is no easy way to know who provided a shared AMI because each AMI is represented by an account ID.

We recommend that you post a description of your AMI, and the AMI ID, in the Amazon EC2 developer forum. This provides a convenient central location for users who are interested in trying new shared AMIs. You can also post the AMI to the Amazon Machine Images (AMIs) page.

Protect Yourself

The previous sections described how to make your shared AMIs safe, secure, and usable for the users who launch them. This section describes guidelines to protect yourself from the users of your AMI.

We recommend against storing sensitive data or software on any AMI that you share. Users who launch a shared AMI might be able to rebundle it and register it as their own. Follow these guidelines to help you to avoid some easily overlooked security risks:

  • Always delete the shell history before bundling. If you attempt more than one bundle upload in the same image, the shell history contains your secret access key.

  • Bundling a running instance requires your private key and X.509 certificate. Put these and other credentials in a location that is not bundled (such as the instance store).

  • Exclude the ssh authorized keys when bundling the image. The Amazon public images store the public key used to launch an instance with its ssh authorized keys file.

[Note]Note

Unfortunately, it is not possible for this list of guidelines to be exhaustive. Build your shared AMIs carefully and take time to consider where you might expose sensitive data.

Protect Paid AMIs

The simplest way to prevent users from rebundling paid AMIs that you create is to not provide root access to the AMI and to pay attention to security announcements that involve privilege escalations. Amazon EC2 requires you to have root access on any AMI that you rebundle.

If you must provide root access to an AMI, Amazon EC2 tools are designed to protect the product code. Although this is effective, it is not guaranteed and users might create AMIs using other tools.

To ensure users cannot rebundle your paid AMIs, we recommend that you configure your application to check the instance metadata to verify that the product code is intact.

Sharing AMIs

Amazon EC2 enables you to share your AMIs with other AWS accounts. This section describes how to share AMIs using the Amazon EC2 command line tools.

[Note]Note

Before proceeding, make sure to read the security considerations of sharing AMIs in the Protecting a Shared AMI (Linux/UNIX) section.

AMIs have a launchPermission property that controls which AWS accounts, besides the owner's, are allowed to launch instances of that AMI. By modifying an AMI's launchPermission property, you can allow all AWS accounts to launch the AMI (make the AMI public) or only allow a few specific accounts to launch the AMI.

The launchPermission attribute is a list of accounts and launch groups. Launch permissions can be granted by adding or removing items from the list. Explicit launch permissions for accounts are granted or revoked by adding or removing their AWS account IDs. The only launch group currently supported is the all group, which makes the AMI public. The rest of this section refers to launch groups simply as groups. Launch groups are not the same as security groups and the two should not be confused. An AMI can have both public and explicit launch permissions.

[Note]Note

You are not billed when your AMI is launched by other AWS accounts. The accounts launching the AMI are billed.

Making an AMI Public

To make an AMI public

  • Add the all group to the AMI's launchPermission.

    PROMPT>  ec2-modify-image-attribute <ami_id> --launch-permission -a all

    The <ami_id> parameter is the ID of the AMI.

To check the launch permissions of an AMI

  • Enter the following command, where <ami_id> is the ID of the AMI.

    PROMPT> ec2-describe-image-attribute <ami_id> -l

To make an AMI private again

  • Remove the all group from its launch permissions, where <ami_id> is the ID of the AMI.

    PROMPT> ec2-modify-image-attribute <ami_id> -l -r all

    This will not affect any explicit launch permissions for the AMI or any running instances of the AMI.

Example

This example makes the ami-2bb65342 AMI public.

PROMPT>  ec2-modify-image-attribute ami-2bb65342  --launch-permission -a all
launchPermission        ami-2bb65342    ADD     group   all

This examples displays the launch permissions of the ami-2bb65342 AMI.

PROMPT> ec2-describe-image-attribute ami-2bb65342 -l
launchPermission        ami-2bb65342    group   all

This example removes the all group from the permissions of the ami-2bb65342 AMI, making it private.

PROMPT> ec2-modify-image-attribute ami-2bb65342 -l -r all
launchPermission        ami-2bb65342    REMOVE  group   all

Sharing an AMI with Specific AWS Accounts

You can share an AMI with specific AWS accounts without making the AMI public. All you need is the account ID.

To grant explicit launch permissions

  • Enter the following command:

    PROMPT> ec2-modify-image-attribute <ami_id> -l -a <user_id>

    The <ami_id> is the ID of the AMI and <user_id> is the account ID, without hyphens.

To remove launch permissions for an account

  • Enter the following command:

    PROMPT> ec2-modify-image-attribute <ami_id> -l -r <user_id>

    The <ami_id> is the ID of the AMI and <user_id> is the account ID, without hyphens.

To remove all launch permissions

  • Enter the following command to remove all public and explicit launch permissions:

    PROMPT> ec2-reset-image-attribute <ami_id> -l

    The <ami_id> is the ID of the AMI.

[Note]Note

The AMI owner always has rights to the AMI and is unaffected by this command.

Example

The following example grants launch permissions to the AWS account with ID 111122223333 for the ami-2bb65342 AMI:

PROMPT> ec2-modify-image-attribute ami-2bb65342 -l -a 111122223333
launchPermission        ami-2bb65342    ADD     userId  111122223333

The following example removes launch permissions from the AWS account with ID 111122223333 for the ami-2bb65342 AMI:

PROMPT> ec2-modify-image-attribute ami-2bb65342 -l -r 111122223333
launchPermission        ami-2bb65342    REMOVE  userId  111122223333

The following example removes all public and explicit launch permissions from the ami-2bb65342 AMI:

PROMPT> ec2-reset-image-attribute ami-2bb65342 -l
launchPermission        ami-2bb65342    RESET

Publishing Shared AMIs

After you create a shared AMI, you can publish information about it in the Amazon EC2 Resource Center.

To publish your AMI

  1. Post it in the Public AMIs Folder of the Amazon Web Services Resource Center, and include the following information:

    • AMI ID

    • AMI name (for Amazon EBS-backed AMIs) or AMI manifest (for Amazon EC2 instance store-backed AMIs)

    • Publisher

    • Publisher URL

    • OS / Distribution

    • Key Features

    • Description

    • Daemons / Services

    • Release Notes

  2. If you want to, you can paste the following information into the document. You must be in HTML edit mode.

    <strong>AMI&nbsp;ID: </strong>[ami-id]<br />
    <strong>AMI&nbsp;Manifest: </strong>[bucket/image.manifest.xml]<br />
    <h2>About this &AMI;</h2>
    <ul>
    
        <li>Published by [Publisher] (<a href="http://www.mysite.com">[http://www.mysite.com]</a>).<br />
                </li>
        <li>[Key Features] <br />
                </li>
        <li>[Description]</li>
        <li>This image contains the following daemons / services:
        <ul>
    
            <li>[Daemon 1]</li>
            <li>[Daemon 2]</li>
        </ul>
                </li>
    </ul>
    <h2><strong>What&#39;s New?</strong></h2>The following changes were made on [Date].<br />
    <ul>
    
        <li>[Release Notes 1]</li>
    </ul>
    <span style="font-size: x-small; font-family: courier new,courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[Note 1]</span><br />
    <span style="font-size: x-small; font-family: courier new,courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[Note 2]</span><br />
    <span style="font-size: x-small; font-family: courier new,courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[Note 3]</span><br />
    <ul>