Sunday, July 31, 2011

Cisco ASA 5500 and iPhone/iPad VPN

This weekend I decided to setup VPN access to my home network for my iPhone and iPad. SSH just doesn't cut it all the time. I knew VPN was available natively in iOS but I was disappointed that nobody had written an app that supports OpenVPN -- my VPN software of choice. Jailbreaking (on iPhones at least) doesn't have a great hassle:reward ratio these days so I decided it was time to man up and turn my ASA into a VPN server that would be compatible with iOS.

First off, let me tell you about the general setup. The router is a Cisco ASA 5505 running ASA IOS 8.2(5) with a basic license. It is already doing NAT, dhcp, and some basic port mapping for my home network. The phone is an iPhone4 with the current Verizon iOS firmware (4.2.10). It is not jailbroken. And my iPad is running iOS 4.3.5 -- also not jailbroken.

Googling various combinations of "VPN" "iPhone" and "ASA" eventually landed me at this excellent Cisco article:

http://www.cisco.com/en/US/docs/security/asa/asa82/configuration/guide/l2tp_ips.html

Although this looks a little scary at first, it is the best resource I found for understanding and setting up the basics. It also gives you a mostly working configuration example. In fact, there are only a handful of lines I change from its configuration example to "ensure ASA compatibility with a native VPN client on any operating system."

90% pasted straight from that Cisco link, here is what is required on your ASA:
ip local pool VPN_pool 172.16.29.1-172.16.29.10
group-policy VPN_policy internal
group-policy VPN_policy attributes
 dns-server value 8.8.8.8 8.8.4.4
 vpn-tunnel-protocol l2tp-ipsec
tunnel-group DefaultRAGroup general-attributes
 default-group-policy VPN_policy
 address-pool VPN_pool
tunnel-group DefaultRAGroup ipsec-attributes
 pre-shared-key *
tunnel-group DefaultRAGroup ppp-attributes
 no authentication pap
 authentication chap
 authentication ms-chap-v1
 authentication ms-chap-v2
crypto ipsec transform-set trans esp-3des esp-sha-hmac
crypto ipsec transform-set trans mode transport
crypto dynamic-map dyno 10 set transform-set trans
crypto map vpn 20 ipsec-isakmp dynamic dyno
crypto map vpn interface outside
crypto isakmp enable outside
crypto isakmp policy 10
 authentication pre-share
 encryption 3des
 hash sha
 group 2
 lifetime 86400
crypto isakmp nat-traversal 20
username happyvpn password changeme mschap
access-list VPN_nonat extended permit ip 172.16.31.0 255.255.255.0 172.16.29.0 255.255.255.240
nat (inside) 0 access-list VPN_nonat
Let's go over the parts of this you shouldn't blindly paste from top to bottom:
  • 172.16.29.1-172.16.29.10 are arbitrary IPs that are assigned to VPN clients. Since a basic license can only handle 10 VPN clients, it is pointless for me to make my range larger than that. These IPs must be different from your normal internal IP range(s) -- it should be a totally new local subnet

  • The dns-server values should be changed to your preferred nameservers, possibly on your local network

  • DefaultRAGroup can not be edited. This is a special Cisco tunnel-group

  • pre-shared-key * is one of the two passwords needed to connect, the * represents what you want that password to be

  • At the previously mentioned cisco.com link, "crypto dynamic-map dyno 10 set transform-set set trans" has a typo in it and gives a fairly straightforward error. It is fixed in my version above

  • username happyvpn password changeme mschap is how you create an account on the ASA for a VPN user. There are other ways of authenticating but this is the easiest

  • access-list VPN_nonat extended permit ip 172.16.31.0 255.255.255.0 172.16.29.0 255.255.255.240 In this example, 172.16.31.0/24 is my normal home network, and 172.16.29.0/27 is the range I assign VPN IPs from (as set by the ip local pool VPN_pool ... command)
That is the full ASA VPN configuration needed.

The iPhone setup is very simple. This is under Settings->General->Network->VPN:


  • The Server is your public IP or hostname. I have been using a free account at DynDNS.com for years on my home cablemodem with a dynamic IP

  • The Account is the username your set on the ASA with username; the Password is its password

  • The Secret is the password you set with pre-shared-key

  • Send All Traffic does not work with this configuration because of the VPN_nonat rule. I didn't want to send all my traffic through my home VPN anyway
Finally, flip VPN from Off to On and you should get connected with a new VPN icon at the top:


You now have access to the private IPs behind your ASA like any happy VPN connection.

Doesn't work? Let me give you the phone number and IRC haunts of my buddy to helped me when I was stuck on that VPN_nonat thing... one sec... okay just kidding. I am by no means a Cisco guru and probably can't help you! This exact configuration works for me under the versions mentioned above as of today. I did find one document from Cisco on common VPN problems that includes fixes for both traditional IOS devices and PIX/ASA IOS:

http://www.cisco.com/en/US/products/ps6120/products_tech_note09186a00807e0aca.shtml

That covers some solid troubleshooting. My next advice would be to setup logging on your ASA and see what the logs say. I used a simple app to ping for testing from the phone. Finally, some useful stats/troubleshooting commands on your ASA are:
show vpn-sessiondb
show crypto isakmp sa
show crypto ipsec sa
Good luck!