Raspberry Pi VPN Gateway - NordVPN

18K1332

Intro: Raspberry Pi VPN Gateway - NordVPN

I wrote an Instructable about using a Raspberry Pi as a VPN gateway. It was based on Tunnel Bear and I wrote several follow ups on my blog as well. I have recieved several questions specific to NordVPN so I put together this short Instructable just for NordVPN.

For additional information around using the Raspberry Pi as a VPN Gateway read my last Instructable on the subject.

For more interesting projects visit my blog https://www.hackviking.com

STEP 1: Install the Raspberry Pi

For implementations like this I use the Raspbian Lite operating system. Since I have no need for the GUI at all. You can get the latest release here.

I use Win32DiskImager to load the .img file on the SD-card for the Raspberry Pi. Then add a blank text file to the partition labeled boot just named ssh. That will enable ssh when the Raspberry Pi boots.

Once the Raspberry Pi have booted I look in my routers DHCP list to get the IP-address and then connect over SSH with Putty. Standard username and password are pi/raspberry

Once connected I run the raspi-config tool to change the basic settings.

sudo raspi-config

The most importent things to take care of in this config is:

  • Expand file system
  • Change password

You can also change the hostname of your Raspberry Pi if you like. My DHCP have very long leases and I can also reserve a specific address. If you don't have that ability you have to configure the Raspberry Pi to use a static IP-address. Since other devices will use this as there default gateway it is important that it keeps using the same IP-address. Here is a post I wrote about setting a static IP in Raspbian Jessie.

Then we need to upgrade everything to the latest version:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

STEP 2: Install OpenVPN

Lets set up OpenVPN on the Raspberry Pi.

sudo apt-get install openvpn

Make sure the service starts properly

sudo systemctl enable openvpn

Now we can configure the NordVPN specific things. They published a tutorial them self's on setting it up on Raspberry Pi but targeted towards users running it on command. They still make it very easy to use for an automated setup like ours with supplying proper configuration files with the certificates included.

First we need to download all the configuration files.

cd /etc/openvpn
sudo wget https://nordvpn.com/api/files/zip
sudo unzip zip
sudo rm zip

Now we have all the configuration files for the different exit servers that they offer. The filenames are constructed as {country+number}.nordvpn.com.{protocol}1194.ovpn. Check the server list on NordVPN to select the proper server. For this example I am using us1306.nordvpn.com.udp1194.

First we need to store our NordVPN credentials in a file.

sudo nano /etc/openvpn/nordvpn_auth.txt

Add your username and password on separate lines like this

username
password

Use CTRL + O to save the file and CTRL + X to exit nano. Now we need to secure this file since it contains our credentials.

chmod 600 /etc/openvpn/nordvpn_auth.txt

OpenVPN only autostart tunnel configs that end in .conf so we need to rename our selected config file.

sudo mv /etc/openvpn/us1306.nordvpn.com.udp1194.ovpn /etc/openvpn/us1306.nordvpn.com.udp1194.conf

Then we need to edit it to take care of the credentials.

sudo nano /etc/openvpn/us1306.nordvpn.com.udp1194.conf

Locate the line auth-user-pass which signals to OpenVPN to ask for your credentials and replace that with this:

auth-user-pass /etc/openvpn/nordvpn_auth.txt

Once again we use CTRL + O to save and CTRL + X to exit nano. Then restart OpenVPN to test the connection.

sudo service openvpn restart

Now you can check that you have a new public IP by running this.

wget  http://ipinfo.io/ip  -qO -

STEP 3: 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.

STEP 4: 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.

STEP 5: Conclusion

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. In my case both my Kodi media centers (one bedroom and one livingroom) uses this connection so I can stream my Swedish play channels. Of course there are other things you can use this for as well.

Just keep in mind that depending on the VPN supplier you chose and the speed of your internet connection there might be slow performance. If you have any questions or want me to clarify anything let me know in the comments! For more tech post please visit my blogg Hackviking!

19 Comments

Great instructions, easy to follow and has worked well. I am trying to connect my smart tv to a VPN through my Raspi, but am unsure how to find the correct IP settings to enter onto the TV

How do I find the correct subnet mask / gateway / DNS server details to enter?
thanks
Hey!
Thanks for the great tutorial! I have a question. I face the problem that some websites realize that i am using VPN so I cannot access them. Is there a simple way to add "exceptions" to this setup?
Thank You!
Thanks for this good tutorial. One thing today is that you won't have to install openvpn because nordvpn is providing their own software to be installed on raspberry.

