Category: AWS

Setting up EC2 Encrypted File Storage

Setting up EC2 Encrypted File Storage

Step 1: Create an EBS volume

You can do this from the AWS web interface or from the command line, for this example, I’m going to do everything from the command line of the EC2 instance I want to configure.

ec2-create-volume --size 10 -z us-east-1c

Size is in gigabytes, the zone you pick must be the same as the zone your EC2 instance is located in otherwise you won’t be able to attach the volume to your instance if you don’t know what zone you are in use the EC2 metadata query toolYou could also just check it from the AWS web console to find out but that’s cheating and violates my Rule #1 of Cloud Computing: To Know the Cloud is to Know it’s API’s. When you have the time, you should spend some time getting to know the EC2 meta-data API, it’s extremely handy for a lot of things, like getting the run time of your instance for example, but I digress…

Sample output will be something like this (save that vol-XXXXXXXX you will need it later):

VOLUME vol-XXXXXXXX 1 us-east-1c creating 2011-11-26T20:08:15+0000

Step 2: Attach it

Using the vol-XXXXXXXX that you received earlier run the following.

ec2-attach-volume vol-XXXXXXXX -i i-XXXXXXXX -d /dev/sdf

Where i-XXXXXXXX is your instance ID and /dev/sdf is a free device to attach it to. Choose something that is not being used between sdf and sdp, note that the Amazon Linux AMI will likely translate /dev/sdf into /dev/xvdf. If you don’t know your instance ID, use the EC2 metadata tool again or look it up in the AWS web console.

Sample output:

ATTACHMENT vol-XXXXXXXX i-XXXXXXXX /dev/sdf attaching 2011-11-26T20:19:45+0000

 Step 3: Setup the volume for encrypted storage

Now that we have an EBS volume and it’s attached, lets ready it by formatting it for encryption

cryptsetup -y luksFormat /dev/xvdf

Note that I went ahead and changed from /dev/sdf to /dev/xvdf because on the Amazon Linux AMI that’s how your devices will get mapped, just make sure you choose the right device here, once you format your volume, there is no going back. The command will prompt you for confirmation, then a passphrase and then quickly prepare the volume (should take a few seconds).

Sample output:

This will overwrite data on /dev/xvdf irrevocably.

Are you sure? (Type uppercase yes): YES  
Enter LUKS passphrase: ***********  
Verify passphrase: **********

Step 4: Verify the results

You can make sure your new shiny volume is indeed setup for encryption by typing the following:

cryptsetup luksDump /dev/xvdf

Sample output:

LUKS header information for /dev/xvdf

Version:           1  
Cipher name:       aes  
Cipher mode:       cbc-essiv:sha256  
Hash spec:         sha1  
Payload offset:    4096  
MK bits:           256  
MK digest:         xx 22 e1 53 6a 17 hj xx d8 d7 05 55 b7 ee 57 c0  
MK salt:           ec d3 2e 0s f6 e0 05 7e 30 rf xx 76 8d 26 fg 00  
                   c3 kl a0 db xx 68 39 d9 a5 30 31 jk 51 dx 00 c0
MK iterations:     32375  
UUID:              93x0e44x-9x3x-47x5-b6bx-7428x3edcc10

Key Slot 0: ENABLED  
    Iterations:             129600
    Salt:                   xx 30 9d 9b 5e 6b e9 a4 dd g3 fa b6 80 dc 55 ze
                            9c b0 fg x8 11 9c ec 41 94 hf be cj 40 89 k3 fd
    Key material offset:    8
    AF stripes:             4000
Key Slot 1: DISABLED  
Key Slot 2: DISABLED  
Key Slot 3: DISABLED  
Key Slot 4: DISABLED  
Key Slot 5: DISABLED  
Key Slot 6: DISABLED  
Key Slot 7: DISABLED

Step 5: Create a device we can map to

Now that we have an encrypted volume set up, we need to set up a device mapping that we can actually mount, to do so type the following replacing myencfs with something easy for you to remember:

cryptsetup luksOpen /dev/xvdf my_enc_fs

You will be prompted for your password and if everything runs right you will be left with a new device that you can mount or use at /dev/mapper/myencfs (assuming you named your device “myencfs”

Sample output:

Enter passphrase for /dev/xvdf: ***********

Step 6: Format with your filesystem of choice

At this point, the volume is now just like any other newly attached disk volume and needs to be formatted and initialized for use. To format for ext4, a fine choice for a filesystem, type the following

mkfs.ext4 -m 0 /dev/mapper/my_enc_fs

Sample output:

mke2fs 1.41.12 (17-May-2010)  
Filesystem label=  
OS type: Linux  
Block size=4096 (log=2)  
Fragment size=4096 (log=2)  
Stride=0 blocks, Stripe width=0 blocks  
65408 inodes, 261632 blocks  
0 blocks (0.00%) reserved for the super user  
First data block=0  
Maximum filesystem blocks=268435456  
8 block groups  
32768 blocks per group, 32768 fragments per group  
8176 inodes per group  
Superblock backups stored on blocks:  
    32768, 98304, 163840, 229376

Writing inode tables: done  
Creating journal (4096 blocks): done  
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 23 mounts or  
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Step 7: Mount it!

Everything’s been initialized, configured and formatted and your filesystem is now ready for use, this is the moment you have been waiting for, go ahead and create a mount point and mount the volume.

mkdir /encrypted_vol
mount /dev/mapper/my_enc_fs /encrypted_vol

You can now start copying files to /encrypted_vol with the confidence your data is encrypted. In case you are paranoid, you can verify this by running the following

cryptsetup status my_enc_fs

You should see something like the following:

/dev/mapper/my_enc_fs is active and is in use.  
  type:  LUKS1
  cipher:  aes-cbc-essiv:sha256
  keysize: 256 bits
  device:  /dev/sdf
  offset:  4096 sectors
  size:    14752 sectors
  mode:    read/write

Step 8: Disable automount

Your next step should be to disable auto-mounting of dm-crypt/LUKS filesystems to prevent your system from hanging on reboot. To do this you need to add rdNOLUKS to your /etc/grub.conf

Mine looked like this after I finished editing it:

# created by imagebuilder  

title Amazon Linux 2011.09 (  
    root (hd0)
    kernel /boot/vmlinuz- root=LABEL=/ console=hvc0 LANG=en_US.UTF-8 rd_NO_LUKS KEYTABLE=us
    initrd /boot/initramfs-
title Amazon Linux AMI  
    root (hd0)
    kernel /boot/vmlinuz- root=LABEL=/ console=hvc0 rd_NO_LUKS
    initrd /boot/initramfs-

Step 9: You’re done!

That’s it, your system is all set for secure file storage. Just remember to always store your encrypted data in the right place and if you forget, securely delete it after copying into the right place. If you should ever want to unmount and fully detach your encrypted volume, do the following:

umount /encrypted_vol  
cryptsetup luksClose my_enc_fs

Your encrypted volume is now ready to be detached from your instance and re-attached to another one if desired. To re-attach run the following commands (again assuming the volume was mounted to /dev/xvdf, you will be prompted for your passphrase after the first command):

cryptsetup luksOpen /dev/xvdf my_enc_fs
mount /dev/mapper/my_enc_fs /encrypted_vol

You will also need to run these command after you reboot your instance to get access to your data. If you have application data like MySQL DB’s located in your encrypted volume, you should create a script that takes care of mounting your volume and making sure MySQL is running after things are set up which by the way is Rule #17 of the cloud: Automate everything, it’s worth doing once, it’s worth automating.

Credit goes to Erik Peterson who originally wrote this article. You can read his blog here: