How to setup VPN for mobile devices with PPTP Linux server

By , last updated July 4, 2017

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.


403 Forbidden when trying to update the Twitter app in a blocked region

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.


  • Home server connected to the internet, in which you’ll have full control over (root).
  • SSH access to your server.
  • High end mobile device (Android, iOS, others?).

I’ll be using Gentoo Linux with kernel 4.0.5, and HTC One M9 mobile device in my example.

Installing pptpd (remember, it’s insecure)

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.

Configuring pptpd

Open /etc/pptpd.conf and make sure these options are configured.

option /etc/ppp/options.pptpd

Open up the second configuration file /etc/ppp/options.pptpd.

Make sure these options are configured.

name pptpd

Adding users to pptpd.

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.

Configuring the firewall and kernel (iptables).

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.

## 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

# Forward packets from ppp interfaces
-A FORWARD -i ppp+ -j ACCEPT

This block must go under the *nat chain.

# MASQUERADE for internet

Kernel config

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).


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).

Kernel forwarding

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

Time of truth

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.


Be the first to comment.

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>