More times than I care to mention I find myself having to battle with libvirt taking over my iptables rules and starting its own instance of dnsmasq, which just ends up ruining my whole day. Libvirt is a great abstraction layer for virtualisation, and although its xml config format and command line interface are well documented, how it works under the hood is less so.
Libvirt takes over your IPTables rules and dns
On a server, it can be argued, that you shouldn't be running anything fancy in DOM0, to use XEN parlance, but run your DNS servers and other iptables rules in the virtual machine itself. On a desktop that you run virtual machines on, it is as not as strong an argument.
For example, at home, I recently switched out my ADSL line for the prime connect solution from Neotel. This was forced on me when Telkom told me it would take 3 weeks to repair my non-functioning ADSL line. The CDMA modem provided by Neotel, is a USB based solution. This suxs, as it means I couldn't use my openwrt router as a gateway anymore for internet sharing. So I had to setup my desktop to do the connection sharing.
Basic Internet Sharing Setup with IPTables
The basic rules for this type of sharing using iptables are given below.
iptables -P INPUT DROP
iptables -I INPUT -i eth0 -j ACCEPT
iptables -I INPUT -i local -j ACCEPT
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -P FORWARD DROP
iptables -I FORWARD -i eth0 -j ACCEPT
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE
don't forget to "echo 1 > /proc/sys/net/ipv4/ip_forward"
Additional/Custom IPTable Rules
Another thing you would like to setup when doing internet sharing is to setup dnsmasq to provide dns and dhcp services if necessary to your home network. Just doing "apt-get install dnsmasq" usually does the trick. Now if you have libvirt running as well, it starts its own version of dnsmasq and sets up its own iptables rules. I usually just add my iptable rules to /etc/rc.local and it lives well with the rules setup by libvirt.
Running Your Own DNS Server in Parallel with Libvirt
To get your own version of dnsmasq working properly is a bit more work, but not that much. The trick is to edit the dnsmasq.conf file and set the "interface=" parameter to the physical Ethernet port of the LAN interface that it will provide dns services too. e.g interface=eth0. You also need to uncomment the "bind-interfaces" parameter. This will get dnsmasq listening on the eth0 interface only. You can then avoid error messages like
"dnsmasq: failed to create listening socket: Address already in use"
because libvirt has already stolen the port.