In order to install it just go with :
sh <(curl -sSf https://downloads.nordcdn.com/apps/linux/install.sh)
(reference :
https://support.nordvpn.com/Connectivity/Linux/132...
)
Once installed, login to your nordvpn account:
root@raspiGw:/home/pi# nordvpn login (provide your nordvpn credentials)

and then whitelist SSH, else your SSH connection to raspberry will be cut when you will create the tunnel:
root@raspiGw:/home/pi# nordvpn whitelist add port 22

In order to connect to a gateway, just run e.g :
root@raspiGw:/home/pi# nordvpn connect United_States

When you will connect with the nordvpn client, this will automatically inject rules into iptables but you can keep the filtering rules in the tutorial if you want. It will not add the masquerading rule so you should definetely keep it, else nothing will work.
In my case I had to add an additional masquerading rule on wlan0 in order to keep the connection to the internet when nordvpn was disconnected:
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE


this is a great tutorial. I get the following error when I try to enable NAT or do anything with the ipdtables commands.

iptables/1.8.2 Failed to initialize nft: Protocol not supported
Hi, Great read!

Do you have any resources about the programs your using. Where can I read more about NATs, iptables, etc. would really want some more in depth information about all of this.

If you would have any links, videos, references I'd love to recieve them!

This is just fantastic! I was wondering how this could be achieved and your instructable saved me after many many hours of frustration and floundering around the internet.

Questions
1. out of curiosity, are the iptables rules just for security or do they "make the magic happen"
2. if I now want to set up an "outside" vpn using say pivpn - would i.
a) set the vpn gateway up (as in your article) on pi A. set up pivpn on pi B and have the gateway specified on pi B as pi A (i.e. the vpn gateway) i.e. say openvpn connect app on phone->pi B->pi A->nord
b) set this up on the same pi as my vpn gateway. would I have to add in additional ip tables rules or anything else e.g. routing?

Thanks - maybe my second question is a bit much and would need another instructable!

Cheers
Exactly the article I was looking for! However, when I try to test using my RPi's static LAN IP as the gateway address on a test machine, it cannot connect out to the internet at all. Running the ipinfo command from the RPi shows that a new IP has been assigned. How do you recommend I get around this?
Try to change the DNS on your laptop/device to 8.8.8.8
Thanks for the response. I tried that and even flushed the local DNS, but still not able to get an internet connection through a client.
I am also an expat that wants to connect his smart TV to "home". Following your instructions it all went well and I can see that I get the Dutch NordVPN server wit the test command.

Do I only change gateway (windows laptop) or router (MacBook) ? It drops any internet connection when I set my local ip for the device and raspberry as gateway/router.

Update:
I had to change my DNS server to 8.8.8.8 on the client and it works great!
Another issue I had was to use VNC (I installed the GUI version). Just needed to add:
sudo iptables -A INPUT -i eth0 -p tcp --dport 5900 -j ACCEPT
But then the update for persistent ip tables did not work for reboots. The solution for that is to navigate to nano /etc/iptables/rules.v4 and manually insert the rule just under the SSH rule. Just change the port number.
I followed this guide and it works perfectly! Thank you for this. My devices are now redirected through the pi 3 and are now secured.

I have one question - if you ever want to change the NORDVPN server I.e. America instead of the UK for example how do you go about doing that? Do I just need to run these commands again without following the rest of the guide below it?

sudo mv /etc/openvpn/us1306.nordvpn.com.udp1194.ovpn /etc/openvpn/us1306.nordvpn.com.udp1194.conf

sudo nano /etc/openvpn/us1306.nordvpn.com.udp1194.conf

sudo service openvpn restart

Thanks

Thanks for this very helpful guide! I found that when I started openvpn manually, the tunnel would automatically establish. However for openvpn to automatically start and set up the tunnel after booting the RPi, I found that instead of

$ sudo systemctl enable openvpn

I had to use

$ sudo systemctl enable openvpn@<config file>

e.g.

$ sudo systemctl enable openvpn@ch-nl1.nordvpn.com.tcp443

to store subsequent iptable changes I did `sudo netfilter-persistent save`

may be I get it wrong but `sudo systemctl enable netfilter-persistent` does not save changes

Many thanks for your instructions, it works!

I did have one question that has been driving me up the wall for a couple of weeks now. I am using a second Raspberrypi with pi-hole and would like to have the ad blockage working with the gateway tunnel. Seems that I can only adblock the eth0 interface but not the tun0. Would it be possible to use your instructions for upnp to forward the pi-hole?

hey, I am unable to resolve my local host names, even by adding them to /etc/hosts

Any idea? I would like to reach my router by not having to type in the ip address on my browser

I dunno what this guy means by having pictures for a simple command line instruction. These are great and work perfectly, dont change a thing

Hello there!

We're glad you want to share something with the Instructables community!

And we’re here to help you out.

Due to some recent changes on the site, we are no longer able to publish stand-alone videos and other forms of incomplete posts. In order to be published live on the site, Instructables must consist of the following things:

- Multiple steps showing how you made your project

- Written instructions in each step

- Your own original images

Beyond making your Instructable simply publishable, this guide (https://www.instructables.com/id/How-to-Create-a-Feature-Worthy-Instructable/) explains what is required to have your Instructables featured by our site editors. It’s very helpful, and definitely worth checking out.

We would love to review your project again after you have made the necessary edits, and we will publish your project if it is eligible.

If you have any questions, please feel free to ask right here or send us an email at service@instructables.com.

Best,

Instructables Community Manager

In what way is this incomplete? It's a step by step guide how to setup a Raspberry Pi as VPN gateway using NordVPN. The one I wrote for Tunnel Bear have reached over 20k views.

In order to be published an Instructable needs to have pictures. I understand that the nature of this project doesn't involve a lot of visuals. But it needs to at least have something original to use as a thumbnail image.