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

  2. 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é

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

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

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

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

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

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

  9. Hi Tim did you end up solving your problem? I unfortunately have no access to my Pi or Linux for a while. But I’d imagine you would need to create a bash background script that would detect the pressence of a disconnection and restart it.

    1. Hi Ben and thanks for this outstanding tutorial!!

      I’m also a total noob when it comes to Linux and have no idea whatsoever how to detect (and respond accordlingly..) a VPN that drops dead.

      Any chance that you or someone else might help me with some help on that as well?

      After some pretty serious googling I can say that it probably would be a RasPi first.

      Best regards,
      Udo

      1. Hi Udo thanks! Unfortunately I am not quite sure what you are needing as there is a VPN test paragraph in the article under ‘Test for a VPN Connection’. Just go through that and take note of the ‘hop count’ when your VPN is connected and active. If in the future if you suspect the VPN is down, run the same ‘traceroute [web site]’ command again and take note of its hop count. If it is a similar number to your previous tests the connection is active, if it is significantly less then the VPN is down.

        The traceroute tells you how many (hop count) servers a web request needs to pass through to reach the destination website from your computer. If a VPN is active your traceroute hop count will be much higher as a request first detours to the VPN before forwarding the request to the destination website.

  10. Hello Ben, First of all I want to give you a big humble thank you for this work.

    I am almost successful. Almost there. But:
    Yes; My RasPi/Raspbian (uptaded & upgraded) gets connected, authenticated by my FoxyproxyVPN server.
    Yes; ppp0 is created and {netstat -a | grep “/var/run/pptp/”} returns an identical reply as your example (this is true for all commands)
    But No; traceroute 8.8.8.8 returns a confusing result and traceroute google.com does not work at all.
    This is is what I get:

    traceroute 8.8.8.8
    traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
    1 172.16.32.1 (172.16.32.1) 66.882 ms 73.381 ms 72.713 ms
    2 172.16.32.1 (172.16.32.1) 72.022 ms !X 71.267 ms !X 70.612 ms !X
    pi@raspberrypi ~ $ netstat -a | grep “/var/run/pptp/”
    unix 2 [ ACC ] STREAM LISTENING 5919 /var/run/pptp/255.255.255.255:93.89.80.88
    unix 3 [ ] STREAM CONNECTED 5922 /var/run/pptp/255.255.255.255:93.89.80.88

    What can possibly be wrong? 72.022 ms !X is a bad sign…

    I think something goes wrong here:
    sudo route add -net “0.0.0.0/0” dev “ppp0”

    I connect to foxyproxy with my Mac, Ipad and android through the same router (apple) with ease.
    I rebooted and all is clean and fresh before trying to tunnel.

    If anyone can help me out I`ll put up an extra star in the sky for you (a Swedish expression 🙂

    Best regards
    Johan

    1. Hi Johan,

      I might suggest getting in contact with the FoxyProxy support at http://getfoxyproxy.org/vpn/index.html.

      They officially support Ubuntu which is essentially the same as Raspbian that is running on the Pi. Just ask them to help you troubleshoot a Ubuntu shell installation and hopefully they will be able to help out.

      1. Dar Ben,

        Thank you for you immediate reply!
        Last night I solved it.
        The Apple Air Port Extreme routers may cause PPTP related troubles for “Linux users”. I found reports on this issue on the internet, dating from 2006 (maybe even earlier). My old mid priced router allowed this traffic.
        The APE accepts PPTP from my Mac, Ipad and Adroid but not form the Raspberry Pi, most confusing.

        Best regards
        Johan

  11. Hi,

    Many thanks for the info. I get up to the point where it says to enter

    sudo route add -net “0.0.0.0/0” dev “ppp0”

    That works fine but then I try

    traceroute google.com

    and I get the following error:

    google.com: Name or service not known
    Cannot handle “host” cmdline arg `google.com’ on position 1 (argc 1)

    All previous commands work fine including the previous traceroute google.com command. Any help on this would be much appreciated as I have been trying to connect to my VPN for over a week now with no success.

    Gauss4

  12. Hi Gauss4,

    When your traceroute fails like that i means your Pi did not successfully connect to your VPN either because it could not log on or it couldn’t find the server.

    Check your VPN settings on the Pi and make sure they match those on the VPN server.

    The Pi VPN settings can be changed using the pptpsetup command and that is listed under ‘Setup and configuration’ in the blog entry.

    Best of luck

  13. Thanks for the quick response Ben. Unfortunately I really cannot see what could be wrong with my settings. After entering my server configuration and running route -n I get the following:

    sudo pptpsetup –create piaUKLon –server uk-london.privateinternetaccess.com –username *** –password *** –encrypt –start

    Using interface ppp0
    Connect: ppp0 /dev/pts/1
    CHAP authentication succeeded
    MPPE 128-bit stateless compression enabled
    local IP address 10.1.1.11
    remote IP address 10.1.1.1

    route -n

    Kernel IP routing table
    Destination Gateway Genmask Flags Metric Ref Use Iface
    0.0.0.0 192.168.0.254 0.0.0.0 UG 0 0 0 eth0
    10.1.1.1 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
    126.187.18.14 192.168.0.254 255.255.255.255 UGH 0 0 0 eth0
    192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

    Then the re-route to tunnel command:

    sudo route add -net “0.0.0.0/0” dev “ppp0”

    and route -n again:

    route -n

    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
    0.0.0.0 192.168.0.254 0.0.0.0 UG 0 0 0 eth0
    10.1.1.1 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
    126.187.18.14 192.168.0.254 255.255.255.255 UGH 0 0 0 eth0
    192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

    (Where I have changed some of the numbers for security reasons)

    Can you see anything that might be wrong?

    Ah yes, I almost forgot. I connect to my Pi through LAN on my desktop PC through SSH. Could this be a problem? And if I did get the tunnel to work could I still connect to the Pi through the LAN in the usual way?

    Once again any input would be much appreciated.

    Thanks

    Gauss4

    1. Unfortunately I can’t really help you Gauss because I have no information on your VPN or your home network so all those numbers really don’t mean anything. Every individual VPN setup will be different and I am not a customer service rep for your VPN provider. You’ll have to work this out yourself. I’d suggest you first narrow down your potential issues such as trying to connect to the VPN using a different computer on your LAN. And if that works then connect the Pi directly to your router using ethernet and seeing if that is okay.

      1. No problem. Thanks for your comments. Just as a final point. My desktop, on the same LAN connects with no problems but then my provider has specific software for that (windows PC). As for the Pi, it is connected directly to the router with an ethernet cable.

        Gauss4

        1. Well you first need to ask your provider if they support Linux and if so ask for their help. If they don’t support Linux they may have a proprietary setup that will not work without their specific software.

          1. They definitely support Linux because there are tutorials for connecting on their website. Unfortunately they are all GUI instructions and no command line info.

    2. I have fixed this issue by providing the Google public name server in the /etc/resolv.conf file. If you can ping successfully to the Google or any website IP address,but not the http://www.google.com or websites then follow the below steps,

      Make a backup of the resolv.conf file,
      cd /etc/
      sudo cp resolv.conf resolv.conf.bck

      edit the file,
      sudo nano resolv.conf

      Delete all the contents and type,
      nameserver 8.8.8.8

      Save. Now check whether its working.

    1. Hi Philip,

      Whenever you run ‘pon’ you can add the option ‘persist’ which should auto-reconnect on disconnection.

      So instead of …

      pon proxpnuk updetach

      You would do …

      pon proxpnuk updetach persist

  14. Great guide but I got a error when doing traceroute but the comment of Sathesh Sivashanmugam fixed it.
    Just one question: What will happen if the VPN connection drops? Will it stop all data from going out unencrypted and try to reconnect or will data just go out unencrypted?
    Thanks,
    Isaac

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