Quick Start Guide to Debian PPTP Clients

This document describes setting up a functional PPTP client with MPPE encryption
enabled. While it does focus on getting things going with Debian Linux, some
information may be useful for individuals trying to patch things together using
other Linux-based systems.

*BSD users are, unfortunately, screwed.

At this point I’m no longer actively maintaining this page. If you find errors,
please let me know and I’ll try to correct them. However, I now use vpnc to
connect to the local VPN systems; since PPTP is a bit more difficult to set
up, I went that route. For details on setting up vpnc to work with your
favorite Cisco VPN Concentrator, look here.

1. Introduction

2. PPTP basics

3. Debian Installation

1. Introduction

Recently my employer deployed a campus-wide 802.11b network, with connectivity
in most buildings, common areas, and a few popular eating holes. Unfortunately,
the powers that be require some sort of authenticated VPN system to access a
working router - either Cisco’s VPNclient (which is closed-source, proprietary,
X86-specific, and buggy) or PPTP (which is a Micro$oft protocol, has
questionable crypto, and is proprietary). Well, PPTP has an open-source
implementation for Linux (which is 2.4-specific), so that’s the way to go.
Since I use Debian, I built some binary packages and made everything work
nicely. Since others at work also have Debian laptops, this little guide was

2. PPTP Basics

2.1 Overview

PPTP (short for Point-to-Point Tunneling Protocol) is an increasingly common
way of creating a VPN (Virtual Private Network) connection between two hosts,
such as an employee’s laptop/home computer and a server deep in his/her
employer’s network. An authentication connection between client and server is
created over the existing default network connection. The PPTP client turns
this network connection into a virtual network interface; any packets sent over
the virtual interface are encrypted and sent to the endpoint machine.

The VPN negotiation and authentication occurs over a TCP connection to the
server. The protocol is basically CHAPv2 (aka MS-CHAP), just as is used to set
up a PPP link. Actual packet data goes between client and server as (optionally
encrypted) GRE/IP packets. Under Linux (and probably FreeBSD and/or NetBSD)
pptp is used to set up and maintain the connection, but the
kernel-level interaction is handled by the PPP subsystem. Authentication is
done via pppd (and can be automated using Debian’s usual PPP
mechanisms), the network interface created will be a PPP device (eg,
ppp0) - as far as the kernel’s concerned it’s just a PPP link
that’s going over a socket connection (set up by pptp) rather than
out a serial port device.

2.2 MPPE Encryption

Most PPTP servers will want the client to support MPPE, a sort of encryption
(of dubious strength). That provides the “P” in “VPN”. :-)

To do MPPE (either 40-bit or 128-bit, or the stateless versions) you need both
a kernel patch (to decrypt PPP frames as they come in over the PPTP link) and
a patch to pppd (to negotiate the type of MPPE encryption and set
up the connection appropriately).

There are currently two different implementations of MPPE for Linux. Both
provide pppd patches and kernel patches, but they aren’t
compatible - the pppd and kernel patches you use must come from
the same site.

Currently Debian’s pppd (well, the version in unstable, and
probably the version that will be released with Sarge - the current testing)
provides MPPE encryption (and MPPC compression, see
below). Obviously, the trick is finding the right kernel
patch to match it. :-) Appropriate kernel patches, for both Linux 2.4 and 2.6,
can be found at the polbox.com
site. They work - I’m using them to type this now, in fact.

2.3 Compression (MPPC)

Along with MPPE there’s one other popular PPTP protocol - MPPC. It provides
a pretty basic sort of compression over PPP, usable by PPTP. Aside from that
(and that the polbox.com site
has patches to support it) I know nothing about this.

2.4 Links

Obviously, Debian users will be most interested in the
polbox.com site; the patches
from polbox.com have already found their way into pppd‘s upstream
CVS. However, that
author only provides implementations for Linux. FreeBSD (and maybe NetBSD)
users may be more interested in the
SourceForge site. It’s
another set of patches (MPPE support only, though - no MPPC), but they do
provide some notes for the BSDs.

The observant Debian user may have noticed a kernel-patch-mppe
package. This patch comes from the SourceForge site and will not work with
the pppd in unstable/testing. Mildly frustrating…

Both sets of patches should apply fairly cleanly (though the pppd
patch from SourceForge may require a bit of tweaking). Each site has all the
basic instructions necessary to make things work, should you feel like adding
MPPE support by hand. The rest of this document will focus on getting prebuilt
packages to work quickly.

3. Debian Installation

3.1 Necessary Packages

So you’re using Debian. Congratulations. The good news is, PPTP has already
made its way into the core distribution. The bad news is you’ll probably want
to be running at least “testing” (aka sarge, as of this writing) and preferably
“unstable” (aka sid). Testing and unstable have the latest upstream version of
the pptp-linux package, as well as a pppd package
with built-in MPPE (and MPPC) support. I’ve also made pre-built kernel
packages to provide MPPE support in Linux 2.4.24. Feel free to add my APT
archive to your sources.list:

deb http://www.fmepnet.org/debian/ main main
deb-src http://www.fmepnet.org/debian/ main main

