I will describe the method I used to permanently have a connection with NordVPN on my Vero4K, but this should work on any OSMC box.
This method determines the best reachable NordVPN server in or near your country and then connects with it during startup of your machine. When the tunnel is closed for any reason, it will be automatically re-connected, again by first determining the best reachable NordVPN server available. NordVPN’s DNS servers are used by default and DNS queries are sent through the VPN Tunnel to prevent DNS leaking.
All this functionality is actually provided by openpyn and this how-to will describe how to install it on OSMC.
In my opinion, this is the most family-friendly solution, as the VPN is managed completely automatically and transparantly without the need for users to manually start tinkering in an openvpn manager inside Kodi. Only disadvantage that I see is that you also don’t have a status of the connection inside Kodi…
Installation
- Open a SSH connection to your OSMC box
- Install dependencies
sudo apt install openvpn unzip wget python3-setuptools python3-pip psmisc
- Install python wheel, required for openpyn install
sudo python3 -m pip install wheel --upgrade
- Install openpyn:
sudo python3 -m pip install openpyn --upgrade
- Execute the openpyn initialization. This will request your NordVPN credentials and store them, download the ovpn configfiles and install a systemd service):
sudo openpyn --init
- For fast ping tests of the NordVPN servers you will require a version of ping that supports -n and -i:
sudo apt install iputils-ping
- Enable the system service to start on boot:
sudo systemctl enable openpyn
- Start the VPN:
sudo systemctl start openpyn
Support for downloading torrents
However, if you will be downloading torrents on your OSMC box, you will need to connect to a NordVPN server that actually allows that to prevent being kicked from the server and losing your connection all the time:
Edit /etc/systemd/system/openpyn.service
and change the line
ExecStart=/usr/local/bin/openpyn --silent
into
ExecStart=/usr/local/bin/openpyn --p2p --silent
Disable NordVPN DNS
Openpyn also automatically will start using the NordVPN DNS servers, through the tunnel, to prevent DNS leaking. This is a good thing, and you should skip this step if you don’t have an internal DNS server in your network. However if you do have an internal DNS server in your network, you will no longer be able to resolve host-names of your internal network.
In that case, make sure your internal DNS servers forwards external requests to NordVPN DNS servers, preferable also through a NordVPN tunnel, set up on your DNS server itself and change /etc/systemd/system/openpyn.service
to include the --skip-dns-patch
option to prevent openpyn to manage your DNS resolving:
change
ExecStart=/usr/local/bin/openpyn --silent
into
ExecStart=/usr/local/bin/openpyn be --skip-dns-patch --silent
(of-course, if you already added the --p2p
option, you should also leave that option there)
KILLSWITCH
Openpyn also has experimental support for a killswitch, meaning that it won’t allow any traffic going out in the case the tunnel goes down. This can be enabled by adding the -f
option to the ExecStart
line. I don’t use this option myself, so I cannot give any more details about it. See GitHub - jotyGill/openpyn-nordvpn: Easily connect to and switch between, OpenVPN servers hosted by NordVPN on Linux (+patch leakes) for more information about the kill switch and how to allow a few ports to be accessed from outside (kodi webinterface etc… )
Add extra static routes
At this point, all internet traffic should go through the tunnel and any traffic to your internal network (NAS? etc… ) should still stay internal. This is, if you only have one subnet, which is the same as your OSMC box is sitting in.
If you however have multiple subnets (for example a different subnet for wired and for wireless) you will need to add an extra static route so that traffic for the other subnet is not sent down through the tunnel to be lost forever…
I did this by adding an ExecStartPost
and ExecStopPost
entry in the /etc/systemd/system/openpyn.service
-file:
ExecStart=/usr/local/bin/openpyn be --silent
ExecStartPost=/sbin/ip route add 192.168.1.0/24 via 192.168.0.1 dev eth0
ExecStop=/usr/local/bin/openpyn --kill
ExecStopPost=/sbin/ip route del 192.168.1.0/24 via 192.168.0.1 dev eth0
Ofcourse:
- change
192.168.1.0/24
into the required subnet, -
192.168.0.1
into your default gateway and - change
eth0
into the interface your network is connected at.
Netflix
Now with Kodi 18, many may want to watch Netflix on Kodi. However Netflix actively tries to block VPN usage.
Netflix through VPN
Disclaimer: I don’t have a NordVPN netflix-compatible server in my country, so I can’t test this for myself. Also Netflix is actively trying to block all VPN usage, so even those “Netflix-compatible” servers may not work. And on top of that, according to this issue: Ca'nt connect with a VPN- AGAIN. · Issue #181 · CastagnaIT/plugin.video.netflix · GitHub it may even not work at all… But I include this section for completeness, let me know in the comments if you manage to get this working :
NordVPN provides Netflix-compatible VPN servers to use. To select such a server using openpyn, you can add the option --netflix
to the openpyn
command in /etc/systemd/system/openpyn.service
.
NordVPN however does not have those servers in every country. You can check this with:
openpyn -l <countrycode> --netflix
.
Netflix bypassing VPN
If you don’t have such a server in your country, and you choose a server in another country, Netflix will think you are watching from within that country, and the content may be different.
If you don’t want that, or the netflix-compatible servers just don’t work, you can bypass the VPN for Netflix by adding static routes to your default gateway for all Netflix ip-ranges and additionally for all Amazon AWS ip ranges as Netflix is running many services in AWS.
As both have many ip-ranges, I made this script /usr/local/bin/bypass_vpn_static_routes.sh
to automate this:
#!/bin/bash
gateway=192.168.0.1
interface=eth0
netflix_ranges=$(curl https://ipinfo.io/AS2906 | grep -e "^ *[0-9]\{2,3\}\.[0-9]\{2,3\}\.[0-9]\{2,3\}\.0/24" | tr -d " ")
aws_ranges=$(curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | grep ip_prefix | cut -d"\"" -f4 | sort -u)
case "$1" in
start)
# Routes to bypass VPN for Netflix ranges
for range in $netflix_ranges; do
/sbin/ip route add $range via $gateway dev $interface
done
# Routes to bypass Amazon AWS ranges, required for Netflix
for range in $aws_ranges; do
/sbin/ip route add $range via $gateway dev $interface
done
;;
stop)
# Routes to bypass VPN for Netflix ranges
for range in $netflix_ranges; do
/sbin/ip route del $range via $gateway dev $interface
done
# Routes to bypass Amazon AWS ranges, required for Netflix
for range in $aws_ranges; do
/sbin/ip route del $range via $gateway dev $interface
done
;;
esac
which I call from the ExecStartPost
and ExecStopPost
entry in the /etc/systemd/system/openpyn.service
-file (you can also add your own static routes to this script instead of directly in the systemd unit-file):
ExecStart=/usr/local/bin/openpyn be --skip-dns-patch --p2p
ExecStartPost=/usr/local/bin/bypass_vpn_static_routes.sh start
ExecStop=/usr/local/bin/openpyn --kill
ExecStopPost=/usr/local/bin/bypass_vpn_static_routes.sh stop
This currently adds arround 1170 rules to bypass the VPN.
Be aware however, that we can’t determine which IP’s or ranges in AWS are actually used by Netflix (as this also constantly changes by the design of the AWS cloud services). As a result, any AWS cloud service will now bypass the VPN…
If anyone has a suggestion on how to improve this? Idea’s are temporarly disabling VPN when starting Netflix, or only adding those routes when starting Netflix and removing them again afterwards. But I don’t know how I would make kodi do this…
Check VPN status and logging
You can check the IP you are using now with curl ipinfo.io/ip
, which should be different than the IP your ISP gave you.
The status of the VPN set up by openpyn can be checked using systemctl status openpyn
and the openvpn logging can be found by running journalctl -u openpyn
.
Updating VPN config-files
Once in a while you probably will need to update the NordVPN ovpn configfiles. This can be done with openpyn --update
.
This could be added to a crontab, however crontab also is not installed by default on an OSMC. You are free to experiment with that
EDIT 2019-12-18: Added disclaimer to ‘Netflix through VPN’-instructions
EDIT 2019-06-25: Added Netflix instructions
EDIT 2018-10-11: Added psmisc dependency and tip to check vpn status