Simple Cisco VPN How-To
One of our fellow Humanitarian Centre organisations, Engineers Without Borders UK (EWB), asked for our help in setting up a virtual private network (VPN), so that their remote workers can access their file server.
This is something that ought to be really simple. It's probably the most common use case of VPNs, Windows has a built-in VPN client, and Cisco routers can be used as VPN servers. EWB want it to be simple, because they have non-technical remote workers. It turned out to be much harder and take much longer than I expected.
One of the biggest problems was the lack of useful information, and the profusion of useless. The information fell mainly into four categories:
- Cisco marketing materials touting the benefits of VPNs and their expensive Concentrator and WebVPN products;
- Cisco knowledge base articles describing the setup of complex VPN scenarios;
- Cisco command references with little or no details on what each command actually does, or how to use them together;
- Cisco exam study sites with inaccurate, out-of-date or cookie-cutter command sequences, with even less explanation of what the commands actually do.
Because I couldn't find what I was looking for, and had to work it out the hard way, I've written it up in the hope that it will help others.
I would recommend any organisations that simply want to share files to seriously consider a file-sharing service like DropBox or raw Amazon S3 instead of a local file server and VPN. In many cases the low upload bandwidth of ADSL connections, combined with internal office use of the connection. will make a VPN impractically slow, especially compared to Amazon's unlimited upload and download bandwidth. But EWB already had the file server and they just wanted to access it remotely, not to change how they work.
Our scenario is simple: an internal office network with private IP addresses, a Cisco 1800 router providing ADSL connectivity for the office, and remote field workers running Windows desktops.
Getting the Client
For simplicity, we and EWB had hoped to use the built-in VPN client on Windows, which would remove the need to download and install software on the remote workers' machines. But unfortunately the Cisco 1800 does not support this. Windows uses L2TP over IPSEC for modern, secure VPNs, as a replacement for the old insecure PPTP protocol. But Cisco has crippled the L2TP support in this router, and it only supports raw IPSEC. Only their more expensive routers support serving L2TP over IPSEC, allowing simple direct connections from Windows.
Raw IPSEC is the only remaining option on this router, but it's difficult to configure due to its complexity, and the number of choices that need to be made. The standard requires both sides to have the same settings configured, but provides no way to do this automatically. Manual configuration would make life very hard for the remote workers. To solve this problem, Cisco has a non-standard protocol for auto-configuration of the clients:
Establishing a VPN connection between two routers can be complicated, and it typically requires tedious coordination between network administrators to configure the two routers' VPN parameters.
The Cisco Easy VPN Client feature eliminates much of this tedious work by implementing Cisco's Unity Client protocol, which allows most VPN parameters to be defined at [the] IPSec server.
So if we could find a client that speaks this Unity Client protocol, then we could automate the IPsec setup for remote workers. As far as I can tell, only Cisco's own Easy VPN Client does that. Although it's technically free, you can't actually download it without a Cisco support contract, which neither we nor EWB have.
In the end we found that if you go to Cisco's VPN client software page, find the filename of the latest version of the client, and Google it, you'll find that several people have had enough of this nonsense and posted the client online, so it can be downloaded.
Of course it's important to be aware of the potential for viruses in copies that you download from random sites on the Internet, as well as fake download sites that lead you around in circles of free registrations, credit card details and pop-up porn adverts. This site worked fine for me, but it may have been taken down by Cisco's attack dogs by the time you read this.
Security with Obscurity
We decided to choose a configuration that trades some security for ease of use. So instead of authenticating with certificates, we used pre-shared keys. The VPN server has its own login system anyway, which provides an additional layer of security once the remote user is connected to the VPN.
Names and Addresses
Connecting clients need to be allocated an IP address to use over the VPN. We could have used public IPs, or private IPs in the same subnet (with proxy ARP), but we chose to use private IPs in a different subnet. This makes the routing easier, as clients and local network servers will know that they have to route the traffic via the router anyway, and it allows EWB to implement stricter network access policies for VPN clients, if they wish.
We needed to create a local pool (not a DHCP pool) to draw these addresses from:
ip local pool vpnpool 192.168.2.100 192.168.2.200
Keys to the Kingdom
We created an ISAKMP (IKE) policy to specify the authentication method and the level of encryption to be used for negotiation of IPSEC Security Associations (SAs). We chose to make this the first, highest priority policy, and to use AES-256 encryption (strong and fast), Group 2 (1024-bit) Diffie-Hellman key exchange, and pre-shared keys for client authentication as noted above:
crypto isakmp policy 1 encr aes 256 authentication pre-share group 2
Then we specified the pre-shared key itself. This is the only thing that stops random clients on the Internet from connecting to your local network, so it's even more important than a strong wireless network key. Of course this is not the real key:
crypto isakmp key ThisKeyMustBeKeptSecret address 0.0.0.0 0.0.0.0
We specify that any IP address can use it by using the wildcard address,
At the End of the Tunnel
It seems to be common in corporate environments that, when a user is connected to a VPN, all of their Internet traffic is routed through the VPN. It certainly makes it easier for the network administrators, as they don't have to define specific routes for the tunnel, but it wastes their bandwidth and makes Internet access much slower for the remote workers, so we decided not to do this.
Just routing a single subnet through a tunnel is called a split tunnel. I couldn't find simple documentation on setting it up, so I used the Cisco Easy VPN Remote example, extracting just the bits we needed to route only the 192.168.1.0/24 subnet through the tunnel.
First we have to create an access control list (ACL) that defines, on the local (source address) side, what traffic clients should route into the tunnel:
ip access-list extended ewb_office_split_tunnel remark Defines which local (office) networks a remote VPN client will route to permit ip 192.168.1.0 0.0.0.255 192.168.2.0 0.0.0.255
I'm not sure if the second half of the ACL is actually necessary. It doesn't appear to make any difference if I specify
any instead of
We use Cisco's EzVPN (Unity) protocol, as described earlier, to configure connecting clients automatically. To do this, we have to tell the server what configuration should be sent to clients when they connect:
crypto isakmp client configuration group EWB key ThisKeyMustBeKeptSecret dns 192.168.1.1 wins 192.168.1.2 pool vpnpool acl ewb_office_split_tunnel netmask 255.255.255.0
A little explanation about what these options do:
- crypto isakmp client configuration group [name]
- The name must match the group name that the client uses when it connects. This is how the server decides which configuration to send to the client.
- For some reason the client needs to be told what key to use, even though it's already been entered by the user, and the client knows it because it wouldn't be able to get this far in the negotiation without it!
- Tells the client which DNS server to use, for resolving local (private) hostnames, or resolving inside the split horizon. You can specify a second DNS server after the primary one. You probably only need this if you're running a Windows domain, in which case it should point to the domain controller, or if you have split horizon DNS.
- Tells the client which WINS server to use, for resolving local SMB server names. Again, you probably only need this if you're running a Windows domain, in which case it should also point to the domain controller.
- Tells the server which local pool (not DHCP pool) to assign the client's address from. You can specify any name here, even a pool that doesn't exist, but clients won't be able to connect unless the pool name is a valid local pool.
- This ACL, which we defined earlier, is used to tell the clients which subnets are reachable through the connection (split tunnel mode). If no acl statement is used, the tunnel is not split, and a default route is set through the VPN tunnel instead.
- Defines the network mask that the client will apply to its client interface, in combination with the IP address assigned from the pool.
Next, we create an ISAKMP profile on the server which tells the server to assign IP addresses automatically, and which virtual template to use when creating the virtual-access interfaces for the server side of the tunnel. We haven't defined the virtual template yet, but we will in a second.
crypto isakmp profile ewb_isakmp_profile match identity group EWB isakmp authorization list sdm_vpn_group_ml_4 client configuration address respond virtual-template 1
When a client connects using the group name
EWB, it will check for network authorization using the AAA list name
default if that list doesn't exist), respond to IP address requests from the client (using the pool defined in the client configuration above), and create a local virtual-access interface based on virtual template number 1.
You should use the same group name that you used for the client configuration above, instead of EWB, unless you're EWB of course.
Now we define the level of encryption used for data communications with hosts on the internal network, as opposed to securing the negotiation process. We start by defining a transform set which uses 256-bit AES encryption, the SHA hash algorithm and LZS compression for data packets:
crypto ipsec transform-set ewb_encryption esp-aes 256 esp-sha-hmac comp-lzs
Then we create an IPsec profile that links these settings to the ISAKMP profile that we defined above:
crypto ipsec profile ewb_ipsec_profile set transform-set ewb_encryption set isakmp-profile ewb_isakmp_profile
Now we define the template for the virtual interfaces, that we referenced above in the ISAKMP policy:
interface Virtual-Template1 type tunnel ip unnumbered Vlan1 zone-member security in-zone tunnel mode ipsec ipv4 tunnel protection ipsec profile ewb_ipsec_profile
ip unnumbered Vlan1 to set the IP address of the virtual-access interfaces to the address of the router on the local LAN (in this case it's a VLAN bridge), which allows you to ping the router using its internal IP address (192.168.1.1 in our case) when you're connected to the VPN, which is a useful connectivity test.
We place the virtual interfaces into the
in-zone (internal zone) which means that they have full access to the local network, which is not very secure, but simplifies things. We also specify that this interface accepts only traffic encrypted with IPsec and bound to the profile that we created earlier. I'm not sure why it needs to be bound in both directions, as the IPsec profile is connected to the ISAKMP profile which is connected to this virtual interface already.
That should be it for the server-side setup. To configure a client, install the VPN software you downloaded earlier, start it, create a new IPsec configuration, and enter the following details:
- The public IP address of the VPN server
- Group Name
- The same group name that you used on the server earlier
- Pre-Shared Key
- The same key that you entered on the server earlier
Now click on the Connect button, and after a few seconds the window should minimize to the system tray, and you should be connected to the VPN. You can check this by pinging the internal IP address of the router (e.g. 192.168.1.1) and if that works, the IP addresses of whatever internal servers you want to connect to.
If it doesn't work, use the Log menu to enable logging, try to connect again, and check the results on the Logging tab. You can also try enabling IPsec debugging on the router, in run mode (not configuration mode):
debug crypto engine packet debug crypto ipsec error debug crypto isakmp error debug crypto verbose terminal monitor
When the configuration works, write it to the router's non-volatile memory to ensure that you don't lose it when you next reboot the router:
And that's it!
Here are some random unsorted links to pages that I found useful while figuring out how to do this:
- Configuring a Cisco Router to Accept VPN Connections (even simpler example, without split tunnels)
- Configuring Internet Key Exchange for IPsec VPNs (good general overview of how Cisco's IPsec works)
- Cisco Easy VPN Remote configuration guide
- Cisco VPN client downloads
- Cisco ARP Commands
- Cisco ISAKMP command reference
- Configuring Zone Policy Firewalls