This combination (GNU/Linux hosting VMWare with an encrypted guest
OS) seems like a good fit for business users who carry laptops where
sensitive data is stored. All laptops a subject to being lost or stolen,
especially while in transit. The method shown below requires some extra
effort and there is a small performance penalty, but the need for data
safety could justify the extra effort.
DISCLAIMER: These are the approximate steps I followed. I have checked them,
but they may still contain errors. There is NO WARRANTY or claim of suitability
for a specific purpose for the method presented below. Verify all commands are
correct and appropriate for your specific situation before proceeding. You are
responsible for any commands you issue on your system.
First time setup: Steps 1 and 2.
1. Allocate and format a virtual disc:
# LEF=/root/vmware/some_efs
# dd if=/dev/zero of=$LEF bs=1024 count=0 seek=8000000
# losetup -e serpent /dev/loop0 $LEF
# mke2fs -m 3 /dev/loop0
2. Transfer an existing virtual machine to the encrypted disc (that is,
encrypt as it is transferred):
# mount /dev/loop0 /mnt/efs
# DEST=/mnt/efs/vmware
# mkdir $DEST
# SRC=/root/vmware
# VM=someVM
# (cd $SRC && tar -cpf - $VM) | (cd $DEST && tar -xvf -)
# umount /mnt/efs
Subsequent usage to access virtual machine: Step 3.
3. Start vmware application with a script, possibly similar to this:
#!/bin/bash
# Purpose: A script to launch vmware using virtual machine stored on
# encrypted file system
#
# copyright (c) 2006 Douglas D. Mayne
# Use of this software is subject to this license:
# http://www.gnu.org/copyleft/gpl.txt
#
# Usage: vmware_enc.src loopback_encrypted_file
# loopback_encrypted_file is the file which encapsulates your virtual machine
#
# Begin source code
#
EWD=$(pwd)
#
# for is a makeshift try block (continue is error, break is good)
#
for RV in 0 1;do
[ $RV -ne 0 ] && continue
[ $# -ne 1 ] && continue
[ ! -e $1 ] && continue
modprobe cryptoloop
L1=$(losetup -f)
MP=/mnt/efs
mount | grep "$MP type" && continue
[ ! -e "$MP" ] && mkdir $MP
BF=0
#
# Three attempts at password
#
for j in 1 2 3;do
[ $j -ne 1 ] && losetup -d $L1
echo Password Attempt $j
losetup -e serpent $L1 $1
mount $L1 $MP
[ $? -ne 0 ] && continue
BF=1 && break
done
[ $BF -eq 0 ] && continue
killall busyloop
nice ~/busyloop &
child_p=$!
vmware
kill -1 $child_p
cd $EWD
umount $MP
losetup -d $L1
break
done
[ $RV -ne 0 ] && echo "Check some error starting virtual machine."
exit $RV
# end script
Notes for this post:
1. Allocate enough disc space in step 1 to accomodate the total needs for
your virtual machine. Include the machines RAM because it will be
saved when suspending the virtual machine.
2. The busyloop (in the script) was required to keep the Pentium M CPU
from going to sleep between instructions. It may not be required with
other hardware.
Perhaps these instructions will help if you are having trouble getting
started with encrypted virtual machines.
--
Douglas Mayne
> I just tested a VMWare virtual machine using a virtual machine stored in
> a loopback encrypted filesystem. Even with the extra processing
> layer for encryption, the performance is still very good- at least on my
> test machine, a Dell D610 with Pentium M 1.87GHz CPU. The host platform
> is Slackware 10.2+ linux with a self compiled kernel (2.6.15.4).
>
<snip>
I modified this startup script to do a better job of cleaning up after
itself. It makes multiple attempts to clear mounts and loopback
devices. WAG: VMWare may be slow to release locks on open files causing
a simple umount command to fail. Bad things happen when loopbacks are not
closed properly at shutdown.
> 3. Start vmware application with a script, possibly similar to this:
>
#!/bin/bash
#Purpose: A script to launch vmware using virtual machine stored on
# encrypted file system
#
# copyright (c) 2006 Douglas D. Mayne
# Use of this software is subject to this license:
# http://www.gnu.org/copyleft/gpl.txt
#
EWD=$(pwd)
MP=/mnt/efs
T1=$(/home/util/tmpfile.scr)
for TRY1 in 0 1;do
[ $TRY1 -ne 0 ] && continue
[ $# -ne 1 ] && continue
[ ! -e $T1 ] && continue
[ ! -e $1 ] && continue
modprobe cryptoloop
lsmod | grep cryptoloop || continue
L1=$(losetup -f)
#
mount | grep "${MP}\ " && continue
[ ! -e $MP ] && mkdir $MP
#
# Three attempts at password on loopback encrypted file
#
BF=0
for j in 1 2 3;do
[ $j -ne 1 ] && losetup -d $L1
echo Password Attempt $j
losetup -e serpent $L1 $1
echo $L1 >$T1
mount $L1 $MP
if [ $? -eq 0 ];then
echo $MP >>$T1
else
continue
fi
BF=1 && break
done
[ $BF -eq 0 ] && continue
[ ! -e ${MP}/vmware ] && continue
#
# Looks good for startup
#
killall -i busyloop
nice ~/busyloop &
child_p=$!
vmware
kill -1 $child_p
break
done
#
# Clean up: temp file has successful ops to be undone
#
cd $EWD
for TRY2 in 0 1;do
echo Second Try Loop...
[ $TRY2 -ne 0 ] && continue
LC=$(wc -l <$T1)
[ $LC -eq 0 ] && break
#
# Try to umount loopback
#
if [ $LC -eq 2 ];then
MP=$(cat $T1 | head -2 | tail -1)
BF=0
for i in $(seq 1 5); do
mount | grep "${MP}\ " >/dev/null || break
if [ $? -eq 0 ];then
umount $MP >/dev/null && BF=1 && break
else
sleep 5
fi
done
if [ $BF -eq 0 ];then
echo "Could not umount: $MP ..."
echo "umount and remove loopback manually..."
continue
else
echo "Loopback mount: $MP umounted on attempt $i"
fi
fi
#
# Try to delete loopback device
#
L1=$(head -1 <$T1)
BF=0
for i in $(seq 1 5); do
losetup $L1 >/dev/null
if [ $? -eq 0 ];then
losetup -d $L1 >/dev/null && BF=1 && break
else
sleep 5
fi
done
if [ $BF -eq 0 ];then
echo "Could not remove loopback device: $L1 ..."
echo "Remove loopback manually..."
continue
else
echo "Loopback device $L1 deleted on attempt $i"
fi
break
done
#
# Give the user a hint of what happened.
#
if [ $TRY2 -ne 0 ];then
echo "NOTICE: There are errors to be handled manually."
fi
rm $T1
echo "Press any key to exit ..."
read
[ $TRY1 -eq 0 ] && [ $TRY2 -eq 0 ] && exit 0
exit 1
# -- end script
--
Douglas Mayne