User Tools

Site Tools


oldwiki:vpn.client.vpnc

Table of Contents

VPNC

Some people, like students from Ghent University, Belgium, need to connect with a Cisco VPN server in order to connect to the internet. It's an ideal task for an OpenWrt router to make that connection and share it with all the connected PC's.

Performance Reports
 - On Asus WL-500G Deluxe (300Mhz) it maxes out at 30KB/s.
 - With a Asus WL-500gPremium (266Mhz) I got 250KB/s.
 - Tested WRT54GSv4 (200MHz) with Ethernet connection to Cisco Pix, 1des encryption, from NAT'd client behind WRT to ftp server behind Pix. 2.3 Mbps down and 1.9Mbps up.
 - WRT54GL v1.1 (200mhz) - scp test at 45Kbytes a second with  31% CPU usage 

Compatibility and stability

Be warned that the vpnc 0.3 series has issues with re-keying, which means that your connection may hang or be dropped. This is an issue that was fixed in version 0.4 and upwards. Depending upon your environment (concentrator model, software version), you may have significant issues with 0.3.

From a practical standpoint, using 0.4 and beyond means using Kamikaze - !not White Russian. Ok, you've been warned. ;-)

Installation

To install vpnc your OpenWrt router needs internet - obviously you first need to connect to another network than the net you want to access with vpnc. Configure your device to use the backports repository. See packages for instructions. Don't forget

ipkg update
after you added the backport repository to
/etc/ipkg.conf
.

Install vpnc (this will also automatically install the Dependant packages "libgpg-error", "libgcrypt" and "kmod-tun").

ipkg install vpnc

After the kmod-tun is installed a reboot is required.

reboot

Configuration

Create a configuration file:

vi /etc/vpnc.conf

And insert the parameters for your connection in there. These parameters are normally given by your sysadmin. If you only have a

.pfc
file for the Cisco VPN client there is a perl script
pcf2vpnc
to convert. Unfortunately the script is not included in vpnc backport package but in full vpnc packages and kvpnc, a KDE gui for vpnc. You can also download the pcf2vpnc source. If you run into group password problems you may be able to decrypt your password on the web if it does not make you uncomfortable.

Here is an example vpnc.conf:

IPSec gateway 157.193.46.4
IPSec ID ipsecclient
IPSec secret cisco123
Xauth username YOURUSERNAME
Xauth password YOURPASSWORD

The IP-address after IPSec gateway is the address of the VPN-server. The IPSec ID and IPSec secret must be given to you by your sysadmin, or try these values as defaults.

Change YOURUSERNAME and YOURPASSWORD to your username and password respectively. If you don't feel comfortable with having your password in a plain text file on your OpenWrt device, you can remove the Xauth password line, then VPNC will prompt you for the password every time you connect.

vpnc-script

VPNC automatically calls /etc/vpnc/vpnc-script to handle most of the maintenance operations like routing table and resolv.conf updates when a connection is established or broken. Unfortunately, the standard vpnc-script included with VPNC 0.3.3 won't run on OpenWRT's ash shell without a couple of changes. The modified script can be downloaded (updated version that works with the LEDs in White Russian RC6: attachment:vpnc-script) or you can apply the changes shown below.

The stock script uses a c-style "for" expression that we'll replace with an equivalent "while".

The first location is in the "do_connect" function (approx. line 222) and the part we care about looks like this:

for ((i = 0 ; i < CISCO_SPLIT_INC ; i++ )) ; do
    eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
    eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
    eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
    set_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
done

Change the first line and insert a line just above the "done" so you end up with this:

i=0 ; while [ "$i" -lt "$CISCO_SPLIT_INC" ] ; do
    eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
    eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
    eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
    set_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
    i=$(($i + 1))
done

A similar pair of changes are required in the do_disconnect function just below the last change.

for ((i = 0 ; i < CISCO_SPLIT_INC ; i++ )) ; do
    eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
    eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
    eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
    del_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
done

Change to:

i=0 ; while [ "$i" -lt "$CISCO_SPLIT_INC" ] ; do
    eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
    eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
    eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
    del_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
    i=$(($i + 1))
done

On "OpenWrt White Russian - With X-Wrt Extensions 0.9" I also had to change

ifconfig "$TUNDEV" inet "$INTERNAL_IP4_ADDRESS" $ifconfig_syntax_ptp "$INTERNAL_IP4_ADDRESS" netmask 255.255.255.255 mtu 1412 up 

to

ifconfig "$TUNDEV" "$INTERNAL_IP4_ADDRESS" $ifconfig_syntax_ptp "$INTERNAL_IP4_ADDRESS" netmask 255.255.255.255 mtu 1412 up 

in function do_ifconfig().

I also had to add

touch /etc/resolv.conf

to the startup-script from the next section, because it got lost after rebooting.. But be carefull with all this, I'm new to this… :-/

