The ‘cloud’ presents new and interesting issues around hardening an instance. If you buy into the cattle vs. puppies or cloudy application building mentality, your instances or VMs will be very short lived (Hours, Weeks, maybe Months). The internet however, doesn’t much care for how short lived the things are, and the attacks will begin as soon as you attach to the internet. Thus, the need to harden at build time. What follows is a quick guide on how to do this as part of the ‘cloud-init’ process.
Note: Yes, you can use pre-hardened images. However, keeping them up to date and deploying them everywhere presents it’s own set of challenges.
Note the second: The things I do below only harden some of the things, and only do an ‘ok’ job at it. You will want to build this out as needed per your policies / regulatory requirements.
What is User Data / Cloud-Init?
A full discussion of cloud init is a bit beyond the scope of what we’re doing here. That said, there are some details that will help you understand what we’re doing and how it works. From the OpenStack User Guide:
“User data is the mechanism by which a user can pass information contained in a local file to an instance at launch time. The typical use case is to pass something like a shell script or a configuration file as user data.”
“To do something useful with the user data, you must configure the virtual machine image to run a service on boot that gets user data from the metadata service and takes some action based on the contents of the data. The cloud-init package does exactly this. This package is compatible with the Compute metadata service and the Compute configuration drive.”
Using User Data / Cloud-Init to Harden an Instance
Now that we’ve an understanding of the mechanism to run boot time scripts in your images, next up, we need to do just that. For this example we’ll be using an Ubuntu 12.04 image. First create a file with the following contents:
Now that you have that in a file, you’ll need to fire off a command similar to:
nova boot --user-data ./myfile.txt --image myimage myinstance