Eyes are everywhere online.
The websites you visit often track where you came from and watch where you head off to next.
A
VPN - or virtual private network - helps you browse the internet more
anonymously by routing your traffic through a server that is not your
point of origin.
It is a bit like switching cars to shake off someone who is tailing you.
There
are plenty of companies offering services with varying degrees of
security and varying degrees of cost, but if you are willing to roll
your sleeves up and get technical with some basic coding and a £30
Raspberry Pi computer, you can build your own VPN server at home.
It
won't give you the option of appearing to be from somewhere else but
you can use it to connect external devices like a smartphone to browse
the internet more securely through your home network, and access shared
files and media on your home computer.
Make no mistake, this is not a quick and easy process.
On
BBC Click I have shared some tips from my own experience setting up a DIY VPN server.
Below is a step-by-step guide you will need to follow to the letter, symbol and space if you want to follow in my footsteps.
To follow this guide you will need:
- 1 x Raspberry Pi/Pi 2
- 1 x 8GB micro SD card
- 1 x SD card reader
- 1 x 5 volt mini USB power supply (a suitable phone charger will do)
- 1 x HDMI monitor (your TV or computer monitor)
- 1 x USB keyboard
- 1 x Ethernet network cable
Prepare to install your operating system
Insert the micro SD card in your card reader.
If you are reusing an old SD card make sure it is fully formatted to remove any old files using the free tool at
http://sdcard.org
Install Raspbian on your Raspberry Pi
Download NOOBS (New Out Of the Box Software) from the Raspberry Pi website (
https://www.raspberrypi.org/downloads/). This is an easy operating system installation manager.
Open the .zip you downloaded and select all files, then just drag and drop them onto your SD card.
Insert the SD card in the Raspberry Pi then connect a monitor, keyboard and power cable.
Connecting the power will cause the Raspberry Pi to boot up and the green and red LEDs on the board should light up.
If the files are copied properly onto the SD card the green light will start flashing as the computer reads the data.
After
a few seconds you will see a window open on the monitor with a range of
operating systems to install - use the arrow keys on the keyboard to
choose Raspbian and hit ENTER to install.
N.B. If you have trouble
getting the NOOBS installation manager to work, you can also install
Raspbian by copying the disk image of the operating system onto your
micro SD card. Follow the instructions at
https://www.raspberrypi.org/downloads/ to do this.
Change the default password
Before
you go any further, make sure you change the default password, or
anyone who knows the default will be able to access your home network.
You can do this from the options screen you are shown the first time you boot up your Raspberry Pi after Raspbian is installed.
When you next reboot your Raspberry Pi the login will be "pi" and the password whatever you have set.
Give your Raspberry Pi a static IP address
The IP address is what tells devices where to find your Raspberry Pi on your home network.
Networks
usually issue a dynamic IP address, which can change each time you
power up the device. If you want to be able to consistently connect to
your Raspberry Pi from outside your home network you need to fix its IP
address so that it is always the same - a static IP address.
Connect your Raspberry Pi to your router with an Ethernet cable.
At command prompt type:
ifconfig
A bunch of information will come up and you need to note down what it says for your set against the following:
inet addr [Current IP Address]
bcast [Broadcast Range]
mask [Subnet Mask]
Next at the command prompt type:
sudo route -n
This tells you information about your router. Note down:
Gateway
Destination
You
now have all the information you need about your current IP set up and
can edit the network configuration file to make the IP static.
At command prompt type:
sudo nano /etc/network/interfaces
Look for the line that reads "iface eth0 inet dhcp" or "iface eth0 inet manual".
The
"dhcp" bit is requesting a dynamic IP or if your file says "manual" it
is a manual setting, so use the arrow keys on your keyboard to move the
cursor so you can delete this and replace it with "static".
Next
put your cursor at the end of this line and hit Enter, then add the
following lines directly below the line you just altered, filling the
[square brackets] with the information you just noted down.
address [your current IP address]
netmask [your subnet mask]
network [your destination]
broadcast [your broadcast range]
gateway [your gateway]
To
save the file press CTRL and X together, when prompted to save type "y"
and hit Enter to accept the file name without changing it.
At the command prompt type:
sudo reboot
Your Raspberry Pi will now restart with the new, static IP address.
Set up an easy control system
To
save switching around cables if you do not have a spare HDMI monitor
and keyboard you can download a free utility that lets you control your
Raspberry Pi through a pop up window on another computer.
This is called an SSH. The tool is called PuTTY (
j.mp/DLPutty).
Double
click the PuTTY.exe file you download and it opens a dialogue box where
you can enter the new static IP address you have given your Raspberry
Pi. The first time you do this it will ask you to confirm accessing the
device.
You can now login and do everything you need to through
this dialogue box on your computer, which means your Raspberry Pi never
needs a monitor or keyboard to keep running. This is known as running it
"headless".
Update your Raspberry Pi
One last piece of housekeeping to ensure you are running the latest software and drivers.
At command prompt type:
sudo apt-get update
Wait for the updates to finish downloading and then type:
sudo apt-get upgrade
Wait until the upgrade completes.
You are now ready to make your VPN
The
Raspbian operating system we just installed comes with OpenVPN ready to
unpack, which is the software we will be using to make our VPN.
At command prompt type:
sudo apt-get install openvpn
You will be asked to confirm your instruction then the software will be unpacked and installed.
Generating keys
Just
like the unique key that unlocks your front door, your VPN needs keys
generated to make sure that only authorised devices can connect to it.
OpenVPN comes with Easy_RSA, a simple package for using the RSA encryption method to generate your unique keys.
The
next series of commands need to be done in the root directory. You will
notice at the moment the command prompt sits in a directory labelled as
'pi@raspberrypi: ~ $'.
Typing "sudo" before a command tells the
operating system to execute the command in the root directory, but if
you want to save yourself some typing you can go ahead and type:
sudo -s
You will now see your command prompt sits at 'root@raspberrypi:'
Now, at the command type on one line:
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa
Make
sure you have spaces in the right places (before /usr and /etc). This
instruction copies all of the files from the easy-rsa 2.0 directory into
a directory in your openvpn installation.
N.B. You can copy
lines of text using right-click and then when you right click inside the
PuTTY window it should paste, saving you a lot of typing. Be aware
though, some formatting errors can occur when copying and pasting large
blocks of text so if you do not get the result you are expecting, resort
to typing the details in by hand.
Next type:
cd /etc/openvpn/easy-rsa
This changes the directory your command prompt sits at to your openvpn/easy-rsa directory.
You
now need to edit the text in the file we just copied over. Nano is a
simple text editor in Raspbian you are going to see a lot of over the
next few pages. To open the file inside this text editor type:
nano /etc/openvpn/easy-rsa/vars
In the text that opens find the line that begins: export EASY_RSA=
You need to move the cursor down to edit this line to read:
export EASY_RSA="/etc/openvpn/easy-rsa"
N.B.
Make sure you remove any extraneous speech marks as anything other than
the exact text above here will stop your keys from saving in the right
place.
Next move your cursor down until you see the line: export KEY_SIZE=1024
If
you want to be extra secure you can change the value here to 2048 bit
encryption, although the key you eventually build will take
significantly longer to generate. If you choose to do this edit that
line to read:
export KEY_SIZE=2048
Keep scrolling to
the end of the file and you will see a bunch of export parameters such
as Country, Province and City etc. You can choose to change these to set
new defaults (this will potentially save you some typing in various
later stages), but doing so will not affect the workings of your VPN.
Type CTRL and X then Y then ENTER to save this file.
Build your certificates
You
are now set up to build the certificates your VPN will use to grant
authority to devices you want to connect with. To open the easy-rsa
directory, at the command prompt type:
cd /etc/openvpn/easy-rsa
Next type:
source ./vars
This loads the vars document you edited earlier.
Next type:
./clean-all
This will remove any previous keys in the system.
Next type:
./build-ca
This
final line builds your certificate authority. The Raspberry Pi will now
ask you to complete some additional export values, like Country,
Province, City, Organisation etc. (if you changed these in the previous
stage you will see your own choices already set as default).
It
is not necessary for these values to be accurate so just hit Enter each
instance to use default value if you are feeling slack.
Name the server
Once
you have entered through the fields and returned to the command prompt
you need to name your server. Call it whatever you like but do not
forget it.
Type:
./build-key-server [ServerName]
… replacing [ServerName] with your choice of name.
You
will now be given some more fields to enter values. You can change
these or leave them as the defaults, but pay attention to three fields:
Common Name MUST be the server name you picked.
A challenge password? MUST be left blank.
Sign the certificate? [y/n] Obviously, you must type "y."
Finally when prompted with the question:
1 out of 1 certificate requests certified, commit? [y/n]
Type "y"
Build keys for each user
Your server is now set up and you need to build keys for all the devices you want to be able to connect.
You
can cut corners here and just build one key to use on all devices. Only
one device can connect using each key at a time though, so if you want
simultaneous connections you will need a different key for each one.
To assign a user a key type:
./build-key-pass [UserName]
…
substituting the [UserName] with your desired text - for example to
make a key to connect my android to the VPN I chose the name KateAndroid
You will get some more prompts now:
Enter PEM pass phrase
… choose a password you will remember! It asks you to input this twice to eliminate errors.
A challenge password? MUST be left blank.
Sign the certificate? [y/n]
Hit "y"
Next type:
cd keys
then (using my example username, which you should change for your own):
openssl rsa -in KateAndroid.key -des3 -out KateAndroid.3des.key
This last line adds an extra layer of encryption to make it harder for hackers to break in.
You will be asked to enter pass phrase for KateAndroid.key - this is the phrase you entered in the previous step.
You
will then be asked to enter and repeat a new PEM pass phrase for the
des3 key. I used the same pass phrase for both so you only have one to
remember. You will need the 3des.key pass phrase at the end of this
process when you import your files to your devices.
Repeat these steps for all the usernames you want to build a key for.
You have now created your "client certificates". Type:
cd ..
Generate the Diffie-Hellman key exchange.
This is the code that lets two entities with no prior knowledge of one another share secret keys over a public server. Type:
./build-dh
The
screen will slowly fill with dots as the key is built from random
numbers. It will take at least an hour if you upped your encryption to
2048-bit. If you left it at 1024-bit it could take as little as five
minutes.
Denial of Service (DoS) attack protection
OpenVPN
protects against this kind of attack by generating a static pre-shared
hash-based message authentication code (HMAC) key. This means the server
will not try to authenticate an access request if it does not detect
this key. To generate the static HMAC key type:
openvpn --genkey --secret keys/ta.key
N.B.
If you are using copy and paste it probably will not work on this line
as the double "-" seems not to translate in the same way if you do not
type it in.
Configuring your server
Now you
have created all the locks and keys you need to tell your Raspberry Pi
where you want to put the doors and who you want to give the keys to -
essentially instructing the OpenVPN which keys to use, where you are
going to be connecting from and which IP address and port to use.
To do this you must create a server configuration file. At command prompt type:
nano /etc/openvpn/server.conf
This opens an empty file.
Fill
it with this text, taking care to change the details where indicated
with a comment in # CAPS LOCK. (Placing a "#" in front of a sentence in
the code like this tells the system it is a comment and to ignore it
when building the program). Also when changing the YOUR SERVER NAME
sections I refer to the server name that was given to the
'build-key-server' command earlier on.
local 192.168.2.0 # SWAP THIS NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
dev tun
proto udp
port 1194
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/XX.crt # SWAP XX WITH YOUR SERVER NAME
key /etc/openvpn/easy-rsa/keys/XX.key # SWAP XX WITH YOUR SERVER NAME
dh /etc/openvpn/easy-rsa/keys/dh1024.pem # IF YOU CHANGED YOUR ENCRYPTION TO 2048, CHANGE THAT HERE
server 10.8.0.0 255.255.255.0
# server and remote endpoints
ifconfig 10.8.0.1 10.8.0.2
# Add route to Client routing table for the OpenVPN Server
push "route 10.8.0.1 255.255.255.255"
# Add route to Client routing table for the OpenVPN Subnet
push "route 10.8.0.0 255.255.255.0"
# your local subnet
push "route 192.168.0.10 255.255.255.0" # SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
# Set primary domain name server address to the SOHO Router
# If your router does not do DNS, you can use Google DNS 8.8.8.8
push "dhcp-option DNS 192.168.0.1" # THIS SHOULD ALREADY MATCH YOUR OWN ROUTER ADDRESS AND SHOULD NOT NEED TO BE CHANGED
# Override the Client default gateway by using 0.0.0.0/1 and
# 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
# overriding but not wiping out the original default gateway.
push "redirect-gateway def1"
client-to-client
duplicate-cn
keepalive 10 120
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
cipher AES-128-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log 20
log /var/log/openvpn.log
verb 1
Hit CTRL and X then Y and ENTER to save.
There
is one last edit to make in the server configuration files to make sure
your Raspberry Pi knows you want it to forward Internet traffic through
our new network.
Type:
nano /etc/sysctl.conf
Near the top it says, "Uncomment the next line to enable packet forwarding for IPv4."
You want to remove the "#" from the start of the next line to inform OpenVPN you want it to take that text into consideration.
The line should then read:
net.ipv4.ip_forward=1
Hit CTRL and X, then Y and ENTER to save.
Finally you need to action the change you just made in the sysctl.conf file. To do this type:
sysctl -p
You have now made a functioning server that can access the internet.
Pass through the firewall
Raspbian
has a built-in firewall that will block incoming connections, so we
need to tell it to allow traffic from OpenVPN to pass through.
To create a file that will run each time you start up your Raspberry Pi issuing this permission type:
nano /etc/firewall-openvpn-rules.sh
Inside this new file type:
#!/bin/sh
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 192.168.0.10
# SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
CTRL and X then Y and ENTER to save.
Newly
created files are not executable by default, so we will need to change
the permissions and ownership of this file you just created. To do this
type:
chmod 700 /etc/firewall-openvpn-rules.sh
then:
chown root /etc/firewall-openvpn-rules.sh
This
script gives OpenVPN permission to breach the firewall and we now need
to add it into the interfaces setup code so it runs on boot. Type:
nano /etc/network/interfaces
Find
the line that says: "iface eth0 inet static." We want to add a line
below the list of numbers that follow it. This line needs to be added at
an indent so hit TAB first:
pre-up /etc/firewall-openvpn-rules.sh
CTRL and X then Y and ENTER to save.
Finally, reboot your Raspberry Pi by typing:
Reboot
N.B. Each time you reboot your Raspberry Pi you will need to relaunch PuTTY to connect to it.
Ensure you have a static public IP address
We
have created locks and keys for devices to use to connect to your VPN,
but before we hand those keys out we need to tell them where to find the
front door. This is your public IP address, which should be kept a
secret as it identifies your location on the internet.
You can find out your public IP by asking Google. Just type "what's my IP address?" into the search box.
If
this address changes each time you log on you do not have a static IP
address so will need to use a dynamic domain name system (DDNS) service
to give yourself a domain name to put in place of the IP address.
There is a free service at
https://www.changeip.com Then on your Raspberry Pi, you need to run something called DDclient to update your DDNS registry automatically.
At the command prompt type:
sudo apt-get install ddclient
This
will launch a wizard for configuring ddclient. Don't worry too much
about what you enter here as we will be entering the config file
straight away.
To edit the DDClient configuration with the correct setting type:
sudo nano /etc/ddclient.conf
Every
service will have slightly different configuration, - if you are using
changeip.com this blog post will tell you how to edit your settings
successfully
https://blogdotmegajasondotcom.wordpress.com/2011/03/14/use-ddclient-with-changeip-com/
CTRL and X then Y and ENTER to save.
Finally, to set this program running type:
sudo ddclient
N.B. If you reboot your Raspberry Pi you'll need to type "
sudo ddclient" to start running it again.
Create profile scripts for the devices you want to connect
We
have created keys for clients (computers and devices) to use to connect
to your VPN, but we have not told the clients where to find the server,
how to connect, or which key to use.
If you created several
different client keys for each of the devices you want to grant access,
it would be a lot of trouble to generate a new configuration file for
each client from scratch.
Luckily Eric Jodoin of the SANS institute has written a script to generate them automatically.
First type:
sudo nano /etc/openvpn/easy-rsa/keys/Default.txt
Fill in the blank text file with the following:
client
dev tun
proto udp
remote [YOUR PUBLIC IP ADDRESS] 1194 #REPLACE YOUR DYNAMIC DNS VALUE FROM CHANGEIP.COM
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20
CTRL and X then Y and ENTER to save.
Next, to create the script that makes your profile keys type:
nano /etc/openvpn/easy-rsa/keys/MakeOVPN.sh
In this file you need to add the text that Jodoin wrote to create the script:
#!/bin/bash
# Default Variable Declarations
DEFAULT="Default.txt"
FILEEXT=".ovpn"
CRT=".crt"
KEY=".3des.key"
CA="ca.crt"
TA="ta.key"
#Ask for a Client name
echo "Please enter an existing Client Name:"
read NAME
#1st Verify that client's Public Key Exists
if [ ! -f $NAME$CRT ]; then
echo "[ERROR]: Client Public Key Certificate not found: $NAME$CRT"
exit
fi
echo "Client's cert found: $NAME$CR"
#Then, verify that there is a private key for that client
if [ ! -f $NAME$KEY ]; then
echo "[ERROR]: Client 3des Private Key not found: $NAME$KEY"
exit
fi
echo "Client's Private Key found: $NAME$KEY"
#Confirm the CA public key exists
if [ ! -f $CA ]; then
echo "[ERROR]: CA Public Key not found: $CA"
exit
fi
echo "CA public Key found: $CA"
#Confirm the tls-auth ta key file exists
if [ ! -f $TA ]; then
echo "[ERROR]: tls-auth Key not found: $TA"
exit
fi
echo "tls-auth Private Key found: $TA"
#Ready to make a new .opvn file - Start by populating with the default file
cat $DEFAULT > $NAME$FILEEXT
#Now, append the CA Public Cert
echo "<ca>" >> $NAME$FILEEXT
cat $CA >> $NAME$FILEEXT
echo "</ca>" >> $NAME$FILEEXT
#Next append the client Public Cert
echo "<cert>" >> $NAME$FILEEXT
cat $NAME$CRT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $NAME$FILEEXT
echo "</cert>" >> $NAME$FILEEXT
#Then, append the client Private Key
echo "<key>" >> $NAME$FILEEXT
cat $NAME$KEY >> $NAME$FILEEXT
echo "</key>" >> $NAME$FILEEXT
#Finally, append the TA Private Key
echo "<tls-auth>" >> $NAME$FILEEXT
cat $TA >> $NAME$FILEEXT
echo "</tls-auth>" >> $NAME$FILEEXT
echo "Done! $NAME$FILEEXT Successfully Created."
#Script written by Eric Jodoin
\ No newline at end of file
CTRL and X then Y and ENTER to save.
N.B.
I was not able to successfully copy and paste the entire script
accurately in one go, but taking it one section at a time worked no
problem).
Next you need to give this script permission to run. Type:
cd /etc/openvpn/easy-rsa/keys/
The to give it root privileges type:
chmod 700 MakeOVPN.sh
Finally, execute the script with:
./MakeOVPN.sh
As
it runs, it will ask you to input the usernames names of the clients
for you generated keys for earlier (in my case KateAndroid). Type that
when prompted and you should see the line:
Done! KateAndroid.ovpn Successfully Created.
Repeat this step for each additional username you added client.
Export your client keys for use on the connecting devices
You
now need to copy those keys onto the devices you want to use them. If
you are using PuTTY on a Windows machine you can use a software package
called WinSCP to do this. For Mac, try Fugu.
First, to grant yourself read/write access to the folder at the command prompt type:
chmod 777 /etc/openvpn
chmod 777 /etc/openvpn/easy-rsa
chmod 777 /etc/openvpn/easy-rsa/keys
chmod 777 /etc/openvpn/easy-rsa/keys/[ClientName].ovpn
Be sure to undo this when you're done copying files by typing:
chmod 600 /etc/openvpn
and repeating for each step with the chmod 600 command, which removes read/write access again.
You
can now launch the software you are using to copy the files off your
Raspberry Pi to navigate to the openvpn folder and copy the files
labelled "KateAndroid.ovpn" etc.
You can also open the command prompt on the machine in your network you would like to copy the files to and type:
scp pi@[ip-address-of-your-pi]:/etc/openvpn/easy-rsa/keys/[ClientName].ovpn [ClientName].ovpn
Install the OpenVPN Connect app on your device
You
are now ready to download and install the OpenVPN Connect app on your
Android or iPhone - they are available through the stores as a free
download. You will need to import the profile keys you just made as the
final piece of the VPN connection puzzle.
When prompted for a pass phrase here it is the 3des.key one you will need to enter.
For iOS
Use
iTunes to add the .ovpn file to the OpenVPN Connect app. When you
launch the app on your phone you will now get the option of installing
that profile and making the connection.
For Android
Connect
your android device to your computer with a USB cable. Navigate to the
Downloads folder on your handset and paste the .ovpn file there.
When
you launch the app on your handset you can now tap the menu dropdown in
the top right corner, select Import>Import profile from SD card then
navigate to the downloads folder and choose to import the file and make
the connection.
One more thing
After all this is done, if
your phone still can't connect to the OpenVPN server you might need to
adjust the firewall on your router to do port-forwarding of port 1194 to
the Raspberry Pi. You'll need to follow the instructions from your ISP
to access the router and complete this step.
THANKS TO : https://twitter.com/zoodor for debugging this guide.