Linux · Raspberry Pi

Using a Point-to-Point Tunnelling Protocol, Virtual Private Network (PPTP VPN) client on a Raspberry Pi


Why use a VPN?

VPN or a Virtual Private Network is a common way of securing an Internet connection using encryption.

Basically a VPN sets a trusted, designated server on the Internet to act as a man in the middle. As a VPN client, all your web traffic gets encrypted and directed to this designated machine. It decrypts and then reroutes the traffic to its intended destination. This gives you a both benefits and disadvantages.

Having an encrypted connection between yourself and a trusted VPN server means your Internet traffic is mostly safe from snoopers. That could be anyone on the same Wi-Fi network as you, your ISP or even big-brother governments.

If you are behind a government or corporate firewall, the VPN could be used to reach blacklisted websites. As the firewall will only see that your traffic is directed to the designated VPN server.

A VPN also allows you to hide the point of origin of your Internet request from your destination. As the designated server intercepts and decrypts your Internet traffic before it resents it. This fools the destination to believe the Internet request came from the designated server and not from you.

If a website or service has region restrictions placed on it to allow only users from particular countries access. A VPN server hosted in a permitted country allows you to bypass this form of restriction.

The most obvious disadvantage in using a VPN server is that adding an extra layer of Internet bureaucracy slows down your overall Internet experience. The encryption requires more processing time and it consumes more bandwidth. Plus adding a man the middle means your Internet traffic isn’t going to be traversing across the Internet via the quickest possible route.

About this project

For this project I am going to carry out a VPN client connection on a Raspberry Pi without using any GUI tools. This could be used with a headless or server Raspbian Pi set-up. It should also work fine on a Ubuntu based Linux system.

Also this tutorial will use the most common VPN protocol PPTP, known as the Point-to-Point Tunnelling Protocol. Its encryption is not as secure or as safe as some other VPN options but it is the most supported of the protocols out there.

Software installs and updates

First in a Pi shell we need to update our repositories, our Pi operating system and install PPTP for Linux.

sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install -y pptp-linux

sudo apt-get install pptp-linux

Setup and configuration

The pptp-linux installation includes the very useful Perl script pptpsetup that is found at /usr/sbin/pptpsetup.

List the help options for pptpsetup.

pptpsetup --help

pptpsetup has 6 options to create a PPTP connection configuration.

pptpsetup
--create [tunnel name]
--server [vpn server]
--username [vpn server username]
--password [vpn server password]
--encrypt (optional)
--start (optional)

pptpsetup --help

Example usage of pptpsetp.

sudo pptpsetup --create examplela --server pptp-la.example.com --username exampleuser --password examplepassword --start

The --create option is the ‘tunnel’ name you wish to give your connection. It can not have spaces or weird characters and should be something that is descriptive of the VPN server it will connect to such as a geographical location.

--server Is the address of the VPN server to connect to.

--username Is your assigned user name used to authorise access to the VPN server.

--password Is the password required by the user name.

--encrypt Toggles encryption for all communication between your Pi and the VPN server. While this setting is optional, most VPN servers will not accept a connection unless encryption is in use.

--start Will connect to the VPN after creating your new connection configuration.

For the rest of this tutorial I will use my real world example of pptpsetup. Replace any references to my proxpnuk configuration with your own VPN server configuration.

sudo pptpsetup --create proxpnuk --server pptp-uk1.proxpn.com --username xxxx --password xxxx --encrypt --start

pptpsetup realworld

If you have a Connection termination but you are sure your server address, user name and password are correct, try using the --encrypt option.

pptpsetup creates a configuration file that gets placed in /etc/ppp/peers/ which is a superuser protected directory so you will need to run sudo to view its content.

sudo ls -l /etc/ppp/peers/
sudo cat /etc/ppp/peers/proxpnuk

cat proxpnuk

You can see your point-to-point protocol connection using ifconfig -s. It should be listed under ppp0.

ifconfig -s

pptpsetup can also be used to delete an existing configuration file.

sudo pptpsetup --delete [tunnel name]

pptpsetup delete

Usage

PPTP for Linux also installed two Bash scripts that are used to connect and disconnect to your PPTP VPN server. You can use the -h option to see the scripts help text.

/usr/bin/pon and /usr/bin/poff are scripts that call the /usr/sbin/pppd application. pppd known as the Point-to-Point Protocol Daemon is a complicated program but if needed its manual with an endless list of options can be found at http://ppp.samba.org/pppd.html

