Results 1 to 2 of 2

Thread: Bridge KVM guests to LAN & VPN only (no direct internet)

Hybrid View

  1. #1
    Join Date
    Sep 2012
    Beans
    12

    Bridge KVM guests to LAN & VPN only (no direct internet)

    Hi

    I'm *relatively* new to Ubuntu. I used Linux some time ago, but haven't used it much for a while, and was really using it more for basic tasks + a bit of coding rather than complex set-ups. I'm posting this here (having toyed with the idea of posting it in the Absolute Beginners section because this is only my second post or so, and in the Virtualization section because it involves KVM network bridges), but decided that ultimately it was a pretty specific question that belongs in the networking forum. I hope that's ok.

    I have in the last few months been getting back into linux (specifically Ubuntu Desktop 12.04 x64), and have set up KVM virtual machines to run multiple servers on my LAN. After (significant) tweaking, it now works great.

    However, I would like to be able to set certain VM guest machines to only be able to access external networks securely via a VPN connection. I also want this to "fail safe" rather than "fail dangerous", i.e. if a setting gets inadvertently wiped / program crashes, the relevant VM guest machines are denied internet access rather than being given unsecured external network access over something other than the VPN. Ideally, I would like to be able to manage this from the command line, but if necessary a GUI solution would be a good start.

    What I have tried reading up on so far:
    • Using firestarter to set up Internet Connection Sharing to share the VPN connection to the other VMs: I have tried this, and this works to share the VPN connection (tun0) with the bridge connection (br0) so that the KVM guests can access the VPN connection. However, I have found that if firestarter is disconnected, in certain circumstances the VM guest machines can then access the internet via the bridge connection just as they could before firestarter was installed (i.e. this "fails dangerous" rather than "fails safe") (also this is via a gui, which is not ideal)
    • Using shorewall (e.g. http://www.shorewall.net/OPENVPN.html) - at first glance shorewall looks potentially useful, however upon further reading it looks like this is only useful to prevent access / filter packets, i.e. it doesn't act as a router but rather as just a pure firewall.
    • Using iptables - I am aware that this could probably be done using iptables, however I'm struggling to understand based on the iptables documentation how I might set up a situation like this. I understand the basics of setting up iptables rules / chains (and which tables to put them in) now, but I don't understand how one might construct something more complex like what I have described above. If iptables is the solution, again I would like it to fail safe (i.e. the VPN connection is run on the host and it shares the connection with the guest VM, and the connection is *enabled* through iptables forwarding) rather than bridging the host and guest network completely and then using iptables to block insecure access to the external network from the guest VM, (i.e. I want a setup where if the iptables rules get flushed, access is lost rather than gained).


    The simplest solution would seem to be setting up a bridge connected only to tun0 (my VPN tunnel interface) which is then used by each of the guest VMs - if tun0 goes down, they lose internet access completely (as per my requirements). However, when I try to set that up by changing the bridge settings to the following in the /etc/network/interfaces file on the host machine:
    Code:
     auto br0
     iface br0 inet dhcp
             bridge_ports tun0
             bridge_stp off
             bridge_fd 0
             bridge_maxwait 0
    then restart networking, I get the following:
    Code:
    hypervisor@hypervisor:~$ sudo /etc/init.d/networking restart
     * Running /etc/init.d/networking restart is deprecated because it may not enable again some interfaces
     * Reconfiguring network interfaces...                                          RTNETLINK answers: No such process
    ssh stop/waiting
    ssh start/running, process 4922
    can't add tun0 to bridge br0: Invalid argument
    Failed to bring up br0.  
                                              [ OK ]
    My LAN subnet is 192.168.0.xxx mask: 255.255.255.0 gw: 192.168.0.1

    My VPN subnet (which is not managed by me, I just connect to it) is 10.8.0.xxx

    Currently (while connected to the VPN), ifconfig output on the host looks like:
    Code:
    br0       Link encap:Ethernet  HWaddr 2a:0d:xx:xx:xx:xx
              inet6 addr: fe80::280d:xxxx:xxxx:xxxx/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:112 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:0 (0.0 B)  TX bytes:22250 (22.2 KB)
    
    br0:avahi Link encap:Ethernet  HWaddr 2a:0d:xx:xx:xx:xx
              inet addr:169.254.aaa.aaa  Bcast:169.254.255.255  Mask:255.255.0.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    
    eth0      Link encap:Ethernet  HWaddr 14:da:xx:xx:xx:xx
              inet addr:192.168.0.bbb  Bcast:192.168.0.255  Mask:255.255.255.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:48158 errors:0 dropped:0 overruns:0 frame:0
              TX packets:6727 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:6469598 (6.4 MB)  TX bytes:721434 (721.4 KB)
              Interrupt:49 Base address:0xc000
    
    lo        Link encap:Local Loopback
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:16436  Metric:1
              RX packets:65 errors:0 dropped:0 overruns:0 frame:0
              TX packets:65 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:5527 (5.5 KB)  TX bytes:5527 (5.5 KB)
    
    tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
              inet addr:10.8.0.ccc  P-t-P:10.8.0.ddd  Mask:255.255.255.255
              UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
              RX packets:170 errors:0 dropped:0 overruns:0 frame:0
              TX packets:178 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:100
              RX bytes:30435 (30.4 KB)  TX bytes:14485 (14.4 KB)
    
    tun1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
              inet addr:10.8.0.eee  P-t-P:10.8.0.fff  Mask:255.255.255.255
              UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
              RX packets:388 errors:0 dropped:0 overruns:0 frame:0
              TX packets:1162486 errors:0 dropped:1158611 overruns:0 carrier:0
              collisions:0 txqueuelen:100
              RX bytes:96421 (96.4 KB)  TX bytes:1740467809 (1.7 GB)
    
    virbr0    Link encap:Ethernet  HWaddr c6:d3:xx:xx:xx:xx
              inet addr:192.168.122.ggg  Bcast:192.168.122.255  Mask:255.255.255.0
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
    My /etc/network/interfaces file on the host machine looks like this:
    Code:
    auto lo
    iface lo inet loopback
    
    auto eth0
    iface eth0 inet dhcp
    
    auto br0
    iface br0 inet dhcp
            bridge_ports eth0
            bridge_stp off
            bridge_fd 0
            bridge_maxwait 0
    My guest VM xml config file contains the following:
    Code:
    <interface type='bridge'>
        <source bridge='br0'/>
        <mac address='14:da:xx:xx:xx:xx'/>
        <model type='virtio'/>   
        <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    I would be grateful for any solution (based on iptables or otherwise), because I have been tearing my hair out over these iptables rules...

    Many thanks

    sj1981

  2. #2
    Join Date
    Sep 2012
    Beans
    12

    Re: Bridge KVM guests to LAN & VPN only (no direct internet)

    I am continuing to bang my head against a wall on this, and have come up with a few more pointers / insights, mostly based on the OpenVPN website (previously I was mostly looking at KVM / virtualization sites):

    • It looks like in order to bridge to a VPN, I would need to connect using a tap interface rather than a tun interface (Source: http://openvpn.net/index.php/open-so...iguration.html ). You can't bridge a tunnel (which is a virtual cable) only a tap (which is a virtual interface) to another interface.

    • My VPN provider only seems to provide a tun interface (I tried changing my client .conf file to say "dev tap" and it still created a tun when I connected), so I guess bridging is off of the table (also bridging is apparently not normally recommended - http://openvpn.net/index.php/open-so...d-routing.html ).



    I think the routing that I need to set up is as follows:

    Code:
    # (1) Allow initiation of connections from the virtual machines
    #     (guest machines) to the VPN connection
    iptables -I FORWARD -i br0 -o tun0 -s 192.168.0.0/24 -d 10.8.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
    
    # (2) Allow bi-directional and related traffic once 
    #     connection is established
    iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    There may also be an additional rule required for the other direction, but I'm assuming the RELATED, ESTABLISHED rule takes care of that.

    This is my intended network:
    http://pastebin.com/fMDT90qt
    (I can only put it on pastebin because ubuntu forums recognises my 'ascii art' as images and won't let me post it here directly)


    NOTE: [Example guest VM] is shown outside of the perimeter of [OpenVPN client, KVM host and ICS server], but in fact is inside that perimeter in hardware terms, as it is a guest virtual machine running on the [OpenVPN client, KVM host and ICS server] box

    For this to work, I also need to break the direct link between br0 and eth0 (and let the packet forwarding of iptables work its magic instead).

    However, if I comment out the line:
    bridge_ports eth0
    from the definition of br0 in /etc/network/interfaces on the [OpenVPN client and ICS server] machine, and restart networking using init.d (and remove the bridge interface from the guest VM XML file using virsh edit [guestVM]), then I lose network connectivity completely on both machines, i.e. ping 8.8.8.8 and ping 192.168.0.1 both fail.

    Other observations:
    • virbr0 seems to be automatically set up by qemu init scripts

    • Not sure what br0:avahi and br1 are for, or where they come from.


    Key questions:
    Why does my connectivity fail on both machines when I disconnect the bridge and rely on forwarding? Even if the VM's virtual network interface loses all connectivity, shouldn't the host system still have access?
    If the guest OS will lose all connectivity when I break the bridge connection to host OS eth0, is there a way to forward the tun0 to the guest OS without using bridging?


    I would really appreciate some guidance on either of these points!

    Many thanks

    sj1981

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •