I'm using the following command to run a QEMU VM:

qemu-system-x86_64 -enable-kvm -m 1024 -smp 2 -hda disk.qcow2

By default, the guest OS has internet access, but can also access open ports on the host OS. How can I prevent the guest OS from accessing the host ports (but without limiting its internet access)?


This looks somewhat problematic if you do not have experience of advanced iptables manipulation and overview of how Linux filters traffic for local processes.

In your mode qemu runs an emulated NAT: all calls to NIC from guest will be translated as socket/connect/send/recv calls by qemu process itself. This means that connections are made by machine itself, from At this point you can run qemu as another user, and filter that user by adding an owner match:

iptables -I OUTPUT -o lo -m owner --uid-owner username -m multiport --dports ports -j DROP

where username is a name of user you want to filter and ports is a comma separated list of ports you wish to disable for that machine. To run qemu as another user, you need to run it via tools like sudo or logging in as the user with su or login.

Without this, you end up to filter yourself, so if you will add a general rule to filter ports, you will be blocked from accessing these ports as well.

Another way is to change the way qemu does networking. A good way to filter traffic well is to bind qemu to virtual ethernet device:

  • Enable packet forwarding.

  • Install tunctl, add virtual network interface which owner is you:

tunctl -u yourname -t qemu

(remember to add this command to something like rc.local to make it permanent)

  • Configure qemu interface (use ip / ifconfig or other OS provided tool) to assign a free /24 subnet to it. This subnet is needed to be set in your guest OS as well. Then run qemu with -net tap,ifname=qemu,script=off. Configure guest OS networking again.

Then you can easily filter guest OS traffic which is represented by qemu virtual interface:

iptables -I FORWARD -i qemu -m multiport --dports ports -j DROP

should work.

But the NAT stopped working. If you need to make NAT work again, you should add a rule that will patch IP addresses going out of your machine. If you have eth0 interface where your all traffic goes, you enable NAT for it:

iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.