Update everything
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
Install OpenVPN
Now we need to install OpenVPN on the Raspberry Pi.
sudo apt-get install openvpn
Then we need to make sure the service starts properly.
sudo systemctl enable openvpn
When the installation is finished we need to copy the OpenVPN config files and certificates to the box. This will be provided to you by your VPN provider.
The file contains the certificate files and a .opvn configuration file for each country you can tunnel to. You need all the certificate files and the .opvn configuration file for the country of your choice. Unzip the files needed and the use winscp to upload the files to your Raspberry Pi. The same username/password as used for SSH will bring you to /home/pi, just drop the files there.
Then we go back to the SSH terminal and move the files over to the OpenVPN folder. First command is just to make sure we are in the /home/pi folder.
cd /home/pi
sudo mv * /etc/openvpn/
Now we need to do some modifications to the files. First we need to rename the configuration file from .ovpn to .conf. Any file ending in .conf in the /etc/openvpn folder will automatically start when the OpenVPN daemon is started. First we need to get into that directory.
cd /etc/openvpn
Then we change the name of the config file. You can name it anything you want as long as it ends in .conf. I use vpn.conf
sudo mv *.ovpn vpn.conf
Then we need an authentication file containing the username and password used for the VPN tunnel. Open up a text editor and write the username and password on separate lines. We will call this file auth.txt.
sudo nano auth.txt
The content should be like this example:
username
password
Then use CTRL + O to write to the file and the CTRL + X to exit the nano text editor. We also need to protect the auth.txt file containing our credentials.
sudo chmod 600 /etc/openvpn/auth.txt
Then we need to edit the config file to make sure all paths are correct and add a reference to the newly created auth.txt file.
sudo nano vpn.conf
The lines that needs to be changed are the ones referring to other files, they need to be absolute paths. In this example this is what we are looking for:
ca CACertificate.crt
cert UserCertificate.crt
key PrivateKey.key
We change them to absolut paths like this:
ca /etc/openvpn/CACertificate.crt
cert /etc/openvpn/UserCertificate.crt
key /etc/openvpn/PrivateKey.key
Then at the end of the file we add a reference to the auth.txt file, like this:
auth-user-pass /etc/openvpn/auth.txt
Once again we use CTRL + O to save the file and then CTRL + X to exit nano. Now we can restart the OpenVPN daemon and see that the tunnel is working.
sudo service openvpn restart
If you run the command ifconfig you should see a tun0 adapter in addition to your eth0 and lo adapters if the tunnel is up. You can also run the command this command to check your public IP:
wget http://ipinfo.io/ip -qO -
If you are having issues getting the tunnel up first try rebooting your Raspberry Pi and then double check the configuration for errors.
Setup Routing
Now we need to enable IP forwarding. It enables the network traffic to flow in from one of the network interfaces and out the other. Essentially creating a router.
sudo /bin/su -c "echo -e '\n#Enable IP Routing\nnet.ipv4.ip_forward = 1' > /etc/sysctl.conf"
If you run sudo sysctl -p you should see this printed on the screen:
net.ipv4.ip_forward = 1
Now routing is enabled and traffic can go through the Raspberry Pi, over the tunnel and out on the internet.
Setup Firewall and NAT
Since we will have several clients on the inside accessing the internet over one public IP address we need to use NAT. It stands for network address translation and will keep track on which client requested what traffic when the information returns over the tunnel. We also need to setup some security around the Raspberry Pi it self and the tunnel.
sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
Enabling NAT.
sudo iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
Allowing any traffic from eth0 (internal) to go over tun0 (tunnel).
sudo iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
Allowing traffic from tun0 (tunnel) to go back over eth0 (internal). Since we specify the state RELATED,ESTABLISHED it will be limited to connection initiated from the internal network. Blocking external traffic trying to initiate a new connection.
sudo iptables -A INPUT -i lo -j ACCEPT
Allowing the Raspberry Pi’s own loopback traffic.
sudo iptables -A INPUT -i eth0 -p icmp -j ACCEPT
Allowing computers on the local network to ping the Raspberry Pi.
sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
Allowing SSH from the internal network.
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Allowing all traffic initiated by the Raspberry Pi to return. This is the same state principal as earlier.
sudo iptables -P FORWARD DROP
sudo iptables -P INPUT DROP
sudo iptables -L
If traffic doesn’t match any of the the rules specified it will be dropped.
sudo apt-get install iptables-persistent
sudo systemctl enable netfilter-persistent
First line installs a peace of code that makes the iptable rules we just created persistent between reboots. The second one saves the rules after you changed them. This time it’s enough to run the first one. If you change the rules run the second one to save. Iptable rules are in effect as soon as you add them if you mess up and lose access just reboot and the ones not already saved will revert.
Configure on client device
Now you can use this tunnel from any device or computer on the same network. Just change the default gateway to whatever IP-address your Raspberry Pi has
Since I was serving a server on port 80,9090 and dns on port 53
So added few more rules to iptables
sudo iptables -A INPUT -i eth0 -p tcp --dport 9090 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --dport 53 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p udp --dport 53 -j ACCEPT
or
sudo iptables -A INPUT -i eth0 -p tcp --dport 1:65535 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p udp --dport 1:65535 -j ACCEPT
And saved with persistent
sudo iptables-save > /etc/sysconfig/iptables
redirecting all the port to 10000
iptables -A PREROUTING -t nat -i eth0 -p tcp –dport 1:65535 -j DNAT –to-destination 192.168.1.10:10000