Saturday, November 9, 2013

Configure a Raspberry Pi as OpenVPN Client

Background

I wanted to turn a Raspberry Pi into an OpenVPN gateway on my local network at home, so a SIP-based IP phone can talk to my Asterisk server via an encrypted tunnel. This was a quick-and-dirty setup that works. I am sure it can be improved or made more elegant (send me comments if you have suggestions). I wrote this mostly for my own safekeeping.

This document does not describe the setup of the OpenVPN server or how to generate SSL certificates for the client. There is plenty of documentation on that elsewhere. I also will not describe the Asterisk setup here (I might document that separately later).

Network situation


My home LAN is connected to the Internet via a standard router. The hardware SIP phone does not support any kind of VPN natively, so I will route the SIP traffic through the Raspbery Pi, which will be configured as an OpenVPN client to the OpenVPN server running on my Asterisk server.

  • Home LAN: 192.168.1.0/255.255.255.0
  • VPN Network: 192.168.7.0/255.255.255.0

Installation / Configuration


1. Install Raspbian


This document is based on Raspbian. Whether you install it via the NOOBS installer or the Raspbian image does not matter. Install Raspbian on your SD card and go through the initial setup at first boot; set the password of the pi user, etc.

2. Install Software Packages


We need the openvpn package, but it does not hurt to refresh all other packages as well before we start. Log in as pi and become root for these steps.

$> sudo su -
#> apt-get update
#> apt-get dist-upgrade
#> apt-get install openvpn


3. Configure OpenVPN Client


Copy the OpenVPN SSL client certs and the CA cert into /etc/openvpn.

Then create the /etc/openvpn/client.conf file, similar to this example:
# OpenVPN CLient Configuration

client
dev tun

proto udp
remote myserver.com 6666

resolv-retry infinite
nobind

user nobody
group nogroup

persist-key
persist-tun

ca ca.crt
cert mycert.crt
key mycert.key

ns-cert-type server
comp-lzo
verb 3

Launch the VPN by starting the OpenVPN init script and make sure it connects:
$> /etc/init.d/openvpn start

On success, the output of ifconfig should show you a tun0 interface with the IP information of your VPN subnet:
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:192.168.7.10  P-t-P:192.168.7.9  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

4. Configure sysctl


In order to allow network traffic to be forwarded, you need to enable this via sysctl.

First, set this in the running system:

#> sysctl net.ipv4.ip_forward=1

Then update /etc/sysctl.conf, so this gets set at boot time. Find the following lines and uncomment the forward setting:

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

5. Configure iptables


We will configure iptables to masquerade local IPs into the VPN subnet. Create /etc/iptables.conf with the following content, adjusting the masquerading subnet accordingly. The subnet of my VPN is 192.168.7.0/255.255.255.0, so we will masquerade anything that hits the Raspberry Pi for that subnet.

# Generated by iptables-save
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Generated by iptables-save
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o tun0 -d 192.168.7.0/24 -j MASQUERADE
COMMIT

Make sure these rules are loaded whenever the Raspberry Pi boots. You could write a fancy init script, or be lazy like I am and simply restore the rules by adding this to /etc/rc.local:

# Load iptables for VPN masquerading
echo "Loading iptables for OpenVPN masquerading"
/sbin/iptables-restore < /etc/iptables.conf

6. Route to the Pi


The last step is to configure the SIP phone to use the IP of the Raspberry Pi as its default gateway. I have my Pi running on DHCP with a permanent DHCP lease. You could also configure a static IP in your Pi.