Raspberry Pi transparent OpenVPN gateway

[ sharable url: bmn.io/r ]

The Australian government has recently introduced mandatory data retention as a knee-jerk reaction to fighting domestic terrorism, which is a nice gesture - for the government to start monitoring Australian residents. They promised that monitoring & retaining meta data would only be used for the purposes of monitoring & detecting terrorist behaviour within Australia.

Arguing that you don't care about the right to privacy because you have nothing to hide is no different than saying you don't care about free speech because you have nothing to say - Edward Snowden

Let’s face it, we can’t be sure the goverment isn’t using this information for other purposes, and this is only the beginning. So for those of us who aren’t terrorists and don’t appreciate all our data being monitored without our concent, I have decided to share my Raspberry Pi OpenVPN gateway setup.

Basically this setup lets you encrypt all your home network traffic to a server offshore, without having to setup each individual device with a VPN connection. Nifty!

Another bonus to this system is that if you wish to bypass the VPN tunnel and browse directly online, all you need to do is point your device to the existing router as the default gateway.

All you will need for this project is:

  • Basic to intermediate Linux knowledge,
  • a linux machine (I'm using a raspberry pi running 14.04),
  • an OpenVPN provider or your own linux server offshore,
  • access to your router,
  • some spare time

Before we get started, this guide would not have been possible without these pages: https://trick77.com/how-to-set-up-transparent-vpn-internet-gateway-tunnel-openvpn/ https://help.ubuntu.com/lts/serverguide/openvpn.html

And I must also mention, I am not a network/sysadmin guy, so I’m sure this guide is full of errors, this is just what worked for me. And as always, use another source to confirm what you read here. I am not responsible for any mishaps that may occur as a result of this guide.


Overview

In this guide, the server will be the remote OpenVPN server, and the client will be the Raspberry Pi running inside your local network.

Overview of IP addresses:

LAN Network:                10.0.10.0/24
Default gateway of router:  10.0.10.1
Default DNS:                10.0.10.1

Raspberry Pi:               10.0.10.2
Default gateway of VPN:     10.0.10.2
Default VPN DNS:            10.0.10.2

VPN Network:                10.8.0.0/24
VPN Server in VPN Network:  10.8.0.1

Basically this means that for any device inside the LAN, they can simply set their gateway setting to 10.0.10.2 (raspberry pi) and their DNS to 10.0.10.2 and they will have a secure VPN connection.

Server Setup

Obviously if you are using an OpenVPN provider, you can most skip this section - all you will need from your provider is your client certificates & a copy of the ca certificate.

These steps are adapted form the official ubuntu guide.

  • Install the OpenVPN packages:

    sudo apt-get install openvpn easy-rsa
  • Public Key Setup

    Basically we are going to setup our own Certificate Authority (CA), which will issue certificates to clients wanting to connect. In our scenario, we will only have 1 client, which will be the raspberry pi, but theoreticallly you could have many different raspberry pis connecting via this single vpn server.
    • CA Setup

      With all of these steps, always leave the password blank.
      mkdir /etc/openvpn/easy-rsa/
      cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
      Now, lets edit the default vars file /etc/openvpn/easy-rsa/vars, to make certificate generation easier. Adjust the following variables in your version of the vars file accordingly:
      export KEY_COUNTRY="AU"
      export KEY_PROVINCE="VIC"
      export KEY_CITY="Melbourne"
      export KEY_ORG="Example Company"
      export KEY_EMAIL="ben@example.com"
      export KEY_CN="MyVPN"
      export KEY_NAME="MyVPN"
      export KEY_OU="MyVPN"
      export KEY_ALTNAMES="MyVPN2"
      Now we will generate our CA certificate for creating server/client certificates:
      cd /etc/openvpn/easy-rsa/
      source vars
      ./clean-all
      ./build-ca
      Lets now build a server certificate, making sure to sign the certificate & commit the certified certificate:
      ./build-key-server myservername
      Build those Diffie Hellman parameters.
      ./build-dh
      After these steps, you should see some certificates in the keys/ folder. It is common practise to now copy these to /etc/openvpn:
      cd keys/
      cp myservername.crt myservername.key ca.crt dh3048.pem /etc/openvpn/
    • Generate a client certificate for our raspberry pi

      cd /etc/openvpn/easy-rsa/
      source vars
      ./build-key client1
      This should have created us the following files:
      • client1.crt
      • client1.key
      We now copy the following files to the raspberry pi in a secure fashion, making sure to remove the client keys from your server as they aren't required there anymore:
      • /etc/openvpn/easy-rsa/keys/client1.crt
      • /etc/openvpn/easy-rsa/keys/client1.key
      • /etc/openvpn/ca.crt
  • Server config file

    I'm just doing to detail a very basic server config to get the VPN working, but you're welcome to tweak your own as you see fit. The server file is located at /etc/openvpn/server.conf and mine looks like this:
    mode server
    dev tun
    
    ca /etc/openvpn/ca.crt
    cert /etc/openvpn/myservername.crt
    key /etc/openvpn/myservername.key
    dh /etc/openvpn/dh3048.pem
    
    server 10.8.0.0 255.255.255.0
    keepalive 5 30
    user nobody
    group nogroup
    persist-key
    persist-tun
    status /var/log/openvpn-status.log
    log /var/log/openvpn.log
    verb 3
    push "redirect-gateway def1"
    push "dhcp-option DNS 10.8.0.1"
    comp-lzo adaptive
    push "comp-lzo adaptive"
    client-config-dir clients
    
    route 10.0.10.0 255.255.255.0

    My LAN ips are setup in the 10.0.10.0 range, so we have to add this route so the clients know where to route its traffic.

  • IP Forwarding

    Lets also not forget that we need to enable the server to forward IP traffic: Go ahead and edit: /etc/sysctl.conf and uncomment this line (if it isn't already):
    net.ipv4.ip_forward=1
    And then restart sysctl:
    sudo sysctl -p /etc/sysctl.conf
  • Add a local DNS resolver

    Lets boot it up and make sure our config works.
    apt-get install dnsmasq

    Just put a public DNS resolver in /etc/resolv.conf and you should be good to go

    nameserver 8.8.8.8
    nameserver 8.8.4.4
  • IPTables forwarding

    Make sure we route/masquerade the requests from our src network to the destination network
    /sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    /sbin/iptables -t nat -A POSTROUTING -s 10.0.10.0/24 -o eth0 -j MASQUERADE
    I also block all unnessisary traffic on my machine with iptables, so I had to open the specific port for OpenVPN, which is 1194 UDP.
    /sbin/iptables -I INPUT 1 -p udp --dport 1194 -j ACCEPT

    I would suggest adding this to /etc/rc.local if you don't already have any iptables rules.

  • Per client routing

    According to a few sources, we need to add a custom client file on the server, so we can add some specific routes. This file will be named whatever we named the certificated when generated them, in our case client1. So lets create that file at: /etc/openvpn/clients/client1 and put this in it:
    iroute 10.0.10.0 255.255.255.0
    push "route 10.0.10.0 255.255.255.0"
  • Start the service

    Lets boot it up and make sure our config works.
    service openvpn start
     * Starting virtual private network daemon(s)...
       *   Autostarting VPN 'myservername'                     [ OK ]
    And confirm that we have a tun0 interface:
    ifconfig tun0
    tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
              inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
              UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1

Client Setup

If you’ve come this far, well done, we are almost finished!

  • Install the OpenVPN packages:

    sudo apt-get install openvpn easy-rsa
  • Client config file

    I'm just doing to detail a very basic server config to get the VPN working, but you're welcome to tweak your own as you see fit. The server file is located at /etc/openvpn/client.conf and mine looks like this:
    client
    dev tun
    proto udp
    
    remote myserver.com 1194
    resolv-retry infinite
    nobind
    user nobody
    group nogroup
    persist-key
    persist-tun
    
    ca ca.crt
    cert client1.crt
    key client1.key
    
    ns-cert-type server
    comp-lzo
    verb 3
  • Add a local DNS resolver

    apt-get install dnsmasq resolvconf
  • Start the service

    Lets boot it up and make sure our config works.
    sudo service openvpn start
    Starting virtual private network daemon: client.
    And confirm that we have a tun0 interface:
    ifconfig tun0
    tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
              inet addr:10.8.0.10  P-t-P:10.8.0.9  Mask:255.255.255.255
              UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1

Bam - you should now have a running tunnel.

Confirming

Once you have it all setup, and it looks like its working - simply set a devices’ gateway to 10.0.10.2 and their DNS to 10.0.10.2 and then load up whatismyip.org and confirm the differnet IP address. You can go one step further and confirm your new region by loading Max mind geo IP lookup and confirm the change.

Troubleshooting

Obviously there are plenty of places where things can go haywire here - this is by no means a conclusive/complete guide - but should get you going with 95% of the setup - the rest you can figure out by googleing solutions. I do have one piece of information that really helped me when trying to get the client to connect… On the server, tail the openvpn log file to see what is happening.

tail -f /var/log/openvpn.log

And then...?

I’ve extended my client’s functionality by making it the DHCP server & provide static IP assignments within my network rather than my AirPort Extreme. Given the limited configurability of the APE, it was kind of tricky - but I’m happy to write another post detailing how to set that up.

Having my VPN client provide IPs with DHCP, I can get it to issue IP addresses out with the gateway as the VPN server, so by default any device connecting to the network gets tunneled over the VPN - nice! It also lets me never have to remember IP addresses internally as I can name devices based on their MAC address, and better still, if my APE dies, I don’t need to reconfigure anything as I can just dd my rpi to another SDCard for backup.