Thursday, February 14, 2013

Force traffic through your Cisco AnyConnect VPN connection on Mac or Linux

Scenario: You need to access a public IP address (x.x.x.x) that is only accessible from a private network that you have VPN access to using Cisco AnyConnect.  But, when you try to go to x.x.x.x, you are blocked because you were routed through the internet instead of the VPN.

Solution:  Add a route to your routing table to force network traffic through the VPN and add rules to your firewall because the default rules set up by Cisco AnyConnect won't allow this traffic.

Steps:
1) Sign into the VPN and open a command terminal.  Note, I'm using version 3.0.11024 for this.

2) Get the destination IP address if you don't already know it.  You could try pinging the hostname if thats all you have.  Make note of it.

DESTINATION_IP=x.x.x.x

3) Get the IP address of the VPN gateway.  Look at you network interfaces using the ifconfig command.  Cisco AnyConnect should have added it, identified by an interface id called utun0 (Mac) or cscotun0 (Linux).  Or, look at your AnyConnect client.  The IP address should be in there somwhere as "Client Address".  Make note of it.

VPN_GATEWAY_IP=y.y.y.y

On Mac OS X:

4) Add the route to your routing table.  I would suggest listing the routing table before and after adding the new route to ensure it gets added.  List the routing table using the command netstat -nr.  Add the new route with this command

sudo route add -host $DESTINATION_IP $VPN_GATEWAY_IP

5) Add rules to the firewall to allow all IP traffic to and from the destination using the VPN network interface.  Again, look at the existing rules before and after using the command sudo ipfw list to ensure it gets added.  Insert the rules with these 2 commands

sudo ipfw add 00025 skipto 33 ip from $VPN_GATEWAY_IP to $DESTINATION_IP out

sudo ipfw add 00025 skipto 33 ip from $DESTINATION_IP to $VPN_GATEWAY_IP in

### NOTE:  Line numbers 00025 and 33 worked for me, but these are dependent on the rules that your VPN client has defined.  The important thing is that the new rules go before the rule "deny ip from any to any" and skipto goes  beyond it.

On Linux:

The steps are the same as described above but syntax is different.  Here are the commands you'll need.  You will probably have to do these with sudo or as root

4) Add the route to your routing table using the route command.  I would suggest listing the routing table before and after adding the new route to ensure it gets added.  List the routing table using the command route alone.  Add the new route with this command

route add $DESTINATION_IP gw $VPN_GATEWAY_IP

5) Add rules to the firewall to allow all IP traffic to and from the destination using the VPN network interface.  Again, look at the existing rules before and after using the command iptables -L to ensure it gets added.  Insert the rules with these 2 commands

iptables -I ciscovpn 32 -j ciscovpnfw -p all -s $DESTINATION_IP/32 -d $VPN_GATEWAY_IP 

iptables -I ciscovpn 32 -j ciscovpnfw -p all -d $DESTINATION_IP/32 -s $VPN_GATEWAY_IP 

### NOTE: Line number 32 worked for me.  The important thing is that the new rules go before the rule "DROP all -- anywhere anywhere"



You could obviously modify the steps above to grant access to a whole network or range of IP address if required.