Forwarding Incoming Connections By default, guests that are connected via a virtual network with can make any outgoing network connection they like. Incoming connections are allowed from the host, and from other guests connected to the same libvirt network, but all other incoming connections are blocked by iptables rules. If you would like to make a service that is on a guest behind a NATed virtual network publicly available, you can setup libvirt's "hook" script for qemu to install the necessary iptables rules to forward incoming connections to the host on any given port HP to port GP on the guest GNAME: 1) Determine a) the name of the guest "G" (as defined in the libvirt domain XML), b) the IP address of the guest "I", c) the port on the guest that will receive the connections "GP", and d) the port on the host that will be forwarded to the guest "HP". (To assure that the guest's IP address remains unchanged, you can either configure the guest OS with static ip information, or add a element inside the element of the network that is used by your guest. See the libvirt network XML documentation address section for defails and an example.) 2) Stop the guest if it's running. 3) Create the file /etc/libvirt/hooks/qemu (or add the following to an already existing hook script), with contents similar to the following (replace GNAME, IP, GP, and HP appropriately for your setup): Use the basic script below or see an "advanced" version, which can handle several different machines and port mappings here (improvements are welcome) or here's a python script which does a similar thing and is easy to understand and configure (improvements are welcome): #!/bin/bash # IMPORTANT: Change the "VM NAME" string to match your actual VM Name. # In order to create rules to other VMs, just duplicate the below block and configure # it accordingly. if [ "${1}" = "VM NAME" ]; then # Update the following variables to fit your setup GUEST_IP= GUEST_PORT= HOST_PORT= if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then /sbin/iptables -D FORWARD -o virbr0 -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT fi if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then /sbin/iptables -I FORWARD -o virbr0 -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT fi fi 4) chmod +x /etc/libvirt/hooks/qemu 5) Restart the libvirtd service. 6) Start the guest. (NB: This method is a hack, and has one annoying flaw in versions of libvirt prior to 0.9.13 - if libvirtd is restarted while the guest is running, all of the standard iptables rules to support virtual networks that were added by libvirtd will be reloaded, thus changing the order of the above FORWARD rule relative to a reject rule for the network, hence rendering this setup non-working until the guest is stopped and restarted. Thanks to the new "reconnect" hook in libvirt-0.9.13 and newer (which is used by the above script if available), this flaw is not present in newer versions of libvirt (however, this hook script should still be considered a hack).