VPN Follies Part 2 -- Linux 2.4, OpenSWAN, and WRT54G
Behind the "read more" link are my instructions and a sample configuration for terminating an IPSEC VPN tunnel with OpenSWAN on the LinkSys WRT54G from the previous Stupid WRT54G Tricks article. These instructions also apply to any Kernel 2.4.x Linux distro with OpenSWAN or FreeSWAN installed.
Swans, Racoon and other Critters
Before I dive into turning the $40 (after rebate) WRT54G into the equivalent of an $80 WRV54G, there is one thing you ought to know. These instructions will not work with any 2.6.x Kernel Linux build. They will only work with 2.4.x kernels.
I know this now, from painful and embarrassing experience.
The 2.4 kernels use FreeSwan or OpenSwan depending on the distro you are using. The "klips" kernel module performs IPSEC-related functions within the kernel, and the ipsec command is used to manage VPN connections and provide status. The pluto daemon handles IKE key exchanges.
The 2.6 kernels use the tools provided by the ipsec-tools package, which is borrowed from BSD land. The VPN-handling daemon is called racoon. VPN configuration instructions for a BSD-based system should also work for a Linux 2.6.x system and vice-versa.
You can imagine the frustration I experienced when I went poking through the (2.6) kernel source code, looking for the "klips" module -- trying to troubleshoot the baffling "KLIPS not in kernel" error messages that I kept getting when trying to run FreeSwan.
Got it? Good.
Using OpenSWAN to terminate a VPN
Step 1 -- Install the SWAN package
If you are using a WRT54G and followed the instructions in the previous article you already have OpenSWAN installed. If not, you will need to install the appropriate package on the Linux distribution you are using. Some Distro's will come with FreeSWAN and others will come with OpenSWAN (there are very few differences between the packages). If there is no pre-built package for the Linux you are using, you can also download, compile, and intstall the sources code from:
Step 2 -- Edit the configuration files
To terminate the simple Pre-Shared-Key IPSEC VPN from Part 1, I only had to edit 2 configuration files on the WRT54G. The files were: /etc/ipsec.secrets and /etc/ipsec.conf
I also had to configure the iptables firewall rules to make sure the packets were forwarded correctly, but more about that later.
ipsec.secrets was just a one-line file that contained the peer IP addresses and the Shared secret for the tunnel in the following format:
192.168.22.247 64.144.47.23 : PSK "testVPN"
ipsec.conf was the default file that came with the OpenSWAN package (follow the link for the complete file I used). Below are the changes I made to the file to define the new tunnel:
config setup
klipsdebug=none
plutodebug="control parsing"
interfaces=%defaultroute
conn TestVPN
authby=secret
left=192.168.22.247
leftsubnet=192.168.1.0/24
leftnexthop=%defaultroute
right=64.144.47.23
rightsubnet=192.168.50.50/32
rightnexthop=64.144.47.1
auto=start
The %defaultroute is a "magic" value that causes OpenSwan to use its "default route" interface (the one that faces your ISP) as the interface to terminate the "left" (local) side of the tunnel.
Another handy magic value is %any (not used in this example) which tells OpenSwan to accept connections from anywhere as the "right" (remote) side of the tunnel. You would use %any if you were setting up a "road warrior" VPN gateway (Example from http://www.freeswan.ca) and wanted to allow mobile users to connect to your VPN from any IP address.
Step 3 -- Configuring the iptables firewall
On the OpenWRT54G, the file /etc/init.d/S45firewall is the init script that sets up all the firewall and NAT rules for your router. I found that if I left the default rules in place, the VPN connection did not work. If I deleted the S45firewall file and rebooted (or otherwise cleared the iptables rules, the VPN connection would work, but hosts behind my router were unable to access the Internet.
The solution was to add some new rules allowing traffic to be forwarded through the new ipsec0 interface, and to prevent traffic to the far side of the VPN tunnel from being handled by the NAT rule.
The rule changes look like this:
### FORWARDING
### (connections routed through the router)
### ...
# allow
iptables -A FORWARD -i ipsec0 -o $LAN -j ACCEPT
##Uncomment this rule only if you want to allow unsolicetd traffic from the other side of the tunnel
#iptables -A FORWARD -i $LAN -o ipsec0 -j ACCEPT
### ...
### MASQ
###
### In order to prevent traffic to the far side of the VPN tunnel from being NATed, you need to
#
# Replace
# iptables -t nat -A PREROUTING -j prerouting_rule
# iptables -t nat -A POSTROUTING -j postrouting_rule
# iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE
#
# With
iptables -t nat -A PREROUTING -d ! 192.168.50.50/32 -j prerouting_rule
iptables -t nat -A POSTROUTING -d ! 192.168.50.50/32 -j postrouting_rule
iptables -t nat -A POSTROUTING -o $WAN -d ! 192.168.50.50/32 -j MASQUERADE
#The -d! 192.168.50.50/32 is the exception to the rule.
Step 4 -- Starting the daemons
I highly recommend using the init scripts to start and stop the ipsec and pluto daemons for you.
OpenWRT's OpenSwan package installs a file named /etc/init.d/S60ipsec that will automatically start OpenSwan when the router is rebooted. You can also use the command:
/etc/init.d/S60ipsec --start
to manually start the program. Other options are --stop, --restart, and --status