Netflix finally arrived in Germany, but guess what? It's library is heavily limited in comparison to the US one and if you like TV series as much as I do, you don't want to wait until they eventually release it year(s) later for us german users.

Maybe you've heard recently of Anonabox — a small device with two ethernet ports that you can plug in front of your router and everything behind the device is routed through Tor (side note: turned out to be a scam and got pulled from Kickstarter in the end). However, it made me come up with an idea: Instead of having a Tor-box, I want a VPN-box that is connected to my PrivateInternetAccess VPN. If I'm in need of a VPN connection I just switch the WiFi network and I'm good to go. This way I can easily watch US content from Netflix as well as unblock location restricted content like YouTube, even with my iPhone or Xbox.

Another purpose might be to use it as an anonymizer if you care about your privacy and anonymity while browsing the web.

All you need for this is a Raspberry Pi, a WiFi Stick and a 8 or 16 GB SD card. Let's start with the general assumptions:

Assumptions

General

You have a Raspberry Pi and you want to use it as a VPN gateway

The gateway should be accessible within a dedicated VPN-only WiFi SSID

The Pi is connected via Ethernet to your home network

The WiFi stick is a RTL8188CUS 802.11n WLAN Adapter

(Not sure if these are really RTL8188CUS sticks though)

(Not sure if these are really RTL8188CUS sticks though) You use a Mac OS X based computer to prepare the SD card

Technical

Our home network uses IP range: 192.169.1.0/24

The VPN network is going to use the IP range: 192.168.101.0/24

We're going to use PrivateInternetAccess as VPN provider

We're going to use OpenVPN as VPN client

We'll use raspbian as distribution

Guide

Prepare SD card

Mount your SD card and download and unzip the latest raspbian image:

cd /tmp curl -L "http://downloads.raspberrypi.org/raspbian_latest" -o /tmp/raspbian_latest.zip unzip raspbian_latest.zip

Clone @RayViljoen's Raspberry PI SD Installer for OS X and execute it to transfer the raspbian:

git clone https://github.com/RayViljoen/Raspberry-PI-SD-Installer-OS-X.git cd Raspberry-PI-SD-Installer-OS-X sudo ./install /tmp/2014-09-09-wheezy-raspbian.img

In the prompt, select the number of the disk drive (I had to select 5 ) of your SD card and wait till it finished writing the image to the SD card. Finally, unplug the SD card when the process is done

Configure the Pi as access point

Intermediate assumptions:

You plugged in the WiFi stick

You booted the Pi from the SD card

You did the base configuration of raspbian

(change password, timezone, localization, etc.)

(change password, timezone, localization, etc.) apt-get repositories and packages are up to date

( sudo apt-get update && sudo apt-get upgrade -y )

repositories and packages are up to date ( ) ifconfig shows an wlan0 interface

shows an wlan0 interface You can access the internet using ethernet ( curl icanhazip.com returns the external IP)

Install and configure hostapd and the DHCP server

To create a WiFi network, we need hostapd to manage the authentications and isc-dhcp-server to act as DHCP server:

sudo apt-get install hostapd isc-dhcp-server

Now we need to adjust the DHCP configuration:

sudo vi /etc/dhcp/dhcpd.conf

[...] #option domain-name "example.org"; #option domain-name-servers ns1.example.org, ns2.example.org; [...] # If this DHCP server is the official DHCP server for the local # network, the authoritative directive should be uncommented. authoritative; [... go to end of file ...] subnet 192.168.101.0 netmask 255.255.255.0 { range 192.168.101.10 192.168.101.50; option broadcast-address 192.168.101.255; option routers 192.168.101.1; default-lease-time 600; max-lease-time 7200; option domain-name "local"; option domain-name-servers 8.8.8.8, 8.8.4.4; }

And make sure to use the proper interface:

sudo vi /etc/default/isc-dhcp-server

[...] INTERFACES="wlan0"

Setup network interface

Let's adjust the network interface and use a static IP:

sudo vi /etc/network/interfaces

[...] allow-hotplug wlan0 iface wlan0 inet static address 192.168.101.1 netmask 255.255.255.0 [...] #iface wlan0 inet manual #wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf #iface default inet dhcp

