NAT under Qemu

When using user-net Qemu behaves as if it was behind a firewall which blocks all incoming connections. You can use a DHCP client to automatically configure the network for the guest OS. Under QEMU 0.7.2 and below using the option

-user-net

-net nic -net user

Qemu Virtual Machine    <------>  Firewall/DHCP server <-----> Internet
{{{
     (10.0.2.x)            |          (10.0.2.2)
                           |     
                           ---->  DNS server (10.0.2.3)
                           |
                           ---->  SMB server (10.0.2.4)

}}}

In order to check that the user mode network is working, you can ping the address 10.0.2.2 and verify that you got an address in the range 10.0.2.x from the Qemu virtual DHCP server. Note that ping is not supported reliably to the internet as it would require root priviledges. It means you can only ping the local router (10.0.2.2). When using the built-in TFTP server, the router (10.0.2.2) is also the TFTP server.

When using the -redir option, TCP or UDP connections can be redirected from the host to the guest. It allows for example to redirect X11, telnet or SSH connections.

Qemu Bridged Networking

In bridged networking Qemu appears as another host on your LAN, so it has access to the resources on your LAN, and other machines can access services provided by the guest OS. This is in contrast to the above section where the guest is "firewalled" off from your LAN. In the following scenario there is no firewall, so be careful installing potentially vulnerable operating systems (ahem) in a guest where your LAN provides public access, or where you think there may be other compromised machines 'nearby'.

I use the following script - ran as root - to setup my environment for running Qemu. It starts by turning on IP forwarding so that the guest can traverse the host to the network. Next it creates a bridge device which is called br0. You can see the device using standard tools such as ifconfig. I then add the eth0 device to the bridge. eth0 on my laptop is my standard ethernet network port. Once that's done I drop the IP address assigned to my eth0 by giving it 0.0.0.0 as an IP address. Finally br0 gets an IP from the DHCP server on my LAN with the dhclient command. I then fudge the rights on the tun device and finally load the kqemu acceleration module and we're almost ready to run a Virtual Machine.

 1. Allow IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward 
 1. Setup the bridge
brctl addbr br0
 1. Add host ethernet adapter to the bridge
brctl addif br0 eth0
 1. Remove IP address from host ethernet device

ifconfig eth0 0.0.0.0 up
 1. Grab an IP address from DHCP for the bridge
dhclient br0
 1. Allow user access to tun device
chmod 666 /dev/net/tun
 1. Create the device for the binary kqemu module
mknod /dev/kqemu c 250 c
 1. Make it accessible by all
chmod 666 /dev/kqemu
 1. Add the kqemu module
modprobe kqemu

Note: If you are using udev, then instead of doing "chmod 666 /dev/net/tun" as per the script above, you can add a udev rule to ensure that this mode is set each time you boot. To do this on ubuntu:-

I start my vm using the command line below QEMU 0.7.2 and below (see further below for QEMU 0.8.0 and above):

qemu -hda win98sehd -enable-audio -boot c -m 64 -localtime -n ./qemu-ifup

Note the mention of qemu-ifup, which is actually a script in the directory where I keep all my virtual disk images. Here it is:

sudo /sbin/ifconfig $1 0.0.0.0 promisc up
sudo /usr/sbin/brctl addif br0 $1

The above gets called by Qemu upon startup, so make sure that it's in place, you should get this message upon starting Qemu:

Connected to host network interface: tun0

If you get this next message then it could be you haven't specified the -n ./qemu-ifup, or that the permissions on /dev/net/tun are wrong (see above) or something else I haven't thought of yet.

warning: could not open /dev/net/tun: no virtual network emulation

Under QEMU 0.8.0 and above that might look like this:

qemu  -boot c -localtime -m 96 -net nic,vlan=0 -net tap,vlan=0,ifname=tap0,script=./win98if win98sehd

Where the win98if script looks like this:

sudo /sbin/ifconfig $1 0.0.0.0 promisc up
sudo /usr/sbin/brctl addif br0 $1

See Also

LinuxHints/QemuNetworking (last edited 2006-01-05 00:24:48 by 62)