Rerouting VPN Traffic from Cisco AnyConnect

misc

I am connecting to a Client's network via the Cisco AnyConnect VPN. I'm quite impressed with the security of the client, it allows the VPN administrator to have alot of control over how the client can connect.

One problem I was facing though is that I couldn't connect to the internet while I am connected to the client's VPN. The VPN changed my default gateway to route everything through the VPN. Now since I don't want my internet traffic going through the VPN I have to change my default gateway back to my own router (192.168.2.1 in my case), I do that with the command (I'm on a Mac):

sudo route change default 192.168.2.1

Now I need to add a special routing rule to allow me to connect to the servers I need to get to on the VPN server (you may or may not need to do this):

sudo route add 192.168.123.0 10.1.1.1

Where 10.1.1.1 would be the VPN gateway, and 192.168.123.0 is the network the servers I need to connect to are on.

After doing all this you would think everything would be setup for me to work, but I still couldn't connect to the internet! When I tried to ping google this is what I get:

ping: sendto: Permission denied
Request timeout for icmp_seq 0

It turns out after some digging I discovered that the Cisco AnyConnect VPN client was adding rules to my Mac's local firewall (ipfw). You can list the firewall rules using:

sudo ipfw -a list

One of the lines in there was:

01200  667 136583 deny ip from any to any

Which basically blocks all internet traffic except those that were specified explicitly specified by the VPN client. You can delete the rule using this command:

sudo ipfw delete 01200

Where 01200 is the first set of numbers on the line. You may want to add in some additional protection back as well, you can do that as you see fit. The key point of this blog entry though is to point out that the firewall was manipulated by the Cisco AnyConnect client, and in order to customize how it works you need to alter the firewall settings each time you connect.



2 people found this page useful, what do you think?

Trackbacks

Trackback Address: 753/E01FEE9867E6F0BB5B3DE36908585F56

Comments

On 07/13/2010 at 7:40:53 AM EDT deber wrote:
1
hm...I use ProteMac NetMine (protemac.com) as a firewall

On 08/02/2010 at 12:57:24 PM EDT rodoslavov wrote:
2
I would like to exchange links with your site www.petefreitag.com Is this possible?

On 08/09/2010 at 3:19:28 PM EDT Austinn wrote:
3
Creative work around, but all you needed to do was call the VPN administrator and tell him your VPN profile needs to be set up for Split Tunnel. This way, all traffic that does not match one or more specific ranges of IP addresses configured for the split tunnel will follow the same path it would normally take when you are not connected via VPN. Properly configured, split tunnel will give you full access to your normal internet connection while connected to VPN...

On 06/24/2012 at 2:36:03 PM EDT Eli wrote:
4
I just came across this blog post. I've actually been working on an automated way of doing this and thought I'd post what I have here. This is meant to be run immediately after connecting with Cisco Anyconnect and should work on any Mac. Note this doesn't make the changes it just outputs what you need to enter to make the changes yourself. Also you'll need to populate the list for your VPN networks you want to route.

#!/bin/bash

# Add in your VPN networks to route here # For example : # VPNNETS="10.39.0.0/16 10.27.8.0/24 10.27.9.0/24" VPNNETS=""

if [ $UID -ne '0' ]; then echo "This program must be run as root, aborting." echo exit fi

IPFWLNGTH=`ipfw list|wc -l`

if [ $IPFWLNGTH -lt 2 ]; then echo "This program must be run immediately after the Cisco VPN, reconnect and try again." echo exit fi

LANIPR=`ipfw list |grep en|grep out|awk {'print $5;'}|uniq|awk -F. {'print $1 "." $2 "." $3 ".0/24";'}|xargs` LANTIP=`ipfw list |grep en|grep out|awk {'print $5;'}|uniq|awk -F. {'print $1 "." $2 "." $3;'}|xargs` LANIF=`ipfw list |grep en|grep out|grep any|awk {'print $12;'}|uniq|xargs` DLANGW=`netstat -rn |grep UGScI|awk {'print $2;'}` # LANGW is in order of interfaces so en0 is first LANGW=`netstat -rn |grep en|grep UHLI|awk {'print $2;'}|xargs` VPNIF=`netstat -rn |grep -P "^\d+.*utun1.*UCS.*$"|awk {'print $2;'}` VPNIP=`netstat -rn |grep -P "^\d+.*utun1.*UCS.*$"|awk {'print $1;'}` VPNGW=`ifconfig |grep -a1 utun1|grep inet|grep -v inet6|awk {'print $2;'}|xargs`