If you want basic PPTP client support with MPPE encryption, get these packages:

apt-get update
apt-get install pptp-linux ppp kernel-image-2.4.24-1-686+mppe

If you intend to build your own MPPE-enabled kernel you’ll also want
kernel-source-2.4.24 and the patches from

The kernel-image-2.4.24-1-686+mppe package on my site is built
using the config from kernel-image-2.4.24-1-686 in
unstable. The package version ends in “+mppe“ to differentiate
it from the upstream version.

3.2 Automating via PPP

All of Debian’s PPP config files live in /etc/ppp. From here on
in I’ll assume that you want to turn on MPPE encryption; if that’s not the case
you’ll need to strip the appropriate options out of my config file examples.
For demonstration purposes, I’ll give the config files I use to access
PAL (the Purdue Air Link),
the campus-wide wireless service at Purdue

The next few sections are a file-by-file description of what you need to change
to get this working quickly.

3.2.1 /etc/ppp/peers/PAL

This file defines the pppd options to use for a given service
provider. The name of the service provider is the filename - in this case,
PAL. You’ll want something along the lines of this:

pty "pptp --nolaunchpppd"
name <login>
remotename PPTP
file /etc/ppp/options.pptp
ipparam tunnel

For full descriptions of these options consult the pppd man page.
Naturally, is the IP address of your PPTP server (DNS
names can be used here, but DNS resolution when not yet authenticated can be
troublesome on PAL, so it’s best to avoid this hassle).
<login> should be changed to match your login credential on
the PPTP server.

Of course, the “file /etc/ppp/options.pptp“ line means we need an
options.pptp file, so let’s create that next…

3.2.2 /etc/ppp/options.pptp

This file gives a space-separated list of options to pppd for the
PPTP link. Assuming you’re using the
polbox.com patches you’ll want
something like this:

lock noauth nobsdcomp nodeflate require-mppe mppe-stateful

If you’re using the
SourceForge patches you’ll
probably want this instead, since some of the option syntax is different:

lock noauth nobsdcomp nodeflate mppe-40 mppe-128 mppe-stateless

Once again I’ll stress that you probably want to use the polbox.com patches
with Linux, since those have already made their way into pppd‘s
CVS repository.

For descriptions of these options consult the pppd man page.
These options will disable compression (usually a problem for PPTP servers) and
enables all forms of MPPE encryption. If you do not include the
mppe options pppd may fail to connect and will
probably leave the confusing log message of “Negotiated MPPE XX-bit
encryption.” That means that the server requires MPPE, pppd can
support MPPE, but that since you haven’t explicitly turned on MPPE support you
won’t get encryption (or a VPN tunnel, for that matter).

3.2.3 /etc/ppp/chap-secrets

This file contains credentials for all CHAP-authenticated PPP connections,
including PPTP connections. Here’s an example:

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
<login>        PPTP    <passwd>        *
PPTP        <login>    <passwd>        *

Obviously, replace <login> and <passwd>
with your login and password on your PPTP server. Both PPTP lines will usually
be necessary. If your chap-sercrets file needs to contain several
entries you’ll probably want to replace the *s with the actual
IP addresses of your PPTP and PPP servers. Consult the pppd man
page for more details.

3.2.4 /etc/ppp/ip-up.d/000netfix

This script isn’t strictly necessary. However, if you’re using a service like
Purdue’s wireless network that requires you to use a PPTP tunnel as your
default route a script like this is essential:


if route -n | grep -q ^; then
    route del default
    SUBNET=`route -n | grep ^10 | grep eth | awk '{print $1}'`
    DEVICE=`route -n | grep ^10 | grep eth | awk '{print $8}'`
    ROUTER=`echo $SUBNET | sed -e 's/\.0$/.1/'`
    route add -host gw $ROUTER dev $DEVICE
    route add default dev ppp0
    ifconfig ppp0 mtu 1400
    cat <<END > /etc/resolv.conf
search purdue.edu

If the PPTP tunnel (in this case we’ll assume it’s ppp0) is to
be the default route there must be a way to reach the PPTP server. Purdue’s
wireless connection will put you on a non-routed, private network that can
reach the PPTP server ( and nothing else. Once you
set up a PPTP tunnel as the default route your machine will try to send all
packets over the tunnel including the encapsulated IP packets bound for
the PPTP server
. This little script detects that Purdue’s PPTP server
is being used and makes certain (via the route add -host line)
that there’s a non-PPTP route to the server. In addition, this script sets up
proper nameservers (since after using PPTP with Purdue’s link you’ll wind up
having bogus DNSes on the inaccessible network).

This script should be owned by root (and grouped to root), mode 0755.

3.3 Starting the link

Assuming you’ve been following the examples closely thus far, you can now bring
up the PPTP tunnel by typing pon PAL at a root prompt. To bring
it down, use poff PAL. For the connection error logs, use the
plog command.

Unfortunately, because pppd uses several unusual extra programs to
bring up a PPTP tunnel you probably won’t be able to make this work with most
graphical connection managers (eg, kppp). If you manage to make
your favorite GUI PPP dialer start and stop a PPTP connection please drop me an
email and I’ll post a little blurb here.