akkornel / ec2seed

Use KMS random data to seed EC2 instances on boot

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

EC2 Instance Seeder

The EC2 Instance Seeder (ec2seed) is a C program that helps seed a just-booted instance with randomness, using the cryptographically-secure randomness that we can get from AWS KMS, as well as certain instance metadata.

ec2seed is meant for instances that need lots of random data during the boot process. The trade-off is that those random data-needing programs must be willing to wait until after the network is online, so that entropy may be obtained from AWS (beyond the entropy already provided by the virtual hardware).

You may already know that it's possible to give random data to the kernel using something like this...

cat /var/lib/random_data_from_last_boot > /dev/urandom

... however, even though that adds entropy, it does not increase the kernel's entropy available (that is, it doesn't increase the counter), because the kernel does not know how many bits of entropy were in what you just added.

ec2seed is written in C because it uses ioctl() calls that add entropy and increase the entropy count. This also means that ec2seed needs to be run as root, preferably by something like systemd.

Random Data Sources

ec2seed operates in two phases:

  1. Start by getting enough entropy — even if it's not high-quality — in order to get /dev/urandom to unblock.
  2. Obtain and add lots of high-quality entropy, so that the random pools are ready for other services (like Apache) to come online.

First, before any calls are made to KMS, we obtain the following instance metadata and add it to the kernel's random pool:

  • The instance ID.
  • The Local IPv4 Address.
  • The MAC address for eth0. Twenty-four bits of entropy, corresponding to the last three octets (the non-vendor-ID part) of the MAC address.
  • The instance identity document signature, after being Base64-decoded.

The items above were chosen because they will vary from instance to instance. Other metadata were not chosen because they do not change between instances.

Each item above is hashed using SHA-1 before it is given to the kernel. The hashing is used here as a whitening function, to help distribute the bits from each piece of metadata.

In addition to the entropy added here by ec2seed, the kernel is also adding entropy from the following processes:

  • Initial seeing, using various counters, as well as CPU-generated randomness.
  • Disk activity and interrupts generated by the early boot process.
  • Network activity involved in getting an IP address and making the initial metadata requests.

All of this initial entropy is added to the pool so that there is enough randomness for /dev/urandom to unblock.

Once the SSL library is initialized, a call is made to KMS to obtain 1,024 random bytes, the maximum allowed in one request, which are added directly to the entropy pool.

Prerequisites

We rely on CURL for all of our HTTP and HTTPS traffic, and we use JSON-C to parse the JSON that AWS returns. We also use libunichar to process anything that comes back as UTF-8.

Since KMS requires the use of HTTPS, then you need to provide a libcurl that was built with some sort of SSL support (OpenSSL, LibreSSL, or NSS should be fine).

Instructions

For instructions on how to build, install, configure and use ec2seed, check out the INSTALL.rst document.

In short:

autoreconf -i
./configure
make
make install

Next, make sure your instance's IAM role has permission to call GenerateRandom. Then, configure systemd to run ec2seed after network-online.target but before other network-using services.

More information on all of this, including an IAM policy document, are available in INSTALL.rst.

About

Use KMS random data to seed EC2 instances on boot

License:GNU General Public License v3.0


Languages

Language:C 92.3%Language:M4 6.5%Language:Makefile 1.2%