# Load arrays declare -a ALANIPR=($LANIPR); declare -a ALANTIP=($LANTIP); declare -a ALANIF=($LANIF); declare -a ALANGW=($LANGW); ## reverse ALANGW RLANGW=( $(echo ${ALANGW[@]} | awk '{for (i=NF;i>=1;i--) printf $i" "} END{print ""}') )

#Number of lans ALENG=${#ALANIPR[@]}

# Firewall Rule to delete FWALLRL=`ipfw -a list|grep "deny ip from any to any"|awk {'print $1;'}`

# Output section echo "Your number of lans is $ALENG" echo "Your lan IP Range is $LANIPR" echo "Your LAN 3 octet is $LANTIP" echo "Your LAN Interface is $LANIF" echo "Your Default LAN Gateway is $DLANGW" echo "Reverse Gateways are ${RLANGW[@]}" echo "Your VPN Interface is $VPNIF" echo "Your VPN IP Range is $VPNIP" echo "Your VPN Gateway is $VPNGW" echo echo "Enter the following as root to enable split tunnel" echo echo "ipfw delete $FWALLRL" echo "route delete default" for i in $LANTIP do echo "route delete -net $i" done echo "route add default $DLANGW -ifp ${ALANIF[0]}" for (( i=0; i<$ALENG; i++ )) do echo "route add -net ${ALANIPR[$i]} default -ifp ${ALANIF[$i]}" done for VPNNET in $VPNNETS do echo "route add -net $VPNNET $VPNGW -ifp $VPNIF" done

On 09/13/2012 at 3:55:33 PM EDT Scott wrote:
5
This helped but I had to cobble it together with some more info I found elsewhere. I ended up writing this script that automates the process:

<code> #!/usr/bin/python

# The Cisco AnyConnect VPN Client is often configured on the server to block # all other Internet traffic. So you can be on the VPN <b>OR</b> you can have # access to Google, etc. # # This script will fix that problem by repairing your routing table and # firewall after you connect. # # The script does require admin (super user) access. If you are prompted for # a password at the start of the script, just enter your normal Mac login # password. # # The only thing you should need to configure is the vpn_ip_network. # Mine is 10.x.x.x so I just specify '10' but you could be more specific # and use something like '172.16' vpn_ip_network = '10'

import sys import subprocess

def output_of(cmd): lines = subprocess.Popen(cmd if isinstance(cmd, list) else cmd.split(' '), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0] try: lines = lines.decode('utf-8') except Exception: pass return [line.strip() for line in lines.strip().split('\n')]

sys.stdout.write("Mac Account Login ") good_firewall_ids = set([line.partition(' ')[0] for line in output_of('sudo ipfw -a list')]) sys.stdout.write('Firewall Saved.\n')

gateway = None for line in output_of('route get default'): name, delim, value = line.partition(':') if name == 'gateway': gateway = value.strip() p = subprocess.Popen(['/Applications/Cisco/Cisco AnyConnect VPN Client.app/Contents/MacOS/Cisco AnyConnect VPN Client'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) was_disconnected = False while True: line = p.stdout.readline() if line == ' or p.poll(): sys.stdout.write("Never connected!\n") break try: line = line.decode('utf-8') except Exception: pass if 'Disconnected' in line: sys.stdout.write('Waiting for you to enter your VPN password in the VPN client...\n') was_disconnected = True if 'Connected' in line: if was_disconnected: subprocess.Popen(['sudo','route','-nv','add','-net',vpn_ip_network,'-interface','utun0'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait() subprocess.Popen(['sudo','route','change','default',gateway], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait() unfriendly_firewall_ids = list(set([line.partition(' ')[0] for line in output_of('sudo ipfw -a list')])-good_firewall_ids) extra = ' if unfriendly_firewall_ids: subprocess.Popen('sudo ipfw delete'.split(' ') + unfriendly_firewall_ids, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait() sys.stdout.write("VPN connection established, routing table repaired and %d unfriendly firewall rules removed!\n" % len(unfriendly_firewall_ids)) else: sys.stdout.write("VPN connection established and routing table repaired!\n") else: try: subprocess.Popen.kill(p) sys.stdout.write('VPN was already connected. Extra VPN client closed automatically.\n') except Exception: sys.stdout.write('VPN was already connected. Please close the extra VPN client.\n') break break else: sys.stdout.write("Couldn't get gateway. :-(\n") </code>

On 09/13/2012 at 3:56:27 PM EDT Scott wrote:
6
Hmm, formatting didn't work like I had hoped. My script is also here: http://superuser.com/questions/91191/how-to-force-split-tunnel-routing-on-mac-cisco-vpn/473766#473766

Post a Comment




  



Spell Checker by Foundeo

Recent Entries



foundeo


did you hack my cf?