How to configure NAT for Xen virtual machines on OpenSuse 13

I was recently asked to help someone configure NAT for VMs running on Xen with OpenSuse 13.  I don’t have a ton of experience with Xen, but I must say this was much more difficult than I anticipated.  I believe the trouble stems from the recent change to the xl toolstack for Xen and the lack of support within OpenSuse for it although I’d be open to anyone with more experience correcting me on the subject.  I did eventually get it working and I’ve detailed the solution below.

First, verify that virtual bridge 0 or a similair bridge exists,  if not create it because we will need this bridge to perform the NAT.

brctl addbr virbr0
1

Don’t expect to see any interfaces under virbr0, just make sure it exists.

Give it an IP address on the private network, this address is being assigned to the host and will be used as the default gateway on the VMs

ifconfig virbr0 192.168.10.1

Determine if ip forwarding is enabled because it is required for NAT

cat /proc/sys/net/ipv4/ip_forward

If the command responds with a zero ( 0 ) then it is disabled, a 1 for enabled.

If not enable it:

echo 1 > /proc/sys/net/ipv4/ip_forward 

The above command only enables it until a reboot, to enable it permanently then edit the file /etc/sysctl.conf:

/etc/sysctl.conf:
net.ipv4.ip_forward = 1

 

NAT is accomplished by altering rules within the iptables Linux firewall.

This command adds a rule into the INPUT chain of the filter table that allows packets sourced by the network 192.168.10.0/24 (Our private network for virtual machines) to be accepted.  For more information on the iptables tables and chains see this write up: http://www.thegeekstuff.com/2011/01/iptables-fundamentals/

iptables --table filter --insert INPUT --source 192.168.10.0/255.255.255.0 --jump ACCEPT

This command adds a rule to the FORWARD chain of the filter table that allows our private network, so we accept the packet, then we forward the packet.

 iptables --table filter --insert FORWARD --source 192.168.10.0/255.255.255.0 --jump ACCEPT

This command adds a rule in the FORWARD chain of the filter table to allow return packets back to the private network if the TCP state is established, so this is basically stateful firewalling to our private network.

 iptables --table filter --insert FORWARD --destination 192.168.10.0/255.255.255.0 --match state --state ESTABLISHED,RELATED --jump  ACCEPT

Finally this command inserts a rule into the POSTROUTING chain of the nat table to actually translate the outgoing (and incoming packets) to our private network.

 iptables --table nat --insert POSTROUTING --source 192.168.10.0/255.255.255.0 --destination 192.168.10.0/255.255.255.0--jump MASQUERADE

You can see all of the iptables rules including the ones you just added using this command:

iptables --list

All of these commands can be added to a script, or the  iptables rules can be added to a file named /etc/sysconfig/scripts/SuSEfirewall2-custom then edit /etc/sysconfig/SuSEfirewall2

change

Code:
FW_CUSTOMRULES=""

to

Code:
FW_CUSTOMRULES="/etc/sysconfig/scripts/SuSEfirewall2-custom"

Now that networking is setup on the host, we need to define the VM under the xl toolset.  I have not been able to get this to work under virt-manager yet but if someone has, please comment to this post.

Edit a file we will call it vm-2.xl and add the following, I’m using inx 1.1 for this demo available here: http://inx.maincontent.net/

 name = “vm-2”
uuid = “db6f4bac-c17f-8856-3b1e-2b249206e28f”
maxmem = 1024
memory = 1024
vcpus = 1
builder = “hvm”
kernel = “/usr/lib/xen/boot/hvmloader”
boot = “d”
pae = 1
acpi = 1
apic = 1
hap = 0
viridian = 0
rtc_timeoffset = 0
localtime = 0
on_poweroff = “destroy”
on_reboot = “restart”
on_crash = “restart”
device_model = “/usr/lib64/xen/bin/qemu-dm”
sdl = 0
vnc = 1
vncunused = 1
keymap = “en-us”
disk = [ “file:/inx-1.1.iso,hdc:cdrom,r”]
vif = [ ‘bridge=virbr0,ip=10.0.0.2,”mac=01:0c:29:3f:00:d8’]
parallel = “none”
serial = “pty”
soundhw = “es1370”

 

You can export your virt-manager, virsh created VMs to xl using this command:

virsh -c xen:/// domxml-to-native xen-xm /etc/libvirt/libxl/vm-2.xml > vm-2.xl

Of course you will want to edit the resulting file so as to be like the listing above for my working VM.

This command instantiates the VM:

xl create vm-2.xl

You may get a couple of errors relating to the choices I made in the VM configuration file, but if it does not error out you should be able to check which interfaces are created with ifconfig.

ifconfig

3

You should have two interfaces vif2.0 and vif2.0-emu that are part of a bridge virbr0 or something similiar

brctl show

1

If you sniff on vif2.0-emu you should see traffic from the VM

tcpdump -i vif2.0-emu

Of course the VM needs to be configured with an IP address like 192.168.10.x/24 and a gateway of 192.168.10.1 and set the DNS in /etc/resolv.conf

Run the following command to get a console on your VM

xl vncviewer vm-2
sudo ifconfig eth0 192.168.10.10 netmask 255.255.255.0 
sudo route add -net default gw 192.168.10.1 

If all goes well, you should be able to ping google from the VM and get a response:

 

ping 8.8.8.8
64 bytes from 8.8.8.8: icmp_seq=1 ttl=47 time=46.063 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=47 time=46.178 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=47 time=49.135 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=47 time=46.251 ms
Advertisements
This entry was posted in Linux, Uncategorized and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s