I am not an expert and I came out with a working hack for my need of isolating some VM in my virtual farm from the rest of other VMs.
I use Xen+libvirt. The ingredients for this receipt are:
- a working vm
- a persistent named tun interface that connects somewhere via VPN
- policy routing
Let us call the existing VM goofy. It has a virtual NIC attached to a virtual bridge created with libvirt. This virtual bridge is in NAT mode.
<network connections='1'> <name>unsafe-nat</name> <uuid>fa91e8bf-6666-5555-4444-222211110000</uuid> <forward dev='tun-ovpn' mode='nat'> <nat> <port start='1024' end='65535'/> </nat> <interface dev='tun-ovpn'/> </forward> <bridge name='virbr3' stp='on' delay='0'/> <mac address='52:54:00:9a:ca:ca'/> <domain name='unsafe-nat'/> <ip address='192.168.126.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.126.128' end='192.168.126.254'/> </dhcp> </ip> </network>
As you can see, it is a bridge that includes all the virtual NICs of the VMs and an interface on my host, tun-ovpn, that I previously created with openvpn.
Now you can finish all this mess creating a new routing table, that I choose to be number 666
root@host $ ip route add to default via <vpn_gateway> dev tun_ovpn table 666 root@host $ ip route add to 192.168.126.0/24 dev virbr3 table 666
and creating a new rule to match the traffic from the subnet of the unsafe VMs
root@host $ ip rule add from 192.168.126.0/24 lookup 666
To end all of this, if you want to give access to this VM from the outside, but you don’t want to set up complicated NATing and routing rules, you can create a Tor hidden service inside goofy and bind it to ssh (adding these lines in /etc/tor/torrc)
HiddenServiceDir /var/lib/tor/ssh/ HiddenServicePort 22 127.0.0.1:22
The remaining is to secure your host from the VMs in 192.168.126.0/24 from being malicious.