pon -h
poff -h

pon and poff -h

If connected let us disconnect our current ppp connection using the poff script.

sudo poff -a
ifconfig -s

Ifconfig should only list eth0 and lo under the Iface column.

ifconfig -s

Let us reconnect again.

sudo pon proxpnuk updetach
ifconfig -s

sudo pon proxpnuk updetach

To see your connection settings for troubleshooting.

sudo pon proxpnuk debug dump

To save the debug output to a file and view it.

sudo pon proxpnuk debug dump > ~/proxpnuk-debug.txt
cat ~/proxpnuk-debug.txt

pon proxpnuk dump proxpnuk-debug.txt

PPTP for Linux has a log file that can also be useful for troubleshooting. It is found at /var/log/messages. The tail command normally displays the last 10 lines of text file but when it’s combined with the -f follow option it displays the most recent text appended to the file.

tail -f /var/log/messages

Press [Ctrl] C to exit tail.

tail -f var log messages

Test for a VPN connection

I use the traceroute command to test for an active VPN connection. First make sure there is no ppp0 connection.

sudo poff -a
ifconfig -s

Then run traceroute to a well-known website such as google.com.

traceroute google.com

traceroute google.com no vpn

Make a note of the number of hops. In my case it took 8 hops for a request from my Raspberry Pi to reach Google’s servers.

Now if we enable our ppp0 connection and try again, you will probably discover that connecting to Google takes exactly the same number of hops.

sudo pon proxpnuk updetach
traceroute google.com

traceroute google.com no route

This probably means the internet traffic sent and received from the Pi is not using our VPN connection.

We need to create a route to tunnel our Internet traffic through our VPN. The route command at /bin/route is perfect to carry out this task.

sudo route add -net "0.0.0.0/0" dev "ppp0"

The -net 0.0.0.0/0 sets the target network of the route to be the default route. dev toggles a device to reroute our traffic to. While PPP connection number one ppp0 is that device.

To check if our route was successful use netstat with the -a all sockets option and feed the output into grep to filter and display only the lines that contain the string "/var/run/pptp/". These lines signify our PPTP routes.

netstat -a | grep "/var/run/pptp/"

route add

Test your connection again and you should have a greater number of hops than last time.

traceroute google.com

traceroute google.com with route

That meant the connection to Google.com from your Pi had rerouted through your VPN server. Congratulations.

VPN at boot

To automatically connect your Pi to a VPN server at start-up I’d recommend placing the following script into /etc/rc.local. This file runs all commands within as a superuser, at the end of a Pi boot but before the user login prompt. I use the -B option with the nano text editor to backup the rc.local file before making any changes to it.

sudo nano -B /etc/rc.local

Make sure you insert any script before the exit 0 line and after the hashed # comments.

vpn="on"
if [ $vpn = on ]; then
printf "\nVPN connection to ProXPN UK\n"
pon proxpnuk updetach
printf "Add Internet traffic route through ppp0\n"
sudo route add -net "0.0.0.0/0" dev "ppp0"
printf "Netstat output of all PPTP sockets\n"
netstat -a | grep "/var/run/pptp/"
fi

nano etc rc.local

The script is pretty self-explanatory and I have contained it within a conditional statement to disable if needed. To do this simply change the vpn="on" variable to something else such as vpn="off".

In nano press the [Ctrl] X keys to prompt for a Save modified buffer? query. Answer Y at the prompt to save and press enter to keep the current File Name to Write.

You don’t need to reboot to test your changes to rc.local.

sudo /etc/rc.local

Executes the script same way as it would with a reboot.

 

sudo etc rc.local

fi

I am happy to reply to any questions about this post but I am no expert on the subject of VPN and can not help in setting up a VPN server or using other client protocols such as OpenVPN. Extracting this information on PPTP for Linux was quite time-consuming.

Advertisements

