5kits zhao

Openvpn

OpenVPN Termination on OpenWrt

This page contains an overview on how to configure an OpenVPN client on a Linksys WRT54GS running OpenWrt.

Introductory Information

To secure the wireless network link between the WRT client and the remote access point, I chose to setup a VPN tunnel, and route all traffic from the network behind the WRT through this VPN tunnel.

OpenVPN was chosen, due to the availability of packages for OpenWrt and numerous other platforms, the security it provides, and the flexibilty and ease of configuration.

I chose to configure my linux router at the remote end as the OpenVPN server, with the OpenVPN client being the WRT.

Note that I’m using pre-shared keys, rather than SSL/TLS, as it simplifies the configuration.

As the subnet behind the WRT is houwels.sgnet.wafreenet, and it is connecting to the SGNet router, I prefix all OpenVPN configuration files with the name of the subnet, namely houwels.

Network Addressing
The following network addresses are used below:

10.60.68.16/29 client subnet behind WRT
10.60.68.17 LAN interface of WRT
10.60.68.18-22 client PCs behind WRT
10.60.68.232/30 client link between SGNet and WRT
10.60.68.233 virtual interface on SGNet router
10.60.68.234 WLAN interface of WRT
10.60.68.236/30 VPN link between SGNet and WRT
10.60.68.237 VPN end-point on SGNet router
10.60.68.238 VPN end-point on WRT

Substitute your own network addresses when implementing your own configuration.

Install & Configure OpenVPN Server
Install OpenVPN Server
I’m using an OpenVPN 2.0.5 server on a RedHat 9 linux box. Refer to the OpenVPN documentation for information on installing OpenVPN on RedHat and other linux distributions.

Create Static Key
On the linux router, create a pre-shared static key for the VPN link:

  openvpn --genkey --secret /etc/openvpn/houwels_static.key

Create Configuration File
The OpenVPN configuration file (/etc/openvpn/houwels_openvpn.conf) on the SGNet linux router is similar to this:

  # Use a dynamic tun device.
  dev tun0

  # 10.60.68.237 is our local VPN endpoint (SGNet).
  # 10.60.68.238 is our remote VPN endpoint (WRT).
  ifconfig 10.60.68.237 10.60.68.238

  # up script will establish routes once the VPN is alive.
  up ./houwels.up

  # pre-shared static key
  secret houwels_static.key

  # OpenVPN uses UDP port 1194 by default.
  # Each OpenVPN tunnel must use a different port number.
  port 1194

  # Downgrade UID and GID to "nobody" after initialization for extra security.
  user nobody
  group nobody

  # use LZO compression.
  comp-lzo

  # More reliable detection when a system loses its connection.  
  ping 15
  ping-restart 45
  ping-timer-rem
  persist-tun
  persist-key

  # Silence  the output of replay warnings, which are a common false
  # alarm on WiFi networks.  This option preserves the  security  of
  # the replay protection code without the verbosity associated with
  # warnings about duplicate packets.
  mute-replay-warnings

  # Verbosity level.
  # 0 = quiet, 1 = mostly quiet, 3 = medium output, 9 = verbose 
  verb 3

Create Routing Script
OpenVPN can run a script when the VPN link is established. This is useful, as it allows you to add a route through the VPN tunnel.

On the SGNet router, I use the following script (/etc/openvpn/houwels.up) to add a route to the subnet behind the WRT (10.60.68.16/29):

  #!/bin/bash

  # add route to houwels network via VPN end-point of WRT
  route add -net 10.60.68.16 netmask 255.255.255.248 gw $5

Note that the houwels.up script must be executable:

chmod 755 /etc/openvpn/houwels.up

Start OpenVPN
Once configured, start OpenVPN. On my RedHat linux router, it’s simply a matter of running

  /etc/init.d/openvpn start

and OpenVPN will parse each .conf file it finds in /etc/openvpn/, and start an OpenVPN daemon for each.

Install Components on OpenWrt
Install IPK Packages
Firstly, install the OpenVPN package and dependancies.

ipkg install openvpn

and ipkg will automatically install all required dependancies, including kmod-tun, liblzo, libopenssl, and of course the openvpn package.

The liblzo package provides libraries to support lzo compression for OpenVPN, the libssl package provides libraries for SSL encryption used by OpenVPN, and the kmod-tun package provides the TUN/TAP device driver kernel module required by OpenVPN.

