I’ve decided to update the VPN router on my home network using a Raspberry Pi 2, I’m quite impressed at how well it works. I was previously using a HomePlug AV adapter but found this to be a bit of a network bottleneck. So now my Raspberry Pi 2 is connected directly to my router using an ethernet cable.
Previously, I installed a DNS server (Unbound) as a caching recursive DNS server, this service resided on the same machine that I ran my VPN router on. Now however, after a bit of research I’ve decided to let my VPN’s DNS servers answer all the requests from my VPN connected devices.
I now run a separate DHCP/DNS server on my home network (DNSMasq) with a DNSCrypt wrapper that encrypts all the DNS requests that don’t go through my VPN Router.
What you need
You will need some knowledge of networking and/or some IT knowledge.
A Raspberry Pi 2 or 3 running the current Raspian Jessie Lite – 2016-03-18.
Configure a static IP address
The new version of of the dhcpcd daemon included in the Jessie image doesn’t seem to read /etc/network/interfaces as it used to So if you configure a static IP in the usual way, you’ll end up with 2 IP addresses.
The workaround is to configure a static IP address as you would normally, then disable dhcpcd daemon. Then if you decide later to provision your Pi for something else, it’s easily reversible.
sudo systemctl disable dhcpcd.service
The above shows that the router’s IP address (Gateway) is 192.168.1.254, yours may be different, so remember to change it to suite your circumstances. You may well have to changing the network address if your network address differs from mine, which is 192.168.1.0/24.
sudo nano /etc/network/interface
iface eth0 inet static
dns-nameservers 18.104.22.168 22.214.171.124
Setting up your VPN server
Next, you need to install openvpn on your raspberry pi and test it, I’ve provided an extensive list of VPN providers in the references section (right at the bottom) feel free to choose one after installing openvpn (make sure the VPN provider you choose, support openvpn).
First off, you need to install openvpn. You can do this by typing the following at the prompt.
sudo apt-get install openvpn
After you’ve installed openvpn, you’ll need to choose a VPN provider. Ensure that the one you choose, supports Linux and Openvpn. If it’s a good provider, they will provide you with the option of downloading an OpenVPN configuration file, which should have the extension (.ovpn). After you’ve downloading the file to your Raspberry Pi, change the extension to a (.conf) extension and copy it to the “/etc/openvpn/” directory of your Raspberry Pi.
sudo cp your_vpn_provider.ovpn /etc/openvpn/your_vpn_provider.conf
Test that the VPN actually works.
sudo openvpn --config /etc/openvpn/your_vpn_provide.conf
If it’s working as expected, then press ctrl-c to exit.
Enable VPN after reboot
sudo systemctl enable openvpn@your_vpn_provider
You should get a message similar to this (see below), the “your_vpn_provider@” will of course be what you’ve called your file.
Created symlink from /etc/systemd/system/multi-
Fire-walling the interface and enabling forwarding
Below is the shell script that I wrote (with the help of online resources). What it does is firewall the tunnel interface and the internal eth0 interface. In the event of the openvpn daemon shutting down, or the connection to your VPN provider going down, all traffic stops being forwarded.
The only part that will need changed, is the “Home_Network” variable which is currently set to my home network (192.168.1.0/24) and the VPN_DNS variable, which are the DNS servers supplied by your VPN provider. Download the script (or cut and paste) to your pi.
# Filename - firewall.sh
# Written by William Dickson
# My Private Class C Network, your network may be different.
# My VPN providers DNS servers.
# Flush previous rules, delete chains and reset counters
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Create two user-defined chains that we will use to
# open ports in the firewall.
iptables -N TCP
iptables -N UDP
# SSH Open Port.
iptables -A TCP -s $Home_Network -p tcp --dport 22 -j ACCEPT
# Open ports if you're running a DNS cache server on the same device.
# iptables -A UDP -s $Home_Network -p udp --dport 53 -j ACCEPT
# iptables -A TCP -s $Home_Network -p tcp --dport 53 -j ACCEPT
# ntopng web interface
iptables -A TCP -s $Home_Network -p tcp --dport 3000 -j ACCEPT
# Zeroconfig mdns port
iptables -A UDP -p udp -m udp --dport 5353 -j ACCEPT
# NTP Open Port.
iptables -A UDP -p udp --dport 123 -j ACCEPT
# Create two user-defined chains for the forward rules.
iptables -N fw-interfaces
iptables -N fw-open
# Create user-defined rules for the fw-interface chain.
iptables -A fw-interfaces -i eth0 -o tun+ -s $Home_Network -j ACCEPT
# Allow anything on the local link.
iptables -A INPUT -i lo -j ACCEPT
# Input chain and user defined chains (UDP and TCP) for open ports.
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
iptables -A INPUT -p udp -m state --state NEW -j UDP
iptables -A INPUT -p tcp --syn -m state --state NEW -j TCP
iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-rst
iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
# Forwarding rules and user defined chain.
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -j fw-interfaces
iptables -A FORWARD -j fw-open
iptables -A FORWARD -j REJECT --reject-with icmp-host-unreach
# Change the address of an incoming packet from the gateway to a LAN machine.
# Packet forwarding to allow me to share Linux ISO’s on bittorrent.
# iptables -t nat -A PREROUTING -i tun+ -p tcp --dport 47367 -j DNAT --to 192.168.1.15
# iptables -t nat -A PREROUTING -i tun+ -p udp --dport 47367 -j DNAT --to 192.168.1.15
# iptables -A fw-open -d 192.168.1.15 -p tcp --dport 47367 -j ACCEPT
# Re-routes all internal DNS requests to external VPN’s DNS servers.
# Stops DNS Leaks.
# If you are running your own DNS caching nameserver, you can of course change
# the IP address to point to that.
for dns in $VPN_DNS
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 53 -j DNAT --to $dns
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to $dns
# In the POSTROUTING chain of the NAT table, map the tun+ interface outgoing
# pack IP address, cease examining rules and let the header be modified.
iptables -t nat -A POSTROUTING -s $Home_Network -o tun+ -j MASQUERADE
# Log INPUT AND FORWARDING errors.
iptables -A INPUT -m limit --limit 10/m --limit-burst 7 -j LOG --log-prefix '[FW INPUT]: '
iptables -A FORWARD -m limit --limit 10/m --limit-burst 7 -j LOG --log-prefix '[FW FORWARD]: '
To change permission on the firewall.sh script (make it executable), type the following.
sudo chmod 744 firewall.sh
Run the script and apply the firewall.
I want to make the firewall rules persistent, so I’m going to install a package called iptables-persistent.
sudo apt-get install iptables-persistent
Make the rules apply at startup
sudo systemctl enable netfilter-persistent
If at any time you re-run the firewall.sh script after updating or changing it, then you will have to re-run the iptables-persistent program, to apply the updated rules after reboot. The command for that is.
sudo service netfilter-persistent save
Enable IPv4 forwarding
Edit the sysctl.conf file to enable IPv4 forwarding.
sudo nano /etc/sysctl.conf
Uncomment the following.
Save the changes and run the following to make the change permanent.
You should get the following output.
Start VPN now
sudo systemctl start openvpn@your_vpn_provider
Testing your VPN Connection
IP Address: 192.168.1.12
Subnet : 255.255.255.0
Default Gateway: (IP address of your now working Raspberry Pi VPN Router)
DNS Server : (The IP address of your VPN provider’s DNS Servers)
Here’s a screenshot of my Windows 10 virtual machine with the static IP of the details above.
As you can see below, I’m currently in Canada (hurahh!), the DNS leak test shows one ip which is the same as my exit node IP.
Here’s a good resource, with instructions on setting up a PC with a static IP address.
You can either install ntopng from the Raspberry Pi repository or you can install the new version, using the instructions provided on the ntopng website.
Installing ntopng (using the repository – Current Version 1.2.1 (r1.2.1)
Install ntopng from the repository
sudo apt-get install ntopng
Installing ntopng from the ntopng website
Got to the ntop website and follow the instructions provided.
I got the following error message when I tried to run the program.
billy@vpn:~ $ sudo systemctl status -l ntopng.service
* ntopng.service - LSB: Start/stop ntopng web
Loaded: loaded (/etc/init.d/ntopng)
Active: active (exited) since Wed 2016-06-15 12:09:32 BST; 1min 34s ago
Process: 2153 ExecStart=/etc/init.d/ntopng start (code=exited, status=0/SUCCESS)
Jun 15 12:09:27 vpn ntopng: Generating configuration file /etc/ntopng/ntopng.conf
Jun 15 12:09:27 vpn ntopng: Starting ntopng:/usr/bin/ntopng:
error while loading shared libraries: libpcap.so.0.8:
cannot open shared object file: No such file or directory
Jun 15 12:09:32 vpn ntopng: Unable to start ntopng ... failed!
Jun 15 12:09:32 vpn ntopng: failed!
Jun 15 12:09:32 vpn systemd: Started LSB: Start/stop ntopng web.
Jun 15 12:10:01 vpn systemd: Started LSB: Start/stop ntopng web.
To fix this, I had to install a couple of libraries, instructions to fix the issue below.
sudo apt-get install libpcap0.8
sudo apt-get install libmysqlclient18
sudo systemctl restart ntopng.service
Change the default ntopng login
Fire up your favorite browser and point it at the IP address of your new VPN router. For me that would be http://192.168.1.1:3000
Your may have used a different IP address, all you need to do is append the port number to the IP address.
After installing ntopng, I would suggest that you change the admin password after you login, the default login are as follows.
Default login – admin
Default password – admin
Screenshots of ntopng.
All hosts currently using my VPN router on my home network.
Showing one host on my network, and as you can see, you can look at the traffic type, ports, peers and protocols. It’s a great addition if you’re sharing your VPN with others in your family or friends. It allows you to see if someone is hogging your bandwidth or doing something a bit suspect.
It’s a really great program and if you find it useful then I would definitely buy a licence, because the paid version has a lot more functionality. If you want to see what the paid version looks like, restart your VPN router and connect to ntop, it runs the pro version for 10 minutes before defaulting to the community version.If you like it they you can purchase a licence for the pro version from here. Alternatively, if you have a little cash you can also make a donation to the project.
Simple Stateful Firewall – ArchLinux
OpenVPN – Open Source
Raspberrypi.org – Website
How To Use Systemctl to Manage Systemd Services and Units – DigitalOcean
Wikipedia – Virtual Private Network
Networking – Pi as a VPN Router
15 best VPN Providers
Geospoofing with the Raspberry Pi
VPN Provider shuts down after Lavabit case undermines security
How do I know if my VPN provider is trustworthy? (Lifehacker)
How NSA Proof Are VPN Providers?
How (and why) to set up VPN today
Electronic Frontier Foundation
VPN Creative – What is my IP address
DNS Leak Test
IP and DNS Detect
Selective VPN routing : [Solution – DSVR]
iptables ipv4 firewall – Debian Firewall Wiki
Draft investigatory Powers Bill
GCHQ Mass Surveillance
Theresa May unveils UK surveillance measures in wake of Snowden claims
UK cyber-spy law takes Snowden’s revelations of mass surveillance and sets them in stone
UN privacy head slams ‘worse than scary’ UK surveillance bill
Investigatory Powers Bill: what’s in it, and what does it mean?
Don’t spy on us