I finally got my Opensolaris box hooked up to a Cisco VPN:
1. Get the tun/tap
driver from
Kazuyoshi. This driver is used for creating a using between the client and the Cisco VPN router.
2. Compile and install the driver:
pkg install sunstudioexpress
export CC=/opt/SunStudioExpress/bin/cc
./configure
make
make install
3. Download the
vpnc client. This program handels the vpn connection. I've used the version
0.5.1.4. Get gmake
pkg install SUNWgmake
5. Adjust installation paths (my personal preferences):
Makefile:
PREFIX=/opt/vpnc
ETCDIR=/opt/vpnc/etc
config.c (hardcoded locations):
Line 250: return "/opt/vpnc/etc/ssl/certs";
Line 270: return "/opt/vpnc/etc/vpnc-script";
Line 275: return "/var/run/vpnc.pid";
Line 541: ... : /opt/vpnc/etc/", ...
Line 760: ... "/opt/vpnc/etc/default.conf" ...
Line 761: ... "/opt/vpnc/etc/vpnc.conf" ...
gmake
gmake install
6. Convert the pcf file into vpnc format using
/opt/vpnc/pcf2vpnc. Store the file in /opt/vpnc/etc
7. Now comes the tricky part. Create the
/opt/vpnc/etc/vpnc-script -script. The script opens the connection and sets up the appropriate routing.
My target was to just have a couple of connections go through the tunnel instead of all.
Attention! If you want to have a default route set into the tunnel, be sure to add some direct routes to your vpn gateway before the default route points to the tunnel. Otherwise the vpn gateway will become unreachable and the tunnel goes down. Your remote gateway can be found in your conf file ("IPSec gateway" line).
Depending on what you want to achieve, you have to configure your DNS servers in /etc/resolv.conf manually.
Here is my sample /opt/vpnc/etc/vpnc-script :
#!/bin/sh
#* reason -- why this script was called, one of: pre-init connect disconnect
#* VPNGATEWAY -- vpn gateway address (always present)
#* TUNDEV -- tunnel device (always present)
#* INTERNAL_IP4_ADDRESS -- address (always present)
#* INTERNAL_IP4_NETMASK -- netmask (often unset)
#* INTERNAL_IP4_DNS -- list of dns serverss
#* INTERNAL_IP4_NBNS -- list of wins servers
#* CISCO_DEF_DOMAIN -- default domain name
#* CISCO_BANNER -- banner from server
#* CISCO_SPLIT_INC -- number of networks in split-network-list
#* CISCO_SPLIT_INC_%d_ADDR -- network address
#* CISCO_SPLIT_INC_%d_MASK -- subnet mask (for example: 255.255.255.0)
#* CISCO_SPLIT_INC_%d_MASKLEN -- subnet masklen (for example: 24)
#* CISCO_SPLIT_INC_%d_PROTOCOL -- protocol (often just 0)
#* CISCO_SPLIT_INC_%d_SPORT -- source port (often just 0)
#* CISCO_SPLIT_INC_%d_DPORT -- destination port (often just 0)
# =========== script (variable) setup ====================================
PATH=/sbin:/usr/sbin:$PATH
FULL_SCRIPTNAME=/usr/local/sbin/vpnc
SCRIPTNAME=`basename $FULL_SCRIPTNAME`
# =========== tunnel interface handling ====================================
do_ifconfig() {
ifconfig "$TUNDEV" inet "$INTERNAL_IP4_ADDRESS" "$INTERNAL_IP4_ADDRESS" netmask 255.255.255.255 mtu 1412 up
}
# =========== route handling ====================================
get_default_gw() {
# isn't -n supposed to give --numeric output?
# apperently not...
# Get rid of lines containing IPv6 addresses (':')
netstat -r -n | sed 's/default/0.0.0.0/' | sed 's/^.*:.*$//' | grep '^0.0.0.0' | awk '{print $2}'
}
do_pre_init() {
echo "do_pre_init"
}
do_connect() {
if [ -n "$CISCO_BANNER" ]; then
echo "Connect Banner:"
echo "$CISCO_BANNER" | while read LINE ; do echo "|" "$LINE" ; done
echo
fi
do_ifconfig
if [ -n "$CISCO_SPLIT_INC" ]; then
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}"
i=`expr $i + 1`
done
fi
# Hosts 1&2 & 3
add_host_route "xx.xx.xx.xx"
add_host_route "xx.xx.xx.xy"
add_host_route "xx.xx.xx.xz"
for i in $INTERNAL_IP4_DNS ; do
add_host_route "$i"
done
}
do_disconnect() {
if [ -n "$CISCO_SPLIT_INC" ]; then
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}"
i=`expr $i + 1`
done
fi
# Delete all routes again
del_host_route "xx.xx.xx.xx"
del_host_route "xx.xx.xx.xy"
del_host_route "xx.xx.xx.xy"
for i in $INTERNAL_IP4_DNS ; do
del_host_route "$i"
done
}
add_host_route() {
HOST="$1"
route add "$HOST" "$INTERNAL_IP4_ADDRESS" -interface
}
del_host_route() {
HOST="$1"
route delete "$HOST" "$INTERNAL_IP4_ADDRESS" -interface
}
#### Main
if [ -z "$reason" ]; then
echo "this script must be called from vpnc" 1>&2
exit 1
fi
case "$reason" in
pre-init)
do_pre_init
;;
connect)
do_connect
;;
disconnect)
do_disconnect
;;
*)
echo "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
exit 1
;;
esac
exit 0
8. Now you should be able to connect to your vpn:
/opt/vpnc/sbin/vpnc myvpn.conf
9.The output should look like this:
/usr/local/sbin/vpnc cia.conf
Enter password for tzhbomi5@bwpir.bluewin.ch:
do_pre_init
add host xx.xx.xx.xx: gateway zz.zz.zz.zz
add host xx.xx.xx.xy: gateway zz.zz.zz.zz
add host xx.xx.xx.xz: gateway zz.zz.zz.zz
VPNC started in background (pid: 3971)...
10. The interfaces look like this, where zz.zz.zz.zz is the IP Address that got assigned from the other side of the tunnel. The tun0 device was automatically created by vpnc·
ifconfig -a
lo0: flags=2001000849 mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
rge0: flags=201004843 mtu 1500 index 2
inet 192.168.1.35 netmask ffffff00 broadcast 192.168.1.255
ether 0:22:15:5e:61:2b
tun0: flags=10010008d1 mtu 1412 index 4
inet zz.zz.zz.zz --> zz.zz.zz.zz netmask ffffffff
ether 2:0:0:0:0:0