I'd like to introduce Joe. He is a good looking, experienced sys-admin and like all good sysadmins, he has more stuff to do than time to do it.
Joe wants to get up and running on Amazon EC2 with a Wordpress installation, and chooses to do so with a pre-configured appliance. These are the steps Joe performs:
- Joe logs into his favourite Amazon EC2 console, specifies a Wordpress appliance, and other configurations.
- Clicks launch.
- Once the instance is running, he logs in using his SSH public key and changes the root password (it was set randomly on firstboot, right?).
- He then proceeds to change the MySQL root password as well (also set randomly on firstboot, hopefully!). Joe knows how to do this as he's an experienced sys-admin, do you?
- Finally, Joe logs into Wordpress using the default admin password (he noted the default password in the release notes before launching), resets the password and specifies his own email for the account.
While performing the above, Joe was holding his breath and working as fast as he could because he was previously hit by a botnet looking for random systems using default passwords and was compromised. Luckily this time he came out unscaved.
Does this sound familiar? Well, it should because that's how it's mostly being done.
You might be thinking to yourself "but I used the TurnKey Hub to set the root password for my instances, which also set the database password". True, that has been a feature of the Hub from day one, but with the release of TurnKey 11.0 and the end to default passwords, we've extended the Hub to support preseeding as well.
The idea behind this was not only to make cloud deployments more secure, but to make it much easier. We wanted to simplify the process for Joe from the above to this:
- Joe logs into the Hub, selects Wordpress and preseeds the configuration.
- Clicks launch.
Brainstorming a solution
Idea #1: pass it through Amazon EC2 user-data?
Idea #2: store it in the Hub's database, and let the server query the API
Idea #3: pass it as messages using the Advanced Message Queuing Protocol (AMQP)
Designing infrastructure that is secure, scalable and extendible
- The user specifies preseeding data.
- The Hub tells Amazon EC2 to launch the instance with user-data which includes the SERVER_ID.
- The Hub creates a direct message exchange and queue for the server, which is configured to only receive messages sent from the Hub.
- The Hub publishes symmetrically encrypted messages (incl. a CRC) to the server queue with preseeding data that only the server can decrypt.
- The instance pulls user-data from the Amazon EC2 API (SERVER_ID).
The Instance registers itself with the Hub via an SSL secured API using the SERVER_ID, which responds back with the server subkey and messaging secret. Note that this can only be done once for security.
subkey: A one way hash generated from the user's APIKEY. It is unique for each server registered in the Hub, and is used as part of the exchange and queue naming structure.
secret: A secure unique hash used for message encryption and decryption.
- The instance consumes messages from the queue. Messages are decrypted and passed to the callback for processing (preseeding messages appends the arg=value to inithooks.conf).
- During inithooks execution, inithooks.conf is sourced so preseeding will happen. Once inithooks.conf is no longer needed, it is deleted.
In addition to authentication related preseeding, TKLBAM is also preseeded with the HUB_APIKEY and is initialized, so performing the initial backup is as easy as executing tklbam-backup or using the TKLBAM webmin module.
Take the Hub for a spin and let us know what you think.