JimD's picture


 Have you ever wanted to run test a new Turnkey ISO image under KVM?

 Wanted to run it such that you could invite selected friends or colleagues to remotely access it?

 Here's a quick hack for doing that.  The idea is to run the image under KVM with "user" networking (which KVM/Qemu handles with internal DHCP in the 10.0.2.* IP address range) and use a "redirection" from some port on our local host into port 22 of our virtual machine (VM).  However, to keep the virtual image secure we first block off our host port to all outsiders (so only the localhost/loopback source address can access it during our setup).  Then we set a root password, create other user accounts, copy ssh public key files into .../.ssh/authorized_keys files and perform whatever other setup we like ... and finally we open the port back up (optionally we could open it up only to selected network address blocks, but I'm not fussing with that particular nuance for this case).

Here's my script:

iptables -A INPUT -p tcp -m tcp -s ! --dport 2222 -j REJECT
trap 'iptables -D INPUT -p tcp -m tcp -s ! --dport 2222 -j REJECT' \

kvm -nographic -daemonize -net nic -net user -redir tcp:2222::22 \
        -cdrom /var/vm/iso/turnkey-rails-2009.03-hardy-x86.iso &
reset ## Previous munges terminal for some reason, so we reset it.
echo -n waiting ...
sleep 6
while :; do
ssh -o ConnectTimeout=4 -p 2222 localhost hostname 2> /dev/null && break
sleep 1; echo -n .

# Other set up steps here using ssh -p 222 localhost  and scp -P 2222 localhost commands
ssh -p 2222 localhost usermod -p \''$1$xyzabc123/XYZABC123.//uvwnbcbsx'\' root



  I hope that's plain enough ... note that I use the shell trap command with the exit psuedo-signal so that my iptables reject rule isn't left laying around even if I interupt the script with Ctrl-C. As noted in  the comments we perform all of our setup commands using ssh -p 2222 (or whatever port you choose for your own scripts).  We do this after we've looped through some time, waiting for the virtual host to come up and before we lock ourselves out by setting the password.

 The usermod -p command requires slightly tricky double quoting to get the quoted string properly through the local shell's parsing such that the remote (VM) doesn't interpolate on $1$xyz... strings.    We pull that password hash out of any normal /etc/shadow file after (temporarily) setting a dummy account to to it.  (I just interactively set it in the VM when I first bring it up, then scp it back out into the host and paste it into my script ... that's with the trap/exit line commented out).

 If you want to disable direct root passwords entirely (and just copy in one or more ssh authorized keys) that's easy enough --- just replace the $1$xxxxx with a single, literal '*' (asterisk) or "!" (bang).  Nothing will hash to those so no password will work.  Obviously you could also copy in a new /etc/sudoers file, use useradd -m -p ... commands, and so on.



JimD's picture

[Poor form to follow-up on one's own post but ...]

The example shown has one serious flaw; while it initially works it's not stable because the default KVM memory limit is far too low.  I found that the VM running the Rails Turnkey is far more stable when run with -m 512M ... to give the VM a half a gig of RAM to work with.

I also found found that my customer wanted a few extra ports open, which is easily accomplished by adding a few more -redir ... options to the kvm command line.

When applying this technique to other liveCD images one might want to remove the -nographics switch and add a -vnc ... option to allow remote graphical remote acccess.


Lastly, since I'm opening up a few more ports (which might include some access to something like phpmyadmin then I added the following to the setup script ... using the plain text of the same password that generated the root password hash; though it could be anything I'd like):

mysqladmin -u root password $NEWPASSWORD

However, at some point we're guilding the lily.  In this case the customer was able to determine that the Turnkey Rails CD has a sufficiently coherent installation of Rails and Ruby Gems to support his development effort ... so I can proceed to fetch that suite of specific package versions to install on his system and "pin" into place to keep them from being munged by the package management system.  (Apparently Jaunty Jackalope's default rails  isn't coherently packaged).

He doesn't want to run a virtual machine installation, though a chroot environment might work for him.




Add new comment