Xen 4.4: Windows HVM Networking

linux / xen / networking

Taking a look at the settings and steps required to successfully set up and configure networking on a Windows 7 or Windows Server HVM domain on Xen 4.4 hypervisor running Debian

Getting networking to work in Windows under Xen is not a straightforward task, it seems. Here are my notes while attempting to get a Windows 7 domain set up on a server with Hetzner.

The host machine has a subnet statically routed to it by Hetzner, so we can't use straight bridging, because Hetzner's switches would just drop the packets from an unknown MAC address. So here, we take a look at setting up a bridge and using NAT in iptables to bridge the traffic from an "internal" 10.0.9.101 address to the machine's "external" IP address, 176.9.22.223 -- this IP is dedicated to this Windows virtual machine. Note that this type of NAT is basic or one-to-one NAT, since one address directly translates to another-- there's no port forwarding or any other nonsense.

Preface

The xenbr1 is a virtual interface and bridge with an IP of 10.0.9.1. Configuration from /etc/network/interfaces shown below. We will be adding our Windows domain to this bridge later on.

auto xenbr1  
iface xenbr1 inet static  
  address   10.0.9.1
  broadcast 10.0.9.255
  netmask   255.255.255.0
  pre-up brctl addbr xenbr1

Set up on the client domain

Note that I could not get this to work at all with the Intel e1000 ioemu device on Windows 7 x64, but ymmv. I needed to install the GPLPV drivers to even be able to ping the dom0 host.

If you need to install the GPLPV drivers on a host machine without network access, try the following steps to create a new LVM volume that's formatted NTFS.

  • Install ntfs-3g utils if they are not already installed.
apt-get install ntfs-3g  
  • Create a new 8GB logical volume 'winstrap' on group vg0. Format it as NTFS.
lvcreate -L8G -nwinstrap vg0  
mkfs.ntfs /dev/vg0/winstrap  
  • Mount the volume so that we can put the drivers and things on it
mkdir /mnt/winstrap  
mount /dev/vg0/winstrap /mnt/winstrap  
  • Download the .NET 4.5 Redist package (required for the Xen Shutdown driver to work) and the latest GPLPV drivers. Here we are downloading the GPLPV drivers for 64-bit Windows; adjust as needed.
cd /mnt/winstrap  
wget http://download.microsoft.com/download/1/6/7/167F0D79-9317-48AE-AEDB-17120579F8E2/NDP451-KB2858728-x86-x64-AllOS-ENU.exe  
wget http://apt.univention.de/download/addons/gplpv-drivers/gplpv_Vista2008x64_signed_0.11.0.373.msi  

Check this page for signed up-to-date GPLPV drivers from Univention, as well as downloads for older versions of Windows and 32-bit OSes

Now that everything is ready, unmount our little bootstrapper volume, and add it to your domain's config as an additional disk.

  • Unmount the winstrap volume
umount /mnt/winstrap  
  • Edit the disk line in the domain's XM config to include the winstrap volume (in addition to the primary disk, of course)
'phy:/dev/vg0/winstrap,xvdc,rw'  
  • Now boot your domain, Windows should have mounted the raw NTFS volume as drive (D:) or some such (thankfully it doesn't care that there isn't a partition table). First install the .NET framework. Do not reboot. Then install the Xen GPLPV drivers, and reboot when prompted. After the machine reboots, it may ask to reboot again, so go ahead and shutdown, but this time destroy the machine so that we can edit its config.
  • At this point, remove any references to ioemu devices in the domain's XM config. Your vif line should look similar to the following:
vif = [ 'mac=00:16:3E:29:7B:51, bridge=xenbr1' ]  

Windows network settings

Once the Xen Network Adapter is available, configure the following settings for IPv4. Substitute with your own settings where applicable.

  • Address: 10.0.9.101 (should be on the same subnet as xenbr1)
  • Netmask: 255.255.255.0
  • Gateway: Same gateway as the Dom0 host
  • DNS resolvers: Use your ISP's DNS resolvers or Google DNS (8.8.8.8, 8.8.4.4)

Host network settings

Bridge interfaces

Add the domain's interface, named vifXX.0 (where XX is the domain ID, run xl list to check, or better yet xl network-list DOMNAME). xenbr1 is a secondary interface with an IP address of 10.0.9.1 in this case. This should probably be implemented as a vif script or something, so that it doesn't need to be done or undone everytime the machine is created or destroyed.

brctl addif xenbr1 vifXX.0  

Once you have destroyed the domain, its interface will be removed, and will in turn be removed from the bridge configuration. Keep this in mind when recreating the domain again.

Set up forwarding rules in iptables

Forwards incoming traffic on 176.9.22.223 to 10.0.9.103 on the xenbr1 bridge. Outbound traffic from the Windows domain (10.0.9.103) will have its source address rewritten as 176.9.22.223 so that the remote host can actually send a response and make its way back here. Intra-machine traffic to other domains (routed or bridge) still works as expected.

iptables -t nat -A PREROUTING -d 176.9.22.223 -j DNAT --to 10.0.9.103  
iptables -t nat -A POSTROUTING -s 10.0.9.103 -d 176.9.22.223 -j MASQUERADE  
iptables -t nat -A POSTROUTING -s 10.0.9.103 -j SNAT --to-source 176.9.22.223  

Conclusion

After this, you should be able access the domain just as if it were directly connected to your main interface, eth0 or similar, with both ingress and egress traffic being directly forwarded. There is probably a more elegant solution for this, but this seems to work, at least for my set up.

Connected via RDP and running ping tests

Share on : Twitter, Facebook or Google+