How to allow local LAN access while connected to Cisco VPN?

27
2013-10
  • Ian Boyd

    How can I maintain local LAN access while connected to Cisco VPN?

    When connecting using Cisco VPN, the server has to ability to instruct the client to prevent local LAN access.

    Assuming this server-side option cannot be turned off, how can allow local LAN access while connected with a Cisco VPN client?


    I used to think it was simply a matter of routes being added that capture LAN traffic with a higher metric, for example:

      Network 
    Destination      Netmask        Gateway       Interface  Metric
       10.0.0.0  255.255.0.0       10.0.0.3        10.0.0.3      20  <--Local LAN
       10.0.0.0  255.255.0.0  192.168.199.1  192.168.199.12       1  <--VPN Link
    

    And trying to delete the 10.0.x.x -> 192.168.199.12 route don't have any effect:

    >route delete 10.0.0.0
    >route delete 10.0.0.0 mask 255.255.0.0
    >route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1
    >route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1 if 192.168.199.12
    >route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1 if 0x3
    

    And while it still might simply be a routing issue, attempts to add or delete routes fail.

    At what level is Cisco VPN client driver doing what in the networking stack that takes overrides a local administrator's ability to administer their machine?

    The Cisco VPN client cannot be employing magic. It's still software running on my computer. What mechanism is it using to interfere with my machine's network? What happens when an IP/ICMP packet arrives on the network? Where in the networking stack is the packet getting eaten?

    See also


    Edit: Things I've not yet tried:

    >route delete 10.0.*
    

    Update: Since Cisco has abandoned their old client, in favor of AnyConnect (HTTP SSL based VPN), this question, unsolved, can be left as a relic of history.

    Going forward, we can try to solve the same problem with their new client.

  • Answers
  • Indrek

    The problem with Anyconnect is that it first modifies the routing table, then babysits it and fixes it up should you modify it manually. I found a workaround for this. Works with version 3.1.00495. May work with other versions, at least similar idea should work assuming the code does not get rewritten. Fortunately for us Cisco has put the babysitter "baby is awake" call into a shared library. So the idea is that we prevent action by vpnagentd via LD_PRELOAD.

    1. First we create a file hack.c:

      int _ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEv()
      {
        return 0;
      }
      
    2. Then compile it like this:

      gcc -o libhack.so -shared -fPIC libhack.c
      
    3. Install libhack.so into the Cisco library path:

      sudo cp libhack.so  /opt/cisco/anyconnect/lib/
      
    4. Bring down the agent:

      /etc/init.d/vpnagentd stop
      
    5. Make sure it really is down

      ps auxw | grep vpnagentd
      

      If not, kill -9 just to be sure.

    6. Then fix up /etc/init.d/vpnagentd by adding LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so where the vpnagentd is being invoked so it looks like this:

      LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so /opt/cisco/anyconnect/bin/vpnagentd
      
    7. Now start the agent:

      /etc/init.d/vpnagentd start
      
    8. Fix up iptables, because AnyConnect messes with them:

      iptables-save | grep -v DROP | iptables-restore
      

      You may want to do something more advanced here to allow access only to certain LAN hosts.

    9. Now fix up the routes as you please, for example:

      route add -net 192.168.1.0 netmask 255.255.255.0 dev wlan0
      
    10. Check to see if they are really there:

      route -n
      

    The only side effect that I've observed so far is that vpnagentd is using 100% of CPU as reported by top, but overall CPU is only 3% user and 20% system, and the system is perfectly responsive. I straced it, it seems to be doing two selects in a loop when idle returning from both quickly, but it never reads or writes - I suppose the call that I cut out with LD_PRELOAD was supposed to read. There might be a cleaner way to do it, but it is good enough for me so far. If somebody has a better solution, please share.

    If something does not work, do gdb -p $(pidof vpnagentd), once attached:

    b socket
    c
    bt
    

    and see which call you are in. Then just guess which one you want to cut out, add it to hack.c and recompile.

  • ultrasawblade

    This is VERY convoluted, but if you create a minimal VM using VMWare Player or similar, and run the Cisco AnyConnect VPN client in that, it might be possible to set up routing as you want using the VMWare virtual network adapters, or simply use the VM for access to whatever resources are required via the Cisco SSL VPN and "drag/drop" files to/from your actual machine.

  • banjo

    My company still uses that vpn. The vpnc client simply changes you iptables settings that way :

    # iptables-save
    # Generated by iptables-save v1.4.10 on Sun Jun 17 14:12:20 2012
    *filter
    :INPUT DROP [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT DROP [0:0]
    -A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT 
    -A INPUT -i tun0 -j ACCEPT 
    -A INPUT -i lo0 -j ACCEPT
    -A INPUT -j DROP 
    -A OUTPUT -s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT 
    -A OUTPUT -o tun0 -j ACCEPT 
    -A OUTPUT -o lo0 -j ACCEPT 
    -A OUTPUT -j DROP 
    COMMIT
    

    It filters all except for the vpn traffic.

    Simply get the filter in a file with iptables-save, add INPUT and OUTPOUT access lines that match your needs and reapply the file with iptables-restore.

    for instance to access a local network on 192.168.0

    # Generated by iptables-save v1.4.10 on Sun Jun 17 14:12:20 2012
    *filter
    :INPUT DROP [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT DROP [0:0]
    -A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT 
    -A INPUT -s 192.168.0.0/24 -d 192.168.0.14/32 -j ACCEPT      #local in
    -A INPUT -i tun0 -j ACCEPT 
    -A INPUT -i lo0 -j ACCEPT 
    -A INPUT -j DROP 
    -A OUTPUT -s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT 
    -A OUTPUT -s 192.168.0.14/32 -d 192.168.0.0/24 -j ACCEPT     #local out
    -A OUTPUT -o tun0 -j ACCEPT 
    -A OUTPUT -o lo0 -j ACCEPT 
    -A OUTPUT -j DROP 
    COMMIT
    
  • Marki

    Any news on this?

    At what level is Cisco VPN client driver doing what in the networking stack that takes overrides a local administrator's ability to administer their machine?

    I fully agree and was wondering about the same thing.

    Anyway, it's an app that requires admin privileges to install and while it runs it may very well filter what you do...

    My attempts on Windows fail too:

    route change 0.0.0.0 mask 0.0.0.0 192.168.1.1 metric 1
     OK!
    
    IPv4 Route Table
    ===========================================================================
    Active Routes:
    Network Destination        Netmask          Gateway       Interface  Metric
              0.0.0.0          0.0.0.0      192.168.1.1    192.168.1.230     21 <-- LAN
              0.0.0.0          0.0.0.0    192.168.120.1    192.168.120.3      2 <-- VPN
    

    Haha. No metric below 20 here it seems.

  • Peter Mortensen

    I don't know if I have understood it right, but I first clarify my understanding:

    You have a local LAN (for example, say 10.0.0.0/16, and a remote Cisco VPN Server (for example, 64.0.0.0/16). You want to connect to the VPN server through the Cisco VPN client and yet you need to have the LAN access. In this case you want to separate the whole 10.0.x.x/16 from the VPN connection). The following route must be added in a Mac client:

    /sbin/route add -net 10.0 -interface en1
    

    where en1 is the interface through which you are connected to your LAN. I know you can add the same thing in Windows and Linux as well.

  • vstrale

    Shrew Soft VPN software did the trick for me, also, as Ian Boyd suggested.

    It can import Cisco VPN client profiles. I have used Cisco VPN Client version 5.0.05.0290, and after installing the Shrew VPN (version 2.1.7) and importing Cisco profile, I was able to access local LAN while connected to corporate VPN without any additional configuration of Shrew VPN connection (or software).


  • Related Question

    vmware - How can I prohibit the creation of a route in Windows XP upon connection to Cisco VPN?
  • antik

    Problem

    I have several routes that are created when I connect to my company's VPN using Cisco VPN client. (It appears to be a bug in our VPN client that we're subjected to this in the first place: Allow Local LAN Access is ON but the client is ignoring the option.)

    I have a virtual machine running on my system that I want to connect to while I'm on the VPN. I can do this reliably by deleting the route to the network of my VPN's Host-Only adapter created by the vpn client but I have to delete the route every time I connect to my VPN.

    Question

    How do I reliably prohibit either the deletion of these routes either at the time of connection, prohibit some of them from being created, or work around them?


  • Related Answers
  • antik

    Because I am using the Host-Only VM adapter with set IP addresses on both the host and guest I created a work around as follows:

    Add a persistent route from the host to the VM using the following command:

    route -p add <guest-ip-address> 255.255.255.255 <host-vmnet1-ip-address>

    Because this is a more specific route than the 255.255.255.0 route that the VPN software creates, this route is used even when connected to the VPN.