I'm creating a system similar to a cloud computing provider using the libvirt python bindings.

I would like to give users the ability to specify a custom virtual machine image, in a similar fashion to AWS.

I would like to generate SSH key pairs on the fly and set the VM up for public key authentication.

Which is the best method to do this? Which requirements should I impose on the user-specified VM image for this to work?

I was thinking at a passwordless root account to allow my piece of software to login and set up what needed, but this leaves a (short) timespan during which everyone could login as root. Are there better solutions? Can I edit the virtual machine image before starting it?

In practice, I need to login to be able to login to the machine and execute some commands, before giving it to the user.


Some additional details:

  1. I know about Eucalyptus, Cloudstack and Openstack. This implementation is for a very specific environment/requirements (HPC clusters, batch job scheduling) and does not allow to run these.
  2. I actually don't care (or, for the purpose of this question, it is not relevant) where the key pair comes from, I only want to know how the service provider can possibly access the machine, by requiring as less setup as possible on the VM image on the user part; ErikA replied to this suggesting a service specific key pair. Fair enough. Are there other solutions?
  3. The final user does not have to have access to the new virtual machine, he will run jobs on it through SLURM (though, he could access it if he wants to, I don't care).
  4. The provider takes care of:
    1. Allocating and spawning new domains (virtual machines)
    2. Spawning the SLURM daemon (which does not have to happen at startup, but at a certain point in time, thus the need for the provider to be able to access the machine)
  • 5
    Do not generate key pairs for your users. That goes against the whole public/private archetecture. Just make it easy for your users to generate and deploy their own keypairs. – EEAA Jul 7 '11 at 20:20
  • The problem remains the same. Once the user has generated the key pair, how do I instruct the VM to accept his public key? – GaretJax Jul 7 '11 at 20:40
  • 1
    You give them instructions on how to copy it to the VM. At no time should anyone other than the user be in possession of the private key. – EEAA Jul 7 '11 at 20:55
  • 1
    ...additionally if you have a service account that needs access, include keys for that in the VM templates you make available. – EEAA Jul 7 '11 at 20:56
  • I don't need the private key, I need only the public one, which is the one which I will copy over to the VM. The account specific key pair makes more sense. How does, for example AWS, do it? – GaretJax Jul 7 '11 at 21:26

Perhaps you should try and not re-invent the wheel. There are many frameworks out there that will do exactly what you want... and even free/open-source ones. Try looking at cloudstack or eucalyptus for two such environments.

| improve this answer | |
  • I know (and I have worked with) both of them, add openstack to the mix too. Sadly I'm working on a very specific project for HPC clusters and the requirements prevent the use of such services. – GaretJax Jul 7 '11 at 21:52
  • I admit... neither are the complete package... but both contain half of the picture. Setting up a cloud-framework is no small undertaking. I'm simply amazed at how well Amazon does it. Perhaps you should consider building a Beowulf cluster... or a map-reduce cluster of some flavor... or other similar compute cluster... and not look at hosting services. – TheCompWiz Jul 7 '11 at 21:53
  • I updated the question with some additional details. In practice, we want to give to HPC clusters users the ability to run their own image on top of physical nodes and continue to use the cluster by submitting jobs to SLURM. – GaretJax Jul 7 '11 at 22:03

I solved it in the following way:

As I needed the IP address assigned to the VM, and as libvirt doesn't offer means to retrieve it (as opposed to, i.e. VMWare which offers the VMWare tools suite for such operations), I ended setting up a serial (on the guest) to tcp (on the host) channel between the VM and the Host, using libvirt's virtual devices support.

A simple shell script on the guest waits then until an IP address is assigned to a given interface and writes it to the serial device. When the TCP server sitting on the host receives the IP address, it sends back it's public key, which the script on the guest reads (again, from the serial port) and writes back to the correct authorized_keys file.

This solution can be used without the IP exchange part, with only the guest reading the key from the serial port on booting. The advantages of such a solution are that the guest OS has not to be customized with a given key (so different, key pairs can be used for different system "partitions") and that it can manage where to put it; the downside is that the guest has to be configured to run the script.

Another solution would be to mount the disk image prior the VM booting by using something like libguestfs, copy the public key, unmount it and boot the guest. This solution is preferable over the TCP<->SerialPort one, but as I needed the IP address anyway I proceeded the other way around.

The third solution, as suggested by ErikA in his first comment, would be to let the user creating the image doing all the setup by giving them your public key. This is probably the best (cleanest and more elegant) solution for the most generic case.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.