This page looks best with JavaScript enabled

Setting up OpenVPN on raspberry pi

 ·   ·  β˜• 6 min read

    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:


    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 -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


    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

    Ohidur Rahman Bappy
    Ohidur Rahman Bappy
    πŸ“šLearner 🐍 Developer