Create Configuration Files
Firstly, create a directory for all OpenVPN configuration files on the WRT:

  mkdir /etc/openvpn

Copy the previously created shared static key (houwels_static.key) from the linux router into /etc/openvpn on the WRT.

Create the configuration file for the OpenVPN link, /etc/openvpn/houwels_openvpn.conf:

  # Use a dynamic tun device.
  dev tun

  # OpenVPN server is the SGNet router.
  remote 10.60.68.233

  # 10.60.68.238 is our local VPN endpoint (WRT).
  # 10.60.68.237 is our remote VPN endpoint (SGNet).
  ifconfig 10.60.68.238 10.60.68.237

  # up script will establish routes once the VPN is alive.
  up /etc/openvpn/houwels.up

  # pre-shared static key
  secret /etc/openvpn/houwels_static.key

  # OpenVPN uses UDP port 1194 by default.
  # Each OpenVPN tunnel must use a different port number.
  port 1194  

  # Downgrade UID and GID to "nobody" after initialization for extra security.
  user nobody

  # use LZO compression.
  comp-lzo

  # More reliable detection when a system loses its connection.
  ping 15
  ping-restart 45
  ping-timer-rem
  persist-tun
  persist-key

  # Verbosity level.
  # 0 = quiet, 1 = mostly quiet, 3 = medium output, 9 = verbose
  verb 3

Create a script /etc/openvpn/houwels.up to establish a default route through the VPN once it is active:

  #!/bin/ash

  # add default route through VPN tunnel
  route add -net 0.0.0.0 netmask 0.0.0.0 gw $5

Once again, the houwels.up script must be executable:

chmod 755 /etc/openvpn/houwels.up

Using OpenVPN on OpenWrt
Start OpenVPN
Before OpenVPN can be started, the tun device driver needs to be loaded:

  insmod tun

Note that this module will be automatically loaded by OpenWrt during a reboot, as installation of the OpenVPN ipkg has alreadycreated /etc/modules.d/20-tun.

Now manually start OpenVPN using:

  openvpn --daemon --config /etc/openvpn/houwels_openvpn.conf

Test the VPN by trying to ping the remote end-point of the VPN tunnel.
If it’s not working, increase the verbosity level in the configuration file, restart OpenVPN, and monitor the syslog to see why it might be failing to connect (use logread on OpenWrt, and monitor /var/log/messages on the linux router).

Configure OpenVPN to Auto-Start
To get OpenVPN to start each time the WRT is rebooted, create /etc/init.d/S65openvpn with the following contents:

  #!/bin/sh

  # start the VPN
  openvpn --daemon --config /etc/openvpn/houwels_openvpn.conf --ifconfig-nowarn

and make the script executable:

  chmod 755 /etc/init.d/S65openvpn

Completing Configuration
Firewall Script
Note that you’ll need to modify the firewall script on the WRT to allow for the VPN tunnel.
I modified the firewall to only allow traffic through the VPN tunnel, and block all other non-VPN-ed traffic.

Performance Testing
Network Architecture
This WRT is connecting to an 802.11b Minitar MNWAPB access point, and hence is restricted to 802.11b 11Mbps speeds.

The throughput was measured by using wget to retrieve a 3MB file over the wireless link.

Initial tests were performed during setup, when the WRT was physically located close to the Minitar access point, so the WRT was associated to the Minitar with a link rate of 11Mbps. The tests were repeated once the WRT was installed at the client site, with similar results.

Throughput Without VPN
Throughput over the wireless link between the WRT and the Minitar was tested at approximately 600 kbytes/sec (ie, typical for an 802.11b wireless link).

Throughput With VPN
Once the VPN tunnel was established, and all traffic routed through it, the tests were repeated. Throughput dropped to approximately 300 kbytes/sec.

The major cause of this slow-down is the CPU in the WRT, as it needs to encrypt and decrypt all the traffic that is passing through the VPN tunnel. This can be observed by monitoring the CPU usage on the WRT while transferring large amounts of traffic through the VPN tunnel – the OpenVPN process consumes 99% of the CPU during this time.

The slow-down caused by the VPN tunnel is acceptable in the situation I’m using the WRT. If this isn’t the case, the throughput of the VPN tunnel can be increased by moving the VPN termination from the WRT onto a faster device (ie, a linux router) behind the WRT.

References

http://martybugs.net/wireless/openwrt/openvpn.cgi

Leave a Reply