I’ve been running KVM for quite a while on my lab server. It’s been running without issue but with the release of vSphere/ESXi 6.0 I felt it was time to move back to VMware.

I wanted to preserve the virtual machines already running so I set out to move these to ESXi. I ran into some issues which I’m not sure is a generic problem or specific to ESXi 6.0 but I’ll describe what I have done.

In order to convert the existing disk images to VMware’s vmdk format you should you use the program qemu-img from the package qemu-utils (in Ubuntu).

The process is straight-forward

  • $ sudo qemu-img convert -p -i DiskImage.img -O vmdk DiskImage.vmdk
  • Transfer disk image to ESXi (using scp (enable ssh in ESXi)) or NFS (as I did)
  • Create new virtual machine with custom options and add the converted disk
  • Boot

Unfortunate this did not work as expected, when booting the converted images, the Linux instances inside all crashed during boot with this error message (or something similar)

lib6.so: unsupported version 0 of verneed record

It turns out, two steps were missing; after transfering the converted disk image to ESXi, do this from the ESXi cli (via SSH)

# vmkfstools -i /vmfs/volumes/nfs1/DiskImage.vmdk -d thin /vmfs/volumes/datastore1/MyServer/DiskImage.vmdk

-d is the output format which can be zeroedthick, eagerzeroedthick or thin.

Now open the newly created vmdk file in vi and change the line ddb.adapterType from ide to lsilogic.

After doing this, add the image(s) to a newly created VM and boot.

(This was done in Ubuntu and will work with any Linux variant with qemu-img. If you want to do this in Windows, StarWinds V2V converter is said to be able to do the job)

I have recently moved my hosting to a couple of VPSes at ChicagoVPS and wanted to use IPv6 (via tunnelbroker.net)

ChicagoVPS uses OpenVZ which presents a couple of problems

$ ifconfig sit0
sit0: error fetching interface information: Device not found
$ sudo modprobe ipv6
FATAL: Module ipv6 not found.