36 thoughts on “Using a Point-to-Point Tunnelling Protocol, Virtual Private Network (PPTP VPN) client on a Raspberry Pi

  1. Nope, i’ve figured out to add persist to the end of the line “pon updetach persist” in my rc.local file, and maxfail 0 in the /etc/peers/ file, but it won’t detect a dropped connection, close the connection, then restart it.

  2. Fan-dabby-tastic guide you’ve written here! Quiz-Q for you though, how would you suggest one sets the VPN to keep-alive/auto-redial-on-drop? I’m using this to build a handful of rPIs i’m gonna dot around and would like them all to dial-home, then reconnect if the connection drops (3G for example).

  3. Hi Ben,
    I think I have solved the problem, plus an additional one which I did not mention, namely that the VPN connection will disconnect after a while. If I add “persist” and “maxfail0” to the proxpnuk file in peers (look up what this means in the pppd help) then this not only ensures that the connection will stay up, but also will retry any failed initial attempt which was due to the internet connection not being up yet.
    Regarding my comment on deleting the default route. What I have is:
    route del default
    route add default dev “ppp0”
    This effectively deletes the default route and replaces it with one which uses the VPN connection.
    This works for me anyway.
    Thanks again for your help.

  4. Hi Geoff the guide does make the assumption that the Pi was connected to a wired Ethernet connection. I personally have not used Wifi with the Pi so I am not sure what kind of problems maybe encountered when using that. But by the sounds of it you seem to be on the right track and you might need to enable the updetach functionality after the WIFI connection has been made. I am sorry I can not be of more help but I do not have the Pi with me at the moment.

    You do not want to be deleting any default routes as each internet interface (such as Wifi, ethernet connection 1, ethernet connection 2, etc) needs its own route. ppp0 is used to simulate a point-to-point connection between your Pi and the VPN server but it still needs to share an existing ethernet or wifi interface to gain access to the Internet.

  5. Hi Ben, thanks for providing this guideline. I have found it very useful for my project which is to provide a VPN tunnel to transport my smart TV to another country so that I can see geo-locked streaming content. I connect the rpi to my home network via wlan0 and connect the Smart TV to eth0. Your posting is therefore only part of what I have done. It all works, but only some of the time.I suspect that problem might have to do with you putting the
    pon proxpnuk updetach
    in /etc/rc.local. Doesn’t this mean that the pon bash script might run when the wireless internet connection (in my case) is not up yet? This seems to be the case with me sometimes. How can we wait for the connection? I’m just a newby so have no idea on this at the moment. Since I am a newby, can I ask another clarification question? You also have
    sudo route add -net “0.0.0.0/0” dev “ppp0”
    in /etc/rc.local. Is it not necessary to delete the default route first?
    Cheers,
    Geoff

  6. hey ben, I am a complete noob here and am only copying what I see. I have run into 2 problems.
    1. kernel does not support PPP filtering – what can be done to solve this?
    2. -bash: traceroute: command not found.

    I am running the latest version of Raspbmc with the latest version of pptp-linux

    I appreciate any help you could offer

    1. Hi, Raspbmc seems to be your problem. It’s designed for multimedia and has many of the usual Linux networking tools removed. As a ‘noob’ you’re unfortunately out of luck as Raspbmc does not support VPN. If you need VPN I suggest using Raspbian Linux on your Pi instead.

  7. Hi Jose unfortunately there could be an endless list of problems with no obvious solution. The first thing I would check is to make sure your VPN server you’re connecting to is tested and working and the VPN settings saved to the Pi are 100% correct.

    1. Hi there Ben! Thank you for your reply! So here we go…

      1) The VPN service is ipvanish.com it works well and it’s well configure since withing the PI I can connect through the VPN, and acquire their IP and make normally all kind of stuff
      2) When I connect remotely to my PI using my internal network (LAN) I successively use all of it’s services (HTTP server, SSH, DNS, DHCP
      3) When the PPP tunnel is active the PI tries to route ALL incoming traffic from eth0 (that as a external IP giving by my ISP) to ppp0, and by that when I try to access, for example, SSH it just can’t connect because it’s sending ALL packages through ppp0 and not letting them land on the SSH port of the PI

      Just check my route without the ppp
      Kernel IP routing table
      Destination Gateway Genmask Flags Metric Ref Use Iface
      0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
      192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

      And now with ppp active
      Kernel IP routing table
      Destination Gateway Genmask Flags Metric Ref Use Iface
      0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 ppp0
      94.46.217.221 192.168.0.1 255.255.255.255 UGH 0 0 0 eth0
      94.46.217.221 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
      192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

      It seems to me that the solution would be to route predetermine ports to “lo” interface (127.0.0.1), for example the 22 (SSH).
      I’ve tried to do this with iptables and went on-line and found a script generator for that, but couldn’t get it to work.

      What do you think, is my logic correct? Or does this seems impossible to do, without a new interface, for example a wlan device?
      Thank you in advance.

      José

  8. Hi there just one question,,,

    After I’ve activated the ppp I can’t no longer access my linux box from the outside world, only in my home network, do you now how to solve this?

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s