Setting up QEMU with a NAT

I’ve always had a lot of trouble setting up QEMU so that I’m able to ping from my host to the guest OS, and the documentation out there doesn’t help much. So here are my own instructions, mostly so that I don’t forget them :/

First. Most instructions out there use bridging at layer 2 in order to join an ethernet and tap (simulated ethernet) device. The biggest problem with this approach is that it doesn’t work the same way with wireless devices. Most probably you would need WDS (only certain hardware supports it), or parprouted to do layer 3 bridging. There are other problems like the fact that you need to bring down the interface. So no, bridging is not a nice solution. For reference see this thread.

Another approach is to use a proxy arp. This is slightly better because it doesn’t need to bring down the interface, nor needs any special hardware support. However, you need to reserve one IP address for the spoofed ARP address. I chose not to use this approach mostly because I’m not familiar with this. For reference check this howto.


The simplest approach is to use a NAT. Here are the steps:

As root in the host, create and setup your tap0 device ( will be our NAT network, and felipec our user):
tunctl -u felipec -t tap0
ifconfig tap0 up

Update: You need to run your guest like this:
qemu-kvm -hda winxp.cow -m 512 -net nic -net tap,ifname=tap0,script=no

In your guest:
ip addr:

note: I found some problems on my Windows XP guest; I had to disable the firewall
note: I’m using Google’s DNS, if you want to use the one in your host check /etc/resolv.conf


As root in the host:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
iptables -I FORWARD 1 -i tap0 -j ACCEPT
iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT

That’s it. Now you should be able to use ping back-and-forth between the guest and the host, and both should be able to access the Internet 🙂


12 thoughts on “Setting up QEMU with a NAT

  1. Pingback: configure nat of qemu - Information technology

  2. one of it is

    brctl addbr br-dev
    brctl addif br-dev em1
    ifconfig br-dev “em1 ip address”
    ifconfig em1 up

    route add default gw via br-dev

    and give the br-dev name in the configuration of virt-manager

    my vm system is ubuntu.

  3. Just in case, if you have multiple static IPs and want to use one specific ips, just modify the rule in POSTROUTING as –
    iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to-source

    And all traffic would appear to arrive from there.

  4. Kindly share steps to configure the NAT in windows, Enable IP forwarding and Set iptables rules which should work for both windows 7 as well as on XP

  5. Does anyone knows how ti reproduce this on OS X ? Mac doesn´t support iptables command. I guess that it does have a natd command. Any hint ?

  6. Great, this really worked (Debian 8)! Your post was very helpful, as I also had a difficult time figuring this out from the documentation. Thanks a lot for sharing it!

  7. The first problem is the lack of support for sudo tunctl; the second is the reply that recommends using libvirt, which shows a complex set of steps, none of which appears to use any form of the qemu command, making it a disconnected distraction, rather than an example.

  8. damn man, thanks a lot, was googling and trying 3 days different manuals, but only yours worked 🙂

Leave a Reply

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

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

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s