It turns out, this is a fairly common problem though OpenVZ is supposed to support IPv6. Luckily, someone made a small userland program (tb-tun, which “tunnels” IPv6 tunnels through a TUN/TAP device.

First, it requires tun/tap device support to be enabled in the VPS, this is done in the control panel under settings

Control panel

Note! – Changing this setting will reboot your VPS without warning!

Next, make sure the build-essential package is installed (it’s included in the Ubuntu template at ChicagoVPS)

$ sudo apt-get install build-essential

Now, download and install the tb-tun program

$ mkdir tb-tun
$ cd tb-tun
$ wget https://tb-tun.googlecode.com/files/tb-tun_r18.tar.gz
$ tar zxvf tb-tun_r18.tar.gz
$ gcc tb_userspace.c -l pthread -o tb_userspace
$ sudo mv tb_userspace /usr/local/sbin

Before, continuing I recommend looking up the following information:

Server IPv4 Address - This is the IPv4 address of the Tunnelbroker gateway
Client IPv4 Address - This is the IPv4 address of your server
Client IPv6 Address - This is the IPv6 address of your server (for the tunnel end-point)
Routed /64 - This is your network

Next, you need to ensure your iptables configuration allows incoming encapsulated IPv6 traffic (protocol 41). Since ufw is a PITA to get to work on OpenVZ, I’m using iptables-persistant, which simply means adding one line to /etc/iptables-persistent/rules.v4

# IPv6 tunnel
-A INPUT -p 41 -s <Server IPv4 Address> -j ACCEPT

You also need to secure your server on IPv6, /etc/iptables-persistent/rules.v6

*filter
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Allow ping
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT

Apply the new rules

$ sudo service iptables-persistent reload

Finally, you are ready to set up your tunnel in /etc/network/interfaces

auto tb
iface tb inet6 manual
        pre-up  setsid /usr/local/sbin/tb_userspace tb <Server IPv4 address> <Client IPv4 address> sit > /dev/null &
        up      ifconfig tb up
        post-up ifconfig tb inet6 add <Client IPv6 address>/64
        post-up ifconfig tb inet6 add <Routed /64>:1/64
        post-up ifconfig tb mtu 1480
        post-up route -A inet6 add ::/0 dev tb
        post-up netstat -rn6 | grep -q venet0 && route -A inet6 del ::/0 dev venet0
        down    ifconfig tb down
        post-down       route -A inet6 del ::/0 dev tb
        post-down       killall tb_userspace

In my setup it looks like this:

auto tb
iface tb inet6 manual
        pre-up  setsid /usr/local/sbin/tb_userspace tb 209.51.181.2 192.210.137.214 sit > /dev/null &
        up      ifconfig tb up
        post-up ifconfig tb inet6 add 2001:470:1f10:74b::2/64
        post-up ifconfig tb inet6 add 2001:470:1f11:74b::1:1/64
        post-up ifconfig tb mtu 1480
        post-up route -A inet6 add ::/0 dev tb
        post-up netstat -rn6 | grep -q venet0 && route -A inet6 del ::/0 dev venet0
        down    ifconfig tb down
        post-down       route -A inet6 del ::/0 dev tb
        post-down       killall tb_userspace

Now, I just have one question

Y U NO

(Actually I know, and understand, why. It’s still annoying though)

iptables is not always easy to deal with so I prefer to use Uncomplicated firewall (ufw) in Ubuntu, because it simplifies configuring and maintaining my firewall rules.

Unfortunately, ufw does not play nice with OpenVZ containers so I decided to find something else. In the end (after testing various things) I decided to install the package iptables-persistent which is not as sexy as ufw but gets the job done.

iptables-persistent uses two configuration files

/etc/iptables-persistent/rules.v4
/etc/iptables-persistent/rules.v6

both files can be generated during installation.

The a simple version of /etc/iptables-persistent/rules.v4 may look like this

*filter
#  Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -i ! lo -d 127.0.0.0/8 -j DROP

# Allow all traffic from tun-devices (VPN)
-A INPUT -i tun+ -j ACCEPT

#  Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allows all outbound traffic
#  You could modify this to only allow certain traffic
#  This is in addition to allowing established and related traffic as listed above
-A OUTPUT -j ACCEPT

# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allows SSH connections from trusted-host only - drop the rest
-A INPUT -p tcp --dport 22 -s 1.2.3.4 -j ACCEPT

# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Drop all other inbound - default deny unless explicitly allowed policy (change to REJECT of you which to reject packets instead of dropping them)
-A INPUT -j DROP
-A FORWARD -j DROP

COMMIT

After making changes to your rules files, apply them by running

$ sudo service iptables-persistent reload

It’s been a while since I last had to run Windows on my laptop; back then I used Ext2 Installable File System For Windows to access data on my Linux-formated partitions.

In the meantime a few things have changed: Windows 7 and Ubuntu formating ext3 with a inode size of 256 – none of these are supported by ext3 ifs.

Ext2read supports Windows 7 (as well as ext4 and LVM2) but it’s more like a file browser and does not support assigning drive letters to Linux filesystems and since my /home is formatted with XFS it does not help me anyway.

Instead of going through reformatting the filesystems I wanted to access from Windows, I decided to build a virtual file server instead; that way I can access any filesystem type supported by Linux.

Software used: Windows 7, Virtualbox and Ubuntu (server edition)

This guide will work with other versions of Windows (and other OS’es as well), there are no ties to Virtualbox and the Linux version used can be anyone you like.

Continue reading

Just a quick heads-up.

Virtualbox does not yet officially support Xorg 1.9 (which is shipped with Ubuntu 10.10). According to this ticket the problem will be fixed in 3.2.10. In the meantime, try you your luck which with this unsupported Additions build; it didn’t work for me though.

Background

In the past I have written a couple of articles on how to run Windows applications using SeamlessRDP and Sun xVM (Virtualbox) and Linux KVM (Kernel-based Virtual Machine). After reviewing both articles I have decided to write a new article encompassing both hypervisors and correcting some of the mistakes I have found as well improvements made by a couple of guys who have done quite a deal of testing: Thomas Hansson and Peter Clarén.

By the way – There is no reason why this guide should not work on other platforms like FreeBSD (Virtualbox, Qemu), Mac OSX (Virtualbox) or Solaris/OpenSolaris (Virtualbox) as long as the host platform is x86 or x64. The guide is centered around Ubuntu but it should be possible to use it for other Linux distributions without much work.

So, what is the reason for this article?

I run Linux on my primary machine (well, on all my machines really) but there are a few Windows application I need to run – Some run under Wine but does not act like in native Windows, some will not run under Wine. The solution was to run a virtual machine with Windows but I did not like the fact that I had to have a complete Windows desktop.

Enter SeamlessRDP. SeamlessRDP is an “extension” of the RDP protocol (originally developed by Cendio AB for their ThinLinc product).

SeamlessRDP makes it possible to run individual applications rather than a full desktop. In this mode, rdesktop creates a X11 window for each window on the server side. The remote applications can be moved, resized and restacked.

Choosing a hypervisor

I deal a lot with virtualization in job and have come to be a great fan of VMware’s line of products. Naturally I have been running VMware Workstation on my computer for a very long time but for this particular task it did not fit my needs (most noticeably it does not have the option to run “headless”) so I had to start looking at alternatives.

I started using VMware Server which worked great in version 1.x but after upgrading to 2.0 I was put of by the fact that is now uses a horrible memory hog of a web interface (which could be disabled but one is then dependent on Virtual Infrastructure Client which is Windows only).

After ditching VMware I ended up with two (equally great) products:

  • Sun xVM Virtualbox
    Pros: No problems with kernel modules. Great support for USB devices. RDP based “console”. Great performance using paravirtualized devices. Supports running 64 bit guests on a 32 bit host OS (the host has the be 64 bit of course). Export virtual machines as appliances. Seamless integration of the guests and hosts (using guest additions to provide shared clipboard and dynamic screen resizing)Cons: Not free (there is an open sourced edition which lacks some of the feature described above).
  • Linux KVM
    Pros: Part of the kernel. Lots of features (like live migrations). Powerful. Open source
    Cons: Does not support 64 bit guests on 32 bit host OS. Requires Intel VT-x or AMD-V. Though Virtual Machine Manager makes it easier it is not for the average user

Because I use both on a regular basis I will describe how to accomplish the goal using both hypervisors. My guides are based on Ubuntu so you may need to change the commands to match your environment.

Installing and configuring hypervisor

Installing KVM

One important note: KVM requires hardware virtualization support. To check if your computer supports this, run

$ egrep -c '(vmx|svm)' /proc/cpuinfo

The output should be at least 1 – If you know your CPU support VT-x or AMD-v but the above command does not show anything make sure virtualization is enabled in the computer’s BIOS.

KVM is in Ubuntu’s package repository, so installing it easy

$ sudo apt-get install kvm xtightvncviewer

Install Virtualbox

Virtualbox does not require hardware virtualization support but will benefit from it.

Enable Virtualbox’ package repository

$ echo "deb http://download.virtualbox.org/virtualbox/debian jaunty non-free" | sudo tee -a  /etc/apt/sources.list
$ wget -q http://download.virtualbox.org/virtualbox/debian/sun_vbox.asc -O- | sudo apt-key add -

and then install Virtualbox:

$ sudo apt-get update
$ sudo apt-get install virtualbox-3.0 rdesktop

Configuring network on the host

Though both Virtualbox and KVM support simple NAT networking we need to be able to connect to the virtual machine and the virtual machine need to be able to connect to the outside network.
Virtualbox now supports bridging to host interfaces but that is not necessarily what we want since that exposes the virtual machine to the outside network (which can cause problems on networks that only allow one MAC address per switch port).

So, we’ll set up a virtual interface on the host and let the host handle DNS, DHCP and IP forwarding (using dnsmasq and iptables).

First, install the needed software

$ sudo apt-get install dnsmasq ufw uml-utilities

Ubuntu tries to keep security really tight so be default only root is allowed to access tun/tap devices. To fix this we create a udev rule to allow group access to those devices

$ echo "KERNEL=="tun[0-9]*",GROUP="uml-net" MODE="0660"" | sudo tee -a /etc/udev/rules.d/40-permissions.rules
$ sudo udevadm control --reload-rules

Next create a interface configuration for a tap interface which will spawn a dedicated instance of dnsmasq when the interface is initialized (with Virtualbox it is also possible to use a bridge interface but since it does not work with KVM I will use tap for both) – Add this to /etc/network/interfaces:

auto tap0
iface tap0 inet static
         address 192.168.10.1
         netmask 255.255.255.0
         up /usr/sbin/dnsmasq --interface=${IFACE}  --except-interface=lo,eth0,wlan0,ath0 --bind-interfaces --user=nobody \
         --dhcp-range=kvm,192.168.10.150,192.168.10.250,255.255.255.0,192.168.10.255,8h \
         --domain=kvm.lan --pid-file=/var/run/${IFACE}_dnsmasq.pid --conf-file
         tunctl_user nobody

test if it works

$ sudo ifup tap0
$ ps aux | grep dnsmasq | grep -c kvm
1

You also need to add any users running virtual machines to the group uml-net:

$ sudo adduser <user> uml-net

(It will not work until the user logs on after adding her to the group)

In order for the virtual machine to reach the outside network we need to set up IP forwarding; I use Uncomplicated Firewall because it is very simple to use.

  1. Edit /etc/default/ufw and change DEFAULT_FORWARD_POLICY from DROP to ACCEPT
  2. Edit /etc/ufw/sysctl.conf and enable the line net/ipv4/ip_forward=1 (remove the # in front of the line)
  3. Add the following lines to /etc/ufw/before.rules (right after the comments at the top):
    # nat Table rules
    *nat
    :POSTROUTING ACCEPT [0:0]

    # NAT all traffic coming from 192.168.10.0/24 going through any interface.
    -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE

    # don't delete the 'COMMIT' line or these nat table rules won't
    # be processed
    COMMIT
  4. In the same file (/etc/ufw/before.rules), locate the line -A ufw-before-output -o lo -j ACCEPT and add these lines right after:
    -A ufw-before-input -i tap0 -j ACCEPT
    -A ufw-before-output -o tap0 -j ACCEPT

Getting things running

Converting an existing VMware virtual machine

Both KVM and Virtualbox support vmdk files so there is no need convert the disk files, just adjust the virtual machine creation to point at the vmdk file instead.

Windows can be quite picky when it comes to hardware so moving a virtual machine to a new hypervisor will most likely result in BSOD. If this happens find a Windows XP install CD, boot from it and repair your Windows XP installation.

Creating a virtual machine

Using KVM

Create the script $HOME/bin/kvm-windows:

#!/bin/bash

HD="-hda $HOME/path/to/Windows.img"
NIC1MAC="00:16:3e:66:42:73"
KVM="kvm"
VNC="-vnc :1"
NET="-net nic,macaddr=$NIC1MAC -net tap,script=no,vlan=0,fd=0"
SOUND="-soundhw es1370"
TIME="-localtime"
MEM="-m 512"
NAME="-name Windows"
CPU="-cpu core2duo"
KB="-k da"
USB=""
OTHERARG="-daemonize"

$KVM $HD $NET $VNC $SOUND $MEM $TIME $NAME $CPU $KB $USB $OTHERARG "[email protected]"

Change HD, NIC1MAC, KB and CPU to match your needs.

Last step is to create a virtual disk:

$ kvm-img create -f qcow2 $HOME/path/to/Windows.img

before booting the virtual machine

$ kvm-windows -cdrom /path/to/WindowsXP.iso -boot d

and connecting to the “console”

$ xtightvncviewer :1

Continue to installing Windows

Using Virtualbox

We will create the virtual machine from the shell – simply because it is easier.

$ VBoxManage createvm --name "Windows" --register
$ VBoxManage createhd --filename "Windows.vdi" --size 10000 --remember
$ VBoxManage modifyvm "Windows" --memory "512MB" --hda "Windows.vdi" --dvd /path/to/WindowsXP.iso --acpi on \
   --boot1 dvd --nic1 bridged --bridgeadapter1="tap0" --vrdp on --vrdpport 1337

Boot the virtual machine (this has to be done from the shell to run the “console” as a RDP service):

$ VBoxManage startvm Windows -type vrdp

and then connect to the “console”

$ rdesktop localhost:1337

Continue to installing Windows

Installing and configuring Windows XP

The installation of Windows XP is no different than any other install so I will not go into that.

KVM: Installing paravirtualized network driver

Download the driver disc, shut down the virtual Windows machine, change the variable NET to read:

NET="-net nic,model=virtio,macaddr=$NIC1MAC,vlan=0 -net tap,vlan=0,ifname=tap0,script=no"

and then boot Windows again

$ kvm-windows -cdrom NETKVM-20081229.iso

when Windows asks for a driver for the new network interface device, point to the CD-ROM.

Virtualbox: Installing guest additions

Shut down the virtual Windows machine, then from the shell run

$ VBoxManage modifyvm "Windows" --dvd /usr/share/virtualbox/VBoxGuestAdditions.iso

Boot Windows again

$ VBoxManage startvm Windows -type vrdp

and then connect to the “console”

$ rdesktop localhost:1337

Inside Windows, open the CD-ROM drive and select VBoxWindowsAdditions.exe and follow the instructions.

Configuring and tuning Terminal Services

Terminal Services is called Remote Access in Windows XP – enable it in Start -> Control Panel -> System -> Remote Access.

One downside is that someone needs to log on before XP punches a hole in the firewall. To circumvent this either manually add an exception for the RDP service or simply turn of the firewall (that’s what I did since the host will be protected by the host’s firewall as well as the NAT feature of VirtualBox).

One of the more annoying limitations in Windows XP is that the color depth by default is limited to 16 bits.

To change this open the Group Policy Editor (Start -> Run -> gpedit.msc) and navigate to Administrative Template -> Windows Components -> Terminal Services and change the limit:

Setting maximum colour depth in for Terminal Services

Setting maximum colour depth for Terminal Services

There are a few other parameters one can change, feel free to poke around.

To be able to connect to the Windows machine using RDP you need to set a password for the user you wish connect as.

Assign a static IP to your virtual machine, this will make it easier to create the scripts further down in this article.

Install and configure SeamlessRDP

The main component in this setup is SeamlessRDP which allows one to launch a single application using RDP (remote desktop) and open only the window of that application. The drawback (with Windows XP) is that you are only allowed to open one session which means you can only launch one application at the same time.

Luckily someone grew tired of this and has made a patch to both rdesktop and SeamlessRDP that makes it possible to launch more than one application over the same SeamlessRDP session.

Installing rdesktop from CVS

First make sure that you have all the required packages for building rdesktop

$ sudo apt-get build-dep rdesktop cvs

Download rdesktop from CVS

$ cvs -d:pserver:[email protected]:/cvsroot/rdesktop login
$ cvs -z3 -d:pserver:[email protected]:/cvsroot/rdesktop co -P rdesktop

Download the patch to the checked out source

$ cd rdesktop
$ wget http://www.fontis.com.au/system/files/rdesktop.patch

Patch the source

$ patch -p2 < rdesktop.patch

Compile the source and install (install it as rdesktop-cvs to not interfere with the Ubuntu package)

$ ./bootstrap
$ ./configure
$ make
$ sudo make install
$ sudo mv /usr/local/bin/rdesktop /usr/local/bin/rdesktop-cvs

Installing the Windows component

Download the updated SeamlessRDP program and unpack it to c:\seamlessrdp inside the virtual machine.

Making it all come together

To ease the execution of Windows programs I’ve created a small script called $HOME/bin/winrun:

#!/bin/bash

RDESKTOP="/usr/local/bin/rdesktop-cvs"
SRDP="c:\seamlessrdp\seamlessrdpshell.exe"
SOCKET="$HOME/.rdesktop/socket"
RDESKTOP_ARGS="-k da -u username -p<password  -z -x l -M $SOCKET -A"
RHOST="192.168.10.10"
RUNNING=$(pgrep -c -U $USER -x rdesktop-cvs)

if [ -e $SOCKET -a $RUNNING -ge 1 ]
 then
    $RDESKTOP $RDESKTOP_ARGS -l "$*"
 else
    $RDESKTOP $RDESKTOP_ARGS -s "$SRDP $*" $RHOST
fi

What this script does it to check for a socket file; if it does not exist rdesktop connects the same way as the standard client. If it does exist rdesktop uses the socket and the existing connection to create another window.

Similarly I have a script to connect to the Windows desktop when I need to do some maintenance

#!/bin/bash

RHOST="192.168.10.10"
VM="Windows"

rdesktop -k da -u <username> -p <password>  -g 90% -T $VM -z -x b $RHOST

Sharing data between the host and guest

When running KVM

Remote Desktop resource redirection

This is the easiest way of sharing data but it has some drawbacks.

Enable it by adding this to RDESKTOP_ARGS in winrun:

-r disk:Home=$HOME

This will make your entire home directory available to your virtual machine but only when you are connected and not with an assigned drive letter.

RDP resource redirection active

RDP resource redirection active

Samba

One could also use a Samba server on the host

$ sudo apt-get install samba

By default the section in /etc/samba/smb.conf concerning home directories is commented out

[homes]
   comment = Home Directories
   browseable = no
   read only = no
   create mask = 0700
   directory mask = 0700
   valid users = %S

Be sure to reload the Samba service

$ sudo service samba reload

Then map the home share inside the virtual machine

> net use h: \\192.168.1.1\<username>
When running Virtualbox

The same methods can be used as with KVM but it is a lot smarter to use Shared Folders.

Shut down the virtual machine then run (in a shell on the host):

$ VBoxManage sharedfolder add "Windows" --name Home --hostpath $HOME

Boot Windows again

$ VBoxManage startvm Windows -type vrdp

and then connect to the “console”

$ rdesktop localhost:1337

Inside Windows, run the following command to map the shared folder

> net use h: \\vboxsrv\home

Tips and tricks

Running Explorer in seamless mode

If you try to run explorer.exe using the winrun method you will get the entire desktop. This is because the first explorer.exe launched will be always be used as the “shell” (or desktop).

To get around this, download Litestep, install it and set it as the shell for Windows. Now you are able to run explorer.exe and only get the file manager window presented in Linux.

Running any Windows program as a service

This might come in handy if you need a particular program running (this could be an VPN client needed to access resources from within Windows). In my example I will use the Aventail Connect Client.

Install and configure the program you wish to run as a service. Make sure it works as expected.

Download svcany.zip and unpack in your virtual machine. This example uses C:\srvany

Create a new service

> c:\srvany\instsrv "Aventail Connect Client" c:\srvany\srvany.exe

Open regedit (Start -> Run -> regedit) and nagivate to HKEY_LOCAL_MACHINE -> System -> CurrentControlSet -> Services -> Aventail Connect Client. Add a new key (Edit -> New -> Key) called Parameters and under this new key add a new string called Application with the content “C:\Program Files\Aventail\Connect\as32.exe” (this string has to match your program).

Edit service

Edit service

That’s it.

Errors (and fixes)

A comment in one of the old articles asked: When I run winrun I get this error:

VirtualBox Command Line Management Interface Version 2.1.4_OSE
(C) 2005-2009 Sun Microsystems, Inc.
All rights reserved.

[!] FAILED calling a->virtualBox->OpenRemoteSession(a->session, uuid, sessionType, env, progress.asOutParam()) at line 2731!
[!] Primary RC = NS_ERROR_INVALID_ARG (0×80070057) – Invalid argument value
[!] Full error info present: true , basic error info present: true
[!] Result Code = NS_ERROR_INVALID_ARG (0×80070057) – Invalid argument value
[!] Text = Invalid session type: ‘vrdp’
[!] Component = Machine, Interface: IMachine, {ea6fb7ea-1993-4642-b113-f29eb39e0df0}
[!] Callee = IVirtualBox, {339abca2-f47a-4302-87f5-7bc324e6bbde}
/home/george/bin/winrun: line 22: 4422 Segmentation fault $RDESKTOP $RDESKTOP_ARGS -s “$SRDP $*” $RHOST

That is because you are using the Open Source Editition (OSE) of Virtualbox which does not have a RDP server build in.

Please go to the updated article.

Since I wrote the post about running Windows applications on Linux with Sun xVM VirtualBox and SeamlessRDP I have been using the system almost daily to run some applications needed at work. It has been running well except for crashes in VirtualBox from time to time. Two new releases of VirtualBox has not fixed the problem.

Growing increasingly tired of this I decided to look at KVM (Kernel-based Virtual Machine).

Installing KVM

I run Ubuntu Jaunty (9.04) and at the time of writing the version of KVM in the repository is kvm-84. If you are running an older version of Ubuntu there is a PPA with updated KVM packages. Add it to your apt sources:

$ echo 'deb http://ppa.launchpad.net/intuitivenipple/ubuntu hardy main' | sudo tee /etc/apt/sources.list.d/intuitivenipple.list
$ sudo apt-get update

You are now ready to install KVM (and some other programs we are going to use later):

$ sudo apt-get install kvm dnsmasq qemu uml-utilities

I opted to install a new virtual machine but it should be possible to convert an existing virtual machine (VMware or VirtualBox) by converting the disk image and using it in a KVM machine – The method for converting a VMware image is described in the VirtalBox article.

If you want to convert a VirtualBox VDI image do the following:

$ VBoxManage internalcommands converttoraw OldDisk.vdi NewDisk.img

this requires VirtualBox.

If you are creating a new virtual machine then create a disk image:

$ qemu-img create -f qcow2 WindowsDisk.img 10G

Setting up the network

Because I need to contact the virtual machine from the host using the “user” networking facility (NAT) of KVM was not a possibility. Instead I chose to use a tap-based solution (with NAT’ing done a the host using iptables).

First, create the configuration in

/etc/network/interfaces

(just add this):

iface tap0 inet static
address 192.168.10.1
netmask 255.255.255.0
up /usr/sbin/dnsmasq --interface=${IFACE}  --except-interface=lo --bind-interfaces --user=nobody \
--dhcp-range=kvm,192.168.10.150,192.168.10.250,255.255.255.0,192.168.10.255,8h \
--domain=kvm.lan --pid-file=/var/run/${IFACE}_dnsmasq.pid --conf-file
down kill -s TERM `cat /var/run/${IFACE}_dnsmasq.pid` && rm -f /var/run/${IFACE}_dnsmasq.pid
tunctl_user 

We also start dnsmasq (which will only listen in the tap0 interface) to act as DNS and DHCP server for virtual machines (the idea came from this HOWTO.

Test that everything works:

$ sudo ifup tap0

For some reason (security I guess) a normal user is, per default, not allowed to use the tap/tun interfaces. To fix this:

$ echo "KERNEL==\"tun[0-9]*\",GROUP=\"uml-net\" MODE=\"0660\"" | sudo tee -a /etc/udev/rules.d/40-permissions.rules

and then reread the udev rules:

$ sudo udevadm control --reload-rules

You also need to be member of the uml-net group:

$ sudo adduser $(id -un)

You need to log out and log on again for the changes to take effect.

If you want your virtual machine to be able to access the the outside world you need to setup NAT. One way of doing this is to Ubuntu’s Uncomplicated Firewall.

Configurating and running KVM

Installing Windows in KVM

There is the possibility of using one of the graphical interfaces for Qemu/KVM but I just created a script for my Windows machine, it looks like this:

#!/bin/sh
HD="-hda Windows.img"
NIC1MAC="00:16:3e:66:42:73"
KVM="kvm"
#VNC="-vnc :1"
NET="-net nic,model=rtl8139,macaddr=$NIC1MAC,vlan=0 -net tap,vlan=0,ifname=tap0,script=no"
SOUND="-soundhw es1370"
TIME="-localtime"
MEM="-m 512"
NAME="-name Windows"
CPU="-cpu core2duo"
KB="-k da"
OTHERARG="-daemonize"
$KVM $HD $NET $VNC $SOUND $MEM $TIME $NAME $CPU $KB "[email protected]"

Adjust MEM, NIC1MAC, CPU and KB to suit your setup, use this small script to generate a random MAC address:

#!/usr/bin/python
# macgen.py script to generate a MAC address for Red Hat Virtualization guests
#
import random
#
def randomMAC():
mac = [ 0x00, 0x16, 0x3e,
random.randint(0x00, 0x7f),
random.randint(0x00, 0xff),
random.randint(0x00, 0xff) ]
return ':'.join(map(lambda x: "%02x" % x, mac))
#
print randomMAC()

When installing the Windows guest run the script like this:

$ kvm-windows -cdrom /path/to/windows.iso -boot -d

Once the virtual machine is installed shut down Windows. We are going to switch the network card from an emulated Realtek rtl8139 to the much fast virtio, this reqiures paravirtual network drivers for Windows. Download it from here.

Change the NET= line in the kvm-windows script:

NET="-net nic,model=virtio,macaddr=$NIC1MAC,vlan=0 -net tap,vlan=0,ifname=tap0,script=no"

Boot the machine again:

$ kvm-windows -cdrom /path/to/NETKVM-20081229.iso

Once the virtual Windows machine comes up, install the driver from the CD-drive when Windows asks for drivers.

Let us wrap it all up by allowing the virtual machine to start without the SDL-based console by removing the # from VNC and OTHERARGS. This will run kvm daemonized (detaching it from the tty) and with the console output redirected to a VNC server on display :1.

Enabling Terminal Services

Terminal Services is called Remote Access in Windows XP – enable it in Start -> Control Panel -> System -> Remote Access.

One downside is that someone needs to log on before XP punches a hole in the firewall. To circumvent this either manually add an exception for the RDP service or simply turn of the firewall (that’s what I did since the host will be protected by the host’s firewall as well as the NAT feature of VirtualBox).

Tuning Terminal Services

One of the more annoying limitations in Windows XP is that the color depth by default is limited to 16 bits.

To change this open the Group Policy Editor (Start -> Run -> gpedit.msc) and navigate to Administrative Template -> Windows Components -> Terminal Services and change the limit:

Setting connection limit in Terminal Services

Setting connection limit in Terminal Services

There are a few other parameters one can change, feel free to poke around.

SeamlessRDP

The main component in this setup is SeamlessRDP which allows one to launch a single application using RDP (remote desktop) and open only the window of that application. The drawback (with Windows XP) is that you are only allowed to open one session which means you can only launch one application at the same time.

Luckily someone grew tired of this and has made a patch to both rdesktop and SeamlessRDP that makes it possible to launch more than one application over the same SeamlessRDP session.

Installing rdesktop from CVS

First make sure that you have all the required packages for building

$ sudo apt-get build-dep rdesktop

Download rdesktop from CVS

$ cvs -d:pserver:[email protected]:/cvsroot/rdesktop login
$ cvs -z3 -d:pserver:[email protected]:/cvsroot/rdesktop co -P rdesktop

Download the patch to the checked out source

$ cd rdesktop
$ wget http://www.fontis.com.au/system/files/rdesktop.patch

Patch the source

$ patch -p2 < rdesktop.patch

Compile the source and install (install it as rdesktop-cvs to not interfere with the Ubuntu package)

$ ./bootstrap
$ ./configure
$ make
$ sudo make install
$ sudo mv /usr/local/bin/rdesktop /usr/local/bin/rdesktop-cvs

Now download the updated SeamlessRDP program and unpack it to c:\seamlessrdp on the virtual machine.

Making it all come together

winrun

Used to run any application on you Windows machine.

Create a script in $HOME/bin called winrun (requires that you have added $HOME/bin to your $PATH).

RDESKTOP="/usr/local/bin/rdesktop-cvs"
SRDP="c:\seamlessrdp\seamlessrdpshell.exe"
SOCKET="$HOME/.rdesktop/socket"
RDESKTOP_ARGS="-k da -u  -p   -z -x l -M $SOCKET -A"
RHOST=""
RUNNING=$(pgrep -c -U $USER -x rdesktop-cvs)
if [ -e $SOCKET -a $RUNNING -ge 1 ]
then
$RDESKTOP $RDESKTOP_ARGS -l "$*"
else
$RDESKTOP $RDESKTOP_ARGS -s "$SRDP $*" $RHOST
fi

Run as winrun c:pathtoprogram.exe

Sharing data between host and VM

There are (at least) three ways of sharing data between the host and the virtual machine

Remote Desktop resource redirection

This is the easiest way of sharing data but it has some drawbacks.

Enable it by adding this to RDESKTOP_ARGS in winrun:

-r disk:Home=$HOME

This will make your entire home directory available to your virtual machine but only when you are connected and not with an assigned drive letter.

Redirected local resource in RDP

Redirected local resource in RDP

Samba

Last but not least one could use a Samba server on the host

$ sudo apt-get install samba

By default the section in /etc/samba/smb.conf concerning home directories is commented out

[homes]
comment = Home Directories
browseable = no
read only = no
create mask = 0700
directory mask = 0700
valid users = %S

Yesterday Sun released the second maintenance release for VirtualBox 2.1

See the Changelog for more details.

Actually my Windows VM has been running smoothly since I upgraded to 2.1.2 but as usual there is a bunch of bugfixes in this release.

Download it here.

The fastest way of determining the UUID of a LUN on ESX is through /proc:

# grep "Id:" /proc/vmware/scsi/vmhba1/8:5
Id: 60 5 7 68 1 90 81 1a d8 0 0 0 0 0 0 34 32 31 34 35 20 20

This corresponds to a UUID of

600507680190811ad800000000000034

On ESX 3.5 go to /vmfs/devices/disks to see the mapping to a vmhba.

Sun has released xVM Virtualbox 2.1.2.

The changelog shows a lot of
improvements. I am especially delighted to see this entry

NAT: fixed occasional crashes (bug #2709)

this one bug has really been … bugging me since it made the virtual
machine almost unusable.

Also, this release adds official support for Windows 7.

At least one defect remains. When running more than one Windows VM VirtualBox will die with the error message

An active VM already uses software virtualization. It is not allowed to simultaneously use VT-x or AMD-V.

This happens regardless of the actual setting. Only if you enable VT-x or AMD-V for all VMs they can run simutaniously..

Get it while it’s hot.