This post is mainly for documentation purposes, since this is a task one does not have to do on a daily basis and it always takes some time to get back into the matter. The scenario is a debian kvm host, running libvirt for kvm virtual machines and shorewall for firewalling. The ip address of the guest shall be 18.104.22.168.
First we want to configure the network interface eth0 as bridge, which we'll call vmbr0. For this we edit the /etc/network/interfaces so it contains the following:
iface eth0 inet manual auto vmbr0 iface vmbr0 inet dhcp bridge_ports eth0 bridge_stp off bridge_fd 0 up route add -host 22.214.171.124 dev vmbr0 down route del -host 126.96.36.199 dev vmbr0
Now we can assign our virtual machine the device vmbr0 as bridge, for example via <source bridge='vmbr0'/> in the respective xml-file in /etc/libvirt/qemu/ or via virt-manager. Next we need to configure shorewall; for this we copy an example from /usr/share/doc/shorewall/examples/ into /etc/shorewall/ and change every entry from eth0 to vmbr0, so vmbr0 is associated with the zone net. Now we can edit the rules file to something like this:
# the virtual machine shall have unrestricted access ACCEPT net:188.8.131.52 net # sshing and pinging shall be allowed from everywhere SSH(ACCEPT) net net:184.108.40.206 Ping(ACCEPT) net net:220.127.116.11 # we want http to only be accessible from our /16 subnet ACCEPT net:192.0.0.0/16 net:18.104.22.168 tcp 80 ACCEPT net:192.0.0.0/16 net:22.214.171.124 tcp 443 # reject everything that's not explicitly allowed REJECT net net:126.96.36.199
And this was all. Not very hard to do, but if you don't add guests very often, it's easy to forget how to setup a bridge in debian or in which order shorewall matches the rules, namely going through them in order and apply one as soon as it matches.