This guide is to help Linux users configure client access to a VPN gateway
managed by a Cisco3000 VPN Concentrator, when the VPN administrator has chosen
to deploy clients using a group password. It has been written to be useful in
actually getting the Linux client VPN software
vpnc set
up and interoperating with the Cisco3000 VPN server system.
The configuration details you'll need to figure out to get things working include:
- the IP address of the server's VPN gateway
- the VPN group name
- the VPN group password
The tricky part is the group password. Simply asking an existing user of the VPN client software what
group password they're using is impractical, because the password is stored in an encrypted form within
their configuration, so they will not usually be aware of what it is. This guide tries to explain how to
locate the required configuration files within an already-configured system (usually running a Microsoft
operating system), and how to recover the VPN group password from them.
Some reasons to use vpnc rather than the Cisco VPN client
The major advantage
vpnc has (as a
Free Software VPN client) over the proprietary
Cisco implementation is that you don't need to do anything special if you change your kernel.
This is because
vpnc runs in user-space, in contrast to the Cisco vpn implementation, which
depends on a proprietary binary-only kernel module. There is usually only extremely limited
community support is available for binary-only kernel modules.
Kernel modules, especially those that depend on binary-only object code
(i.e. code to which you do not have the source-code), tend to be difficult
to build in such a way that they load cleanly into the enterprise kernels
from Red Hat and SuSE without "tainting" the kernel. Tainted enterprise
kernels tend to be ineligible for support.
In general, tainted kernels tend to be viewed with suspicion, especially if they're
involved in bug reports to the Red Hat and SuSE developers. As you can imagine, clean
kernels are much more acceptable as starting points for an investigation of any kernel problem.
Get the source for vpnc
Get the source for the user-mode VPN client "vpnc" from here:
http://www.unix-ag.uni-kl.de/~massar/vpnc
At the time this article was written, the latest download was:
http://www.unix-ag.uni-kl.de/~massar/vpnc/vpnc-0.3.3.tar.gz
The latest development code is available in the Subversion repository:
http://svn.unix-ag.uni-kl.de/vpnc
For building vpnc, you'll also need version 1.1.90 or later of the
GNU Libgcrypt Cryptographic library:
http://www.gnu.org/directory/security/libgcrypt.html
ftp://ftp.gnupg.org/gcrypt/libgcrypt/
Libgcrypt also needs libgpg-error, which is in the ftp archive at:
ftp://ftp.gnupg.org/gcrypt/libgpg-error/
Build the software
Once the above
libgcrypt11 and
libgpg-error sources have been built,
you're ready to build
vpnc as follows.
wget http://www.unix-ag.uni-kl.de/~massar/vpnc/vpnc-0.3.3.tar.gz
tar zxvf vpnc-0.3.3.tar.gz
cd vpnc-0.3.3
make
For those lucky folks running Debian, vpnc is available as a pre-built
binary package, so you can save yourself quite some time by just using
the following. I also show the "dev" packages you can install, which are convenient
if you want to follow the latest development, and need to build
vpnc from source.
apt-get install libgcrypt11-dev libgpg-error-dev
apt-get install vpnc
cd /dev && mkdir net
cd /dev/net && mknod tun c 10 200
You also need to make sure your kernel has the tunneling option either built
in or as a module. Most commercial distributions supply the module, look for:
/lib/modules/`uname -r`/kernel/drivers/net/tun.o
If you don't find it, then when you're configuring your kernel, look in the
section
Universal TUN/TAP device driver support.
Usually, it's sufficient to just make sure that your kernel .config has:
CONFIG_TUN=m
This configuration turns on TUN support, which provides packet reception
and transmission for user space programs. It can be viewed as a simple
Point-to-Point or Ethernet device, which instead of receiving packets from a
physical media, receives them from a user space program and instead of
sending packets via physical media, writes them to the user space program.
If you have the kernel sources installed, you can read more about this in
/usr/src/linux/Documentation/networking/tuntap.txt
Configuration
At the time of this writing, the Cisco VPN client software needs
a steering file containing all of its configuration information.
The steering files are usually named according to the location of the
gateway where the VPN server is running.
In a Microsoft Windows installation, the steering files reside in the following
directory, and they have names ending with the ".pcf" suffix.
C:\Program Files\Cisco Systems\VPN Client\Profiles
When looking through the steering files, with a view to creating the
configuration file for "vpnc", you need to take note of the following
lines. Only the labels of the lines are shown here:
Host=
BackupServer=
GroupName=
enc_GroupPwd=
Username=
UserPassword=
Any other lines are irrelevant.
The only file that you need to edit to configure
vpnc is
/etc/vpnc.conf
The "vpnc" configuration file is much shorter than the Cisco VPN client's
steering files. You'll need lines as follows in your /etc/vpnc.conf file.
Note that capitalization matters in the
/etc/vpnc.conf file.
IKE DH Group dh2
IPSec gateway README_1
IPSec ID README_2
IPSec secret README_3
Xauth username README_4
Xauth password README_5
Interface name tun0
Application version Cisco Systems VPN Client 3.7.3 (A):Linux
The
IKE DH Group is the internet key exchange implementation to use.
Diffie-Hellman is an asymmetric cipher, chosen by setting this to
dh2.
Asymmetric ciphers are currently too slow to use for encrypting the vpn
traffic itself, so they are only used to share the key to use for the
symmetric cipher (usually DES) used to encrypt the vpn traffic.
The "vpnc" project implements around six or so key exchange mechanisms.
For
README_1, put whatever you noted down from either the "Host=" or the
"BackupServer=" fields of the .pcf file earlier.
For
README_2, put whatever you noted down from the "GroupName="
field of the .pcf file earlier. This is the name of the VPN group.
For
README_3, you need to decode the hex contents of the "enc_GroupPwd="
field you noted down from the .pcf file earlier, to retrieve the
"plaintext secret" corresponding to the contents of the "GroupName=" field.
If you want to do the password decoding job yourself, use "ltrace" on the
Cisco VPN client version 4.0.3.B-k9, as follows. First, you'll need to know
where to put the steering files, and what extension to give them. They go in the
following the directory and need to have names ending with the ".pcf" suffix.
/etc/CiscoSystemsVPNClient/Profiles
First make sure the steering file is in place and is readable:
ls -l /etc/CiscoSystemsVPNClient/Profiles/EXAMPLE.pcf
then run:
ltrace -i ./vpnclient connect EXAMPLE 2>&1 | fgrep 805ac57
Note: Don't include the '.pcf' extension, when giving the steering file name
to use to the Cisco vpnclient program.
See
below for info
on downloading the Cisco VPN client itself to use with this method,
as the specific version will be needed to match the ltrace.
The above method depends on a vulnerability in the Cisco VPN client
reported
to Cisco by Karl Gaissmaier, University of Ulm, Germany. In short,
anyone in possession of the Group Passwords will have the ability to either
hijack a connection from a valid user, or pose as a VPN head end for stealing
user names and passwords.
If you don't have "ltrace" installed, you can still use "strace":
strace -s 500 -o $HOME/secret/vpnclient.strace.out vpnclient connect EXAMPLE
although you'll need to search for the password string manually because
strace doesn't seem to provide a way of displaying the offsets. The "-s"
parameter is suggested to increase the displayed length of the contents of
the string buffers containing the password. The default is only 32.
If you're in a hurry, a web page provides a
utility to
do the job of decoding the "enc_GroupPwd=" group password field.
Obviously, don't connect to that utility web page from within the network you're
trying to connect to over VPN, as otherwise the site could log the generated
passwords as well as the network originating the decoding request, and put
two and two together. The
vpnc package also contains a script
pcf2vpnc
which does this automatically, given the steering file.
For
README_4, Xauth username, put your login username.
For
README_5, Xauth password, you could put your login password here, but it's really not recommended.
Any config line info that is missing should be prompted for when
you use
vpnc-script to connect, so it's best not to put your password into the
/etc/vpnc.conf
configuration file, and let
vpnc prompt you for it.
Start your VPN connection
To connect, simply issue, from the command line as root, the command:
vpnc-script
You do NOT have to set any environment variables, vpnc will do
that for itself. If you're using an earlier version of
vpnc, the
connection script may have the name
vpnc-connect instead.
Thats about it. A netstat -nr will show that your default route is now
via tun0 which will connect you through to the internal network.
To come back out to normal networking simply issue 'vpnc-disconnect' and
all will be returned to normal.
Unsolved puzzles
The INVALID_PAYLOAD_TYPE message
When connecting to some Cisco VPN servers,
vpnc may give the following error message:
/bin/vpnc: quick mode response rejected: INVALID_PAYLOAD_TYPE
check pfs setting
Connection dropping after 8 hours
When using vpnc, the connection will always be dropped after it has been
up for at most 8 hours, when rekeying occurs. This is because rekeying is
not yet supported in
vpnc, and Cisco's default rekey-intervall is 8 hours.
Usually this is not too inconvenient, but you may want to consider using
either GNU
screen or
TightVNC
if you want to make sure you don't loose any state if you are disconnected unexpectedly.
Firewall considerations
If you are running
vpnc from a machine with a
personal firewall configured
on its external interface (eth0 or ppp0), for example if you are running SuSE
9.0 with
SuSEfirewall2-3.1-206 configured for the external eth0 interface,
then in some situations incoming packets required for setting up the vpn tunnel
connection might get dropped.
As a workaround, I've found that using a second machine (running for example,
SuSE SLES-9 and
SuSEfirewall2-3.1-310.4) configured with two network interfaces,
one for the internal private network, and the second for connection to the
external untrusted network, and with the firewall configured to perform
"Masquerading", allows the machine on the private network to always
successfully connect over the vpn.
Enabling masquerading is bad for security -- please note that it is more secure
to communicate via proxies to the untrusted network than to use masquerading.
Such a configuration may be simple to use, but remember that once the vpn tunnel
is enabled, then unless you have the correct iptables setup (see next section),
your private network could become part of the network on the far side of the
vpn. Also, the use of masquerading in any case is not recommended because it
involves enabling routing on your firewall.
On Debian, the package "guarddog" allows the firewall configuration to be
customized to include the ISAKMP and ESP protocols, which "vpnc" needs.
The way to enable communication over these protocols is to add a checkmark
in both of the following, for the "Internet" zone:
"Network" -> "ISAKMP - Internet security key management"
"Network" -> "ESP - Encapsulating Security Protocol"
If your internet connection is by means of a NAT router (i.e. your IP address
is not a fixed IP address, but one on which network address translation is being
done by a router in between you and the internet), then the port udp/4500 must
also be enabled in the guarddog firewall configuration, for "vpnc" to connect
successfully. The way to do this is to go into the "Advanced" settings and add
a "New Protocol", and enable this new protocol in the "Internet" zone.
iptables setup
On Linux, "vpnc" can be configured to achieve the same goal as the Cisco VPN
client (that is, to disable local LAN access while the VPN tunnel is active).
This explanation is thanks to Alessandro Suardi and Maurice Massar, and took
place on the vpnc-devel mailing list.
Adding the following section to the end of your
vpnc-script
is sufficient to block access to and from the LAN, while still allowing traffic
via the VPN tunnel. If you are already using some iptables rules, remember to
save them using "iptables-save" before running this script, so that you can use
"iptables-restore" within your "vpnc-disconnect" to restore access to
your LAN. There are some drawbacks with "iptables-restore", see for example:
http://www.faqs.org/docs/iptables/drawbackswithrestore.html
# Flush the previous rules
iptables -F
#
# INPUT chain:
# Allow ESP protocol
# Allow UDP on isakmp, NAT, NAT-T
# Allow traffic from the loopback device and the VPN tunnel
# Reject everything else with "filtered" diagnostic messages
#
iptables -A INPUT -j ACCEPT -s $VPNGATEWAY -p esp
iptables -A INPUT -j ACCEPT -s $VPNGATEWAY -p udp -m multiport --sports isakmp,4500,10000
iptables -A INPUT -j ACCEPT -i lo
iptables -A INPUT -j ACCEPT -i $TUNDEV
# Enable LOG if you need to for debugging purposes:
#iptables -A INPUT -j LOG
iptables -A INPUT -j REJECT --reject-with icmp-admin-prohibited
#
# FORWARD chain: disable IP forwarding
#
iptables -A FORWARD -j REJECT --reject-with icmp-admin-prohibited
#
# OUTPUT chain:
# See the INPUT chain settings above, and adjust the parameters
# appropriately to allow traffic in the opposite direction.
#
iptables -A OUTPUT -j ACCEPT -d $VPNGATEWAY -p esp
iptables -A OUTPUT -j ACCEPT -d $VPNGATEWAY -p udp -m multiport --dports isakmp,4500,10000
iptables -A OUTPUT -j ACCEPT -o lo
iptables -A OUTPUT -j ACCEPT -o $TUNDEV
iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited
TCP window scaling considerations
If you prefer to use your own DSL link directly to connect to resources on the
internet, rather than going via your organization's http proxies when you are
connected using vpnc, you may find that the TCP window scaling feature of the
Linux 2.6.7 and later kernels can interfere with such direct connections.
You can disable the new TCP window scaling feature by doing (as root):
echo "0" > /proc/sys/net/ipv4/tcp_window_scaling
echo "0" > /proc/sys/net/ipv4/tcp_moderate_rcvbuf
If you prefer to make this change permanent, you can use the sysctl utility:
sysctl -w net.ipv4.tcp_window_scaling=0
sysctl -w net.ipv4.tcp_moderate_rcvbuf=0
or edit the file /etc/sysctl.conf and add the following:
net.ipv4.tcp_window_scaling=0
net.ipv4.tcp_moderate_rcvbuf=0
The recent 2.6.7 kernel's TCP changes are only exposing a pre-existing problem
with a large number of poor/broken firewall implementations. These are clueless
firewall implementations that strip or alter the TCP options. When the options
are modified, TCP gets busted. The reason this matters now, is that when the
linux kernel proposes a new window scaling, it quite sensibly expects that the
other side will receive the same initial SYN request that it actually sent.
If there is a clueless firewall in the middle that corrupts or strips it, then
the window we send is not correctly scaled, and the result is that the other
side thinks that there is not really enough space to send.
The current proliferation of these clueless firewall implementations resulted
in a proposal on the linux kernel mailing list by Stephen Hemminger, where
he proposes a patch that will avoid sending window scaling that is big enough
to break in these cases unless the tcp_rmem has already been increased.
The aim is to keep the default configuration from blowing in a corrupt world.
For more details on the lively ensuing discussion of Stephen's patch, search
for the following string in the archive pages listed below:
"[PATCH] fix tcp_default_win_scale."
See the
Jul 1 to Jul 7, 2004 lkml archives.
Also the
Jul 8 to Jul 15, 2004 lkml archives
There's also an entertaining explanation from James Janssen, a Gentoo user,
here.
Graphical User Interfaces
There is a GUI for
vpnc for the K desktop environment (KDE)
http://home.gna.org/kvpnc/
vpnc on 64-bit platform: x86_64
Zach Brown
describes the issues
he found with vpnc on the x86_64 platform. He also provides a patch there that may help get you going.
The Cisco VPN client binaries
The specific version of the Cisco VPN client to use for retrieving the Group
Password from the encrypted "enc_GroupPwd" field, has the name
vpnclient-linux-4.0.3.B-k9.tar.gz
and can be downloaded from many places, e.g.
http://www.uni-konstanz.de/RZ/wlan/ipsec/software/cisco-vpnclient-4.0.3/vpnclient-linux-4.0.3.B-k9.tar.gz
This version also works with 2.6 linux kernel.
Alternatives to vpnc
A couple of other ways of setting up VPN tunnels are good to know about,
e.g.
ipsec-tools and the VPN support recently added to
OpenSSH.
ipsec-tools
http://ipsec-tools.sourceforge.net/
http://www.netbsd.org/Documentation/network/ipsec/rasvpn.html
On Wed Apr 6 2005, Joerg Mayer wrote:
http://lists.unix-ag.uni-kl.de/pipermail/vpnc-devel/2005-April/000587.html
If you are using Linux and already have SuSE 9.3, then your choice shouldn't
be vpnc, it should be ipsec-tools that come with SuSE 9.3
The ipsec-tools and the kernel ipsec implementation can do certificates and
hybrid stuff.
When I compared vpnc to ipsec-tools (just looking over what each project says
in their documentation), then ipsec-tools is the thing many people want to use.
I remember that there are one or two things that vpnc does better, but
ipsec-tools have certificates and also supports generating of a new sa after
the lifetime of the old sa has expired.
While I really like the idea of vpnc, it looks like ipsec-tools is not only
catching up but in most cases already surpasses vpnc - with the big
disadvantage that ipsec-tools are tied to only a few platforms. It also
looks like ipsec-tools is being actively developed with more than just one
patch per month or so as is currently the case with vpnc.
--
PeterKnaggs - 06 Feb 2006
to top