Start-up Script

This script can either be placed in the /etc/init.d directory if you'd like the VPN to come up automatically or another location if you want manual control over the starting of the VPN.

It is a good idea to create the /var/run/vpnc directory in the start-up script as this is where vpnc will attempt to store original versions of the files it changes.

For automatic start, place this in /etc/init.d/S75vpnc (on White Russian):

#!/bin/sh
mkdir -p -m777 /var/run/vpnc
vpnc /etc/vpnc/vpnc.conf

Another option (on Kamikaze) is to use the following in /etc/init.d/vpnc and softlink /etc/rc.d/S75vpnc to /etc/init.d/vpnc:

#!/bin/sh /etc/rc.common
START=75
STOP=10

start() {
        mkdir -p -m777 /var/run/vpnc
        vpnc /etc/vpnc/vpnc.conf
}

stop() {
        PID_F=/var/run/vpnc/pid
        if [ -f $PID_F ]; then
           PID=$(cat $PID_F)
           kill $PID
           while [ -d /proc/$PID ];
           do
                sleep 1
           done
        fi
}

To enable this on startup just type:

/etc/init.d/vpnc enable

and to start type:

/etc/init.d/vpnc start

The advantage of this script is that on shutdown it will wait for vpnc to finish (and the restart option will work better and won't say the address is already bound).

Testing

Save the script and execute it to start the connection.

/etc/init.d/S75vpnc

Sharing the VPN - Optional

An additional change to vpnc-script is required to share the VPN with the router's clients. These changes are already in the modified file here (updated version that works with the LEDs in White Russian RC6: attachment:vpnc-script).

Add these two functions to the /etc/vpnc-script (NOT necessary in vpnc 0.4 for Kamikaze):

start_vpn_nat() {
        iptables -A forwarding_rule -o tun0 -j ACCEPT
        iptables -A forwarding_rule -i tun0 -j ACCEPT
        iptables -t nat -A postrouting_rule -o tun0 -j MASQUERADE
}

stop_vpn_nat() {
        iptables -t nat -D postrouting_rule -o tun0 -j MASQUERADE
        iptables -D forwarding_rule -i tun0 -j ACCEPT
        iptables -D forwarding_rule -o tun0 -j ACCEPT
}

These functions should be called right after the connection is established and just before it is torn down. The "connect" and "disconnect" cases at the end of the vpnc-script should be modified to look like this if you want to share the vpn:

connect)
    do_connect
    start_vpn_nat
    ;;
disconnect)
    stop_vpn_nat
    do_disconnect
    ;;

The connection can be stopped by killing the vpnc process and then restarted:

kill `cat /var/run/vpnc/pid`
/etc/init.d/S75vpnc

Visual Indicator - Optional

With RC5 (and RC6), the Cisco LED that is on some Linksys units can be used as an up/down/error indicator. If you downloaded the modified vpnc-script (or the one for RC6 attachment:vpnc-script) then you already have these changes and can skip down to S99done below.

vpnc-script changes

Add these functions to the vpnc-script (for RC5 only):

# LED Codes
# 0x01 - DMZ
# 0x04 - Power flashing
# 0x08 - Cisco White
# 0x10 - Cisco Orange
#
pend=0x10
conn=0x08
vpn_led_pending() {
        ledstat=`cat /proc/sys/diag`
        ledstat=$(($ledstat | $pend))
        echo "$ledstat" >/proc/sys/diag
}

vpn_led_connected() {
        ledstat=`cat /proc/sys/diag`
        ledstat=$(($ledstat ^ $pend))
        ledstat=$(($ledstat | $conn))
        echo "$ledstat" >/proc/sys/diag
}

vpn_led_disconnected() {
        ledstat=`cat /proc/sys/diag`
        ledstat=$(($ledstat ^ $conn))
        echo "$ledstat" >/proc/sys/diag
}

And finally, add calls to these functions in the pre-init, connect, and disconnect cases at the bottom of the script:

pre-init)
    vpn_led_pending
    do_pre_init
    ;;
connect)
    do_connect
    start_vpn_nat
    vpn_led_connected
    ;;
disconnect)
    stop_vpn_nat
    do_disconnect
    vpn_led_disconnected
    ;;

S99done

At the end of the boot process, the S99done script is called and one of the things it does is turn off all the controllable LED indicators. We need to change it to only turn off the DMZ LED to indicate Linux is finished booting without changing the other indicators. You can make the changes below or download a modified copy.

The last two lines of the file are:

# set leds to normal state
echo "0x00" > /proc/sys/diag

Change to:

# set leds to normal state
# remove DMZ
ledstat=`cat /proc/sys/diag`
ledstat=$(($ledstat ^ 0x01))
echo "$ledstat" > /proc/sys/diag


CategoryHowTo

oldwiki/vpn.client.vpnc.txt · Last modified: 2011/02/27 19:31 (external edit)