Restart your network interface to activate the changes:

ifdown wlan0 && ifup wlan0

Configure hostapd

In the next step, we're going to adjust the hostapd configuration. Make sure you replace [Your_WiFi_SSID] as well as [Your_WiFi_Pass] :

sudo vi /etc/hostapd/hostapd.conf

interface=wlan0 driver=rtl871xdrv ssid=[Your_WiFi_SSID] hw_mode=g channel=6 macaddr_acl=0 auth_algs=1 ignore_broadcast_ssid=0 wpa=2 wpa_passphrase=[Your_WiFi_Pass] wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP

And assure to adjust the configuration defaults:

sudo vi /etc/default/hostapd

[...] DAEMON_CONF="/etc/hostapd/hostapd.conf" [...]

Recompile hostapd to work with RTL8188CUS

To use our RTL8188CUS we need to recompile hostapd with the according chipset. Download and extract the latest drivers:

cd /tmp sudo wget "ftp://WebUser:[email protected]/cn/wlan/RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911.zip" sudo unzip RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911.zip cd RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911/wpa_supplicant_hostapd sudo tar -xvf wpa_supplicant_hostapd-0.8_rtw_r7475.20130812.tar.gz

Compile and move them into your $PATH variable:

cd wpa_supplicant_hostapd-0.8_rtw_r7475.20130812/hostapd sudo make && sudo make install sudo mv hostapd /usr/sbin/hostapd sudo chown root:root /usr/sbin/hostapd sudo chmod 755 /usr/sbin/hostapd

Configure OpenVPN

To connect to PIA, we're going to use the OpenVPN client. Install and download the default configuration profiles provided by PrivateInternetAccess:

sudo apt-get install openvpn unzip sudo mkdir -p /etc/openvpn/PIA/disabled cd /etc/openvpn/PIA wget https://www.privateinternetaccess.com/openvpn/openvpn.zip sudo unzip openvpn.zip && rm openvpn.zip

and rename the profiles, so you can take advantage of the autostart option later:

sudo rename 's/ovpn/conf/' /etc/openvpn/PIA/*.ovpn sudo rename 's/ /_/g' /etc/openvpn/PIA/*.conf

Create an authentication file that will hold your PIA username and password. Make sure you replace <PIAopenVPNuser> and <PIAopenVPNpass> , matching your credentials:

sudo echo "<PIAopenVPNuser>" >> /etc/openvpn/PIA/auth.txt sudo echo "<PIAopenVPNpass>" >> /etc/openvpn/PIA/auth.txt

Since relative paths do no good to our setup, we replace them with absolute ones:

sed -i 's/auth-user-pass/auth-user-pass \/etc\/openvpn\/PIA\/auth.txt/g' *.conf sed -i 's/ca ca.crt/ca \/etc\/openvpn\/PIA\/ca.crt/g' *.conf sed -i 's/crl-verify crl.pem/crl-verify \/etc\/openvpn\/PIA\/crl.pem/g' *.conf

Last but not least, you can move all unwanted configurations, that you don't want to connect to in future in the disabled/ folder:

sudo mv CA_North_York.conf disabled/ sudo mv CA_Toronto.conf disabled/ sudo mv France.conf disabled/ sudo mv Germany.conf disabled/ sudo mv Hong_Kong.conf disabled/ sudo mv Netherlands.conf disabled/ sudo mv Romania.conf disabled/ sudo mv Sweden.conf disabled/ sudo mv Switzerland.conf disabled/ sudo mv UK_London.conf disabled/ sudo mv UK_Southampton.conf disabled/

Gimmick: Choose random VPNs from "profile pool"

Because I don't want to use the same VPN server/location over and over again, I rather want to randomly choose one location profile from the "profile pool" in /etc/openvpn/PIA/ . As soon as I restart the VPN, it will choose a different one than before. This way I simply can reboot the Pi to obtain a new location/IP address.

vi /etc/default/openvpn

CONFIG_DIR=/etc/openvpn/PIA [...] test -d $CONFIG_DIR || exit 0 # Helper array and selector variable to pick random element returnRandomVPN (){ CHOSEN=`find $CONFIG_DIR -maxdepth 1 -type f | shuf -n1 | grep conf` CHOSEN=`basename $CHOSEN .conf` # If empty, choose new one if [ ! "$CHOSEN" ]; then returnRandomVPN else echo $CHOSEN fi } # Source defaults file; edit that file to configure this script. AUTOSTART=`returnRandomVPN` [...]

To test the "randomizer", just stop and start the OpenVPN client a couple of times:

[ ok ] Starting virtual private network daemon: US_Florida. [ ok ] Stopping virtual private network daemon: US_Florida.

service openvpn start && service openvpn stop

[ ok ] Starting virtual private network daemon: US_West. [ ok ] Stopping virtual private network daemon: US_West.

service openvpn start && service openvpn stop

[ ok ] Starting virtual private network daemon: US_Seattle. [ ok ] Stopping virtual private network daemon: US_Seattle.

NAT & Netfilter/iptables adjustments

Enable IPv4 forwarding:

sudo echo 1 > /proc/sys/net/ipv4/ip_forward sudo vi /etc/sysctl.conf

[...] net.ipv4.ip_forward = 1 [...]

And adopt the following iptables rules to make sure your traffic is routed via the VPN:

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE -m comment --comment "Use VPN IP for eth0" sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE -m comment --comment "Use VPN IP for tun0" sudo iptables -A FORWARD -s 192.168.101.0/24 -i wlan0 -o eth0 -m conntrack --ctstate NEW -j REJECT -m comment --comment "Block traffic from clients to eth0" sudo iptables -A FORWARD -s 192.168.101.0/24 -i wlan0 -o tun0 -m conntrack --ctstate NEW -j ACCEPT -m comment --comment "Allow only traffic from clients to tun0"

For a persistent configuration that survives reboot, we got to do some extra steps:

sudo iptables-save > /etc/iptables.ipv4.nat sudo echo "up iptables-restore < /etc/iptables.ipv4.nat" >> /etc/network/interfaces

Now reboot your Pi and make sure the iptables rules are loaded again:

reboot

sudo iptables -vL && iptables -vL -t nat

[...] Chain FORWARD (policy ACCEPT 2758 packets, 1347K bytes) pkts bytes target prot opt in out source destination 0 0 REJECT all -- wlan0 eth0 192.168.101.0/24 anywhere ctstate NEW /* Block traffic from clients to eth0 */ reject-with icmp-port-unreachable 117 8618 ACCEPT all -- wlan0 tun0 192.168.101.0/24 anywhere ctstate NEW /* Allow only traffic from clients to tun0 */ [...] Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 116 8536 MASQUERADE all -- any tun0 anywhere anywhere /* Use VPN IP for tun0 */ 8 568 MASQUERADE all -- any eth0 anywhere anywhere /* Use VPN IP for eth0 */

Start/stop services

To ensure your VPN, hostapd and DHCP server is started as soon as you power on the Pi:

sudo update-rc.d hostapd enable sudo update-rc.d isc-dhcp-server enable sudo update-rc.d openvpn enable

Tests

To test the whole setup, reboot the Pi, SSH into it and make sure the services run correctly:

sudo service hostapd status

[ ok ] hostapd is running.

sudo service isc-dhcp-server status

Status of ISC DHCP server: dhcpd is running.

sudo service openvpn status

[FAIL] VPN 'US_California' (non autostarted) is not running ... failed! [FAIL] VPN 'US_East' (non autostarted) is not running ... failed! [FAIL] VPN 'US_Florida' (non autostarted) is not running ... failed! [ ok ] VPN 'US_Midwest' (non autostarted) is running. [FAIL] VPN 'US_Seattle' (non autostarted) is not running ... failed! [FAIL] VPN 'US_Texas' is not running ... failed! [FAIL] VPN 'US_West' (non autostarted) is not running ... failed!

Check the outgoing IP for eth0. Make sure it's one of your VPN provider and not your "real" one: curl icanhazip.com

Connect to the new VPN WiFi of the Pi, open http://ipleak.net and check if there are leaking DNS requests

Reboot the Pi (either sudo reboot or power cycle) and check if you get a new IP from a new VPN location

Sources

Let me know in the comment section below in case you have any issues suggestions or general feedback.