This is a quick and dirty guide to set up a PPTP VPN (Point-to-Point Tunneling Protocol) service on linux server, in which your high end mobile device can connect to.
Imagine you are traveling, and you try to connect to your usual services for your phone. For Android, it’s Google Play and for iOS it’s App Store. Imagine, those services are blocked where you currently are and you are in dire need to install some updates to your phone or install some apps to try out.
With Google Play, you can browse the market, but you can’t download anything. You’ll only get a 403 Forbidden HTTP
response when you try to download anything.
What you need to do, is to use VPN so you’ll appear to download apps from home (where you aren’t blocked from downloading).
This quick and dirty guide uses PPTP. It’s inherently insecure DO NOT ASSUME PPTP SECURE. Only use PPTP for either testing or nonsensitive data.
My original intention was to setup StrongSwan with IPSec/L2TP, but I got some problems and I had to get something working with stock Android VPN, hence PPTP.
Contents
root
).I’ll be using Gentoo Linux with kernel 4.0.5, and HTC One M9 mobile device in my example.
Log in to your server with SSH and open up the root terminal. From here I usually use screen to be able to use multiple terminals with one terminal.
Install pptpd
with this command.
# emerge -av net-dialup/pptpd
When the emerge is finished, continue with configuring the pptpd daemon.
Open /etc/pptpd.conf
and make sure these options are configured.
option /etc/ppp/options.pptpd logwtmp localip 10.0.0.150-199 remoteip 10.0.0.200-249
Open up the second configuration file /etc/ppp/options.pptpd
.
Make sure these options are configured.
name pptpd refuse-pap refuse-chap refuse-mschap require-mschap-v2 require-mppe-128 proxyarp lock nobsdcomp novj novjccomp nologfd
Users are listed in the file /etc/ppp/chap-secrets
. It’s a file with users and passwords in plain text. Did I mention PPTP is insecure?
For home use, this is enough. Our objective is to create a VPN service for personal / home use to get past geographic location blocks. Security is not a requirement.
The chap-secrets format is very simple.
<user> <server> <password> <ipadresses>
This is a sample username and passord (don’t use this, use something else).
user * secret *
This will allow the user user
connect from anywhere with the password secret
. Please do use other passwords. The command line utility pwgen
will help you with generating secure passwords.
To be able to route packets between the VPN subnet and Internet, there are some more steps to be taken. The firewall must allow forwarding and masquerading of packets for the ppp devices, and the kernel needs some options set too.
I always edit my iptables rules by the rule file /var/lib/iptables/rules-save
.
This first block goes under the *filter
chain.
*filter ## PPTP server # Accept all packets via ppp* interfaces (for example, ppp0) -A INPUT -i ppp+ -m state --state RELATED,ESTABLISHED -j ACCEPT -A OUTPUT -o ppp+ -j ACCEPT # Accept incoming connections to port 1723 (PPTP) -A INPUT -p tcp --dport 1723 -j ACCEPT # Accept GRE packets -A INPUT -p 47 -j ACCEPT -A OUTPUT -p 47 -j ACCEPT # Forward packets from ppp interfaces -A FORWARD -i ppp+ -j ACCEPT
This block must go under the *nat
chain.
*nat # MASQUERADE for internet -A POSTROUTING -o ppp+ -j MASQUERADE
To be able to use PPP with the PPTP protocol, the kernel must support it.
These options must be enabled (either built into the kernel or as in my case, built as a module).
CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=m CONFIG_PPPOL2TP=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m
Ok, you might not need all of them, but most of the might come in handy. It’s really easy to spend 2-3 hours debugging a connection failure when all that is missing is a kernel module.
After you’ve build the kernel (and the modules), restart your server OR if you’ve just enabled the modules, just use the modules after installing them (make modules_install
).
Finally, there is one thing that must be enabled, and that is to enable packet forwarding in the kernel.
This is a two-step process. One for making the change permanent, and one for making it effective immediately.
Edit /etc/sysctl.conf
and add this line: net.ipv4.ip_forward = 1
.
To make forwarding effective immediately, run this command:
# echo 1 > /proc/sys/net/ipv4/ip_forward
At this point everything should be working as expected when you start the pptpd
service with /etc/init.d/pptpd restart
.
Just remember to stop the service when you’re done testing.
If you want the insecure service to run at boot time, enable the pptpd service to start when the system starts with the rc-config
command. It’s not recommended by the way.
# rc-config add pptpd default
If you’re using Android 2.3 or older, you might run into problems with PPTP VPN due to a bug in the Android Kernel. Encryption was not compiled into the kernels up until Android 2.3.
The problem is very apparent in the server log with many messages like these.
pppd[9645]: Protocol-Reject for unsupported protocol 0x8b pppd[9645]: Protocol-Reject for unsupported protocol 0x102c pppd[9645]: Protocol-Reject for unsupported protocol 0x4031 pppd[9645]: Protocol-Reject for unsupported protocol 0x5235 pppd[9645]: Protocol-Reject for unsupported protocol 0xf8b2 pppd[9645]: Protocol-Reject for unsupported protocol 0x6e5e pppd[9645]: Protocol-Reject for unsupported protocol 0x87
To get PPTP VPN working with Android 2.3 or older, you must disable encryption… And that sort of defeats the purpose with VPN.
However, if you need an other IP with another geographic location and you could care less about the data being sniffed or analyzed, go ahead with no encryption.
And in general, assume PPTP with encryption is not safe.