[Qemu-devel] qemu and TUN/TAP; a conceptual overview and instructions fo
[Qemu-devel] qemu and TUN/TAP; a conceptual overview and instructions for use.
Tue, 10 Aug 2004 01:01:37 +1200
After spending perhaps the most frustrating evening of my life attempting to make a Windows 98 guest in qemu talk to the world via TUN in Linux, I thought I'd share my observations with the list and gather some feedback. Firstly, I could not find ~anywhere~ a decent high-level, conceptual outline of what a TUN network 'looks like' in Linux; and that seems to lead to a lot of confusion, both for me personally, and on this list generally (I came across many, many incorrect qemu-ifup scripts etc that just Don't Work on various threads archived on this list and elsewhere). Now that I have made TUN bend to my will, I thought I'd clear up some confusion and draw some pictures, for the future benefit of anyone else like me trying to untangle this mess with the help of google ;)
First up; what does a TUN client network 'look like'? Here's how I visualise it:
------| <-192.168.0.10 (real NIC IP)
| |--------------------------------->THE WORLD
^ <-192.168.0.10 (Pretend real NIC IP)
| <-Pretend network link
v <-10.0.0.1 (Pretend fake tun0 IP)
| | <-Fake 'tun0' NIC
^ <- 10.0.0.1 (tun0 IP)
| <-Pretend connection to guest OS
v <- 10.0.0.x (ie 10.0.0.10) QEMU guest NIC IP
| | <-QEMU guest OS NIC
In other words, conceptually, tun0 actually sits 'between' the host OS and the guest (whether this is actually the case or not I leave as an intellectual exercise for the reader). So, the tun0 address and the qemu guest OS address should be different, but should both be on the same subnet, and that subnet should be utterly different to anything else on your network. Intellectually I can appreciate the possibility that it shouldn't *have* to be on a different subnet, but in practice I met with utter and complete failure attempting to make tun0 and the guest OS NIC live on the same subnet as all the 'real' NICs.
Therefore, all traffic to the 'real world' goes from the guest, to tun0 (ie, in the guest OS set the address of the default gateway to be the tun0 address), and from tun0 out to the world via the real NIC address. To make all this work, you need a script that puts the house in order for tun0.
Your real NIC, because all of the traffic is routing through it, has to have an appropriate iptables rule to masquerade traffic, and ip forwarding needs to be enabled for the host OS. Here is a simple script that does everything necessary (ie, this is a working, complete qemu-ifup):
iptables --flush #Clear out all previous rules ('/etc/init.d/iptables stop' may also work)
echo 1 >/proc/sys/net/ipv4/ip_forward #Enable IP forwarding for the host OS
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE #Enable masquerading on your real NIC so tun0 can get in and out
ifconfig $1 10.0.0.1 #Bring up tun0 on a different subnet from the host
Please feel free to reply with comments pointing out where I've gone wrong (if indeed I have; certainly this was the only thing that worked for me ;), along with (for the sake of posterity) some concrete, specific examples of what to change.