I realise that this is a rather specific problem, but hopefully the links I provide here will be useful for anyone wanting to access a PPTP VPN themselves.
I have to say that this is one of those entries more likely to be useful if you ever have this specific problem (eg, you can here via a search engine query for “argh pptp mppe errors argh argh argh”) and less for a casual reader. Apologies loyal fans!
The problem
I have a Linux server with no graphical environment. I wanted to connect it to my university’s VPN in order to be able to backup my stuff from the experimental server.
The solution
Required knowledge
Editing config files on a Linux server, some knowledge of routing, possibly some experience interpreting debugging output, etc. This isn’t the user-friendliest thing in the world, and if I want a desktop to connect to this VPN I’m going to use Network Manager myself.
Summary
I used the pptp-linux package on Ubuntu to connect to the VPN.
Detailed guide
Note that throughout the following I have left the Macquarie University settings in, in case others from that institution want to use them.
Software
I installed the pptp-linux package.
PPP settings
I created /etc/ppp/peers/onenet (where I use “onenet” in this guide, you could use anything you like, I’m using onenet because Macquarie University calls their network OneNet), which looks like:
# replace onenet with a meaningful name for you
remotename onenet
linkname onenet
ipparam onenet
# replace vpn.mq.edu.au with your network's VPN server
pty "pptp vpn.mq.edu.au --nolaunchpppd "
name username
usepeerdns
require-mppe
# you may not need the no-mppe40 setting, but OneNet does, and I will go into it more below
nomppe-40
noauth
# adopt defaults from the pptp-linux package
file /etc/ppp/options.pptp
Check man pppd
to understand the options given above.
Then in /etc/ppp/chap-secrets I have a line with my password:
"username" onenet "password"
Routing
At this point you can bring it up with pon onenet
(for actual use) or pon onenet nodetach
to verify it (nodetach means that pon doesn’t detach, and will dump all the PPP session info to your terminal).
However you may not be able to connect to anything yet. Because I am not instructing PPP to route all my Internet traffic via Macquarie University (I’d rather send it directly via my ISP!), I needed to specifically route some traffic.
I set up the route in /etc/ppp/ip-up.d/onenetroute (make sure file is executable), which runs whenever a PPP interface comes up:
#!/bin/sh
ONENET="onenet"
if [ "${PPP_IPPARAM}" = "$ONENET" ]; then
# replace 10.0.0.0/8 with the relevant network for your VPN, you may have to connect to it and nose around to find out what it is
/sbin/route add -net 10.0.0.0/8 dev ${IFNAME}
fi
If you happen to use 10.0.0.0/8 IP addresses on your home network, you may have to be a bit cannier about this (or renumber your own network, sadly). Roll on IPv6.
This file is close to mirrored with a file to bring that route back down, /etc/ppp/ip-down.d/onenetroute :
#!/bin/sh
ONENET="onenet"
if [ "${PPP_IPPARAM}" = "$ONENET" ]; then
/sbin/route del -net 10.0.0.0/8 dev ${IFNAME}
fi
Now when you run pon onenet
you should both get a connection to Macquarie University (or possibly your own VPN), and be able to connect to the machines on the VPN. Hooray!
PPTP debugging ew
I of course had more trouble than this guide suggests. The first thing to do if you aren’t connecting or aren’t connecting for long is to have a look at debug level output. The nodetach
argument to pon
is a nice way to do this, and you can get more verbose output with:
pon onenet debug dump logfd 2 nodetach
The PPTP client people have a great debugging resource page where you can look up errors.
While this page is genuinely helpful, it didn’t actually cover my exact error. What happened was this: the session couldn’t negotiate MPPE, which is the encryption for the connection. The webpage covers several ways that that can fail, but not the way mine did. Do I tried various combinations of setting the mppe-required
flag in /etc/ppp/peers/onenet with various errors, here are some samples, note all the ConfRej and ConfNak failures.
If I didn’t set any flag to do with MPPE, I’d get this (rcvd is control packages that the Macquarie server sent to me, sent is packets I sent to them):
rcvd [CCP ConfReq id=0x64 <mppe -H -M +S -L -D +C>]
sent [CCP ConfRej id=0x64 <mppe -H -M +S -L -D +C>]
If I set require-mppe
alone:
sent [CCP ConfReq id=0x1 <mppe +H -M +S +L -D -C>]
rcvd [CCP ConfNak id=0x1 <mppe +H -M +S -L -D +C>]
MPPE required but peer negotiation failed
If I set both require-mppe
and mppe-stateful
:
sent [CCP ConfReq id=0x1 <mppe +H -M +S +L -D -C>]
rcvd [CCP ConfNak id=0x1 <mppe +H -M +S -L -D +C>]
I looked at where the flags didn’t match, and at the meaning of the flags on the PPTP client debugging resource page. It was persistantly the H, L and C flags.
The -L flag that the server seems to prefer here turns off 40-bit encryption and so I found nomppe-40
in man pppd
, tried it, and suddenly we got a connection.
I didn’t seem to need to explicitly solve the clash between -H/+H (stateful/stateless) and -C/+C (no compression/compression, I think), which is part of why this was a pain. Why couldn’t they sort the L state out amongst themselves? But hooray! It worked.
Other resources used
- The PPTP routing guide, also thorough, where I took the ip-up.d and ip-down.d scripts from, except I took out everything to do with firewalling from them (since I don’t want to route traffic from any other network into the VPN, and my existing firewall rules cover the VPN interface too, I didn’t need them). Lots simpler!
- The Ubuntu VPN Client guide, where the section about manual configuration lays out most of the basics nicely, except that there’s no reason to use
nodetach
all the time, I just used it for debugging as above. (Note that as a wiki page, this may update pretty quickly.)
You shouldn’t need the route remove script, it should go away when the PPP device is torn down.