Being a long-time user of OpenVPN and generally liking the security approach of ProtonMail I decided to take ProtonVPN for a test drive. These are my experiences using their Linux CLI and a persistent systemd connection, Mac OSX briefly and IOS. This Swiss-based VPN service provides a free tier and reasonably priced paid plans for more benefits.
Why Would I want a VPN?
This lifehacker article does a much better job of explaining this than me, but let me summarize the basics:
- The internet is really aggressive, it helps you ensure all your traffic is encrypted and free from snooping or more malicious eavesdropping to steal your data.
- You value your privacy and may not be able to trust all public networks
- You are in a potentially oppressive country where it could be dangerous to use the internet due to censorship and/or retaliation against free speech.
- The Netflix/some-other-web-service selection SUUUCKS from where you are traveling (or isn’t available).
What is ProtonVPN
ProtonVPN is an OpenVPN-based hosted service offered by the same folks who created ProtonMail (end-to-end encrypted email service) based in Switzerland. You can use it via bog-standard OpenVPN client or use their multi-platform application (Windows, Mac OSX, Linux, Iphone IOS, Android).
Unlike a lot of other hosted VPN services their free tier is truly free with some reasonably imposed limits you’d expect (3 Country locations only for endpoints, more QoS’d speeds and only 1 connection at a time, no P2P traffic) but otherwise no bandwidth limitations that I was able to see.
Being a fan of Swiss-based companies like ProtonMail and pCloud already and being a fairly frequent traveler just running my own OpenVPN server from home doesn’t always suffice due to my location(s) so I decided to take ProtonVPN for a test drive.
This is a personal review of ProtonVPN’s hosted OpenVPN solution, nothing stops you from running your own DIY OpenVPN service on your home system for both privacy/security as well as access to home network resources which isn’t covered here.
Installation on Linux
After making an account you can download the Linux CLI client or simply integrate the settings (obtained on your account page) into OpenVPN using NetworkManager/nmcli or just use the normal openvpn command(s) if you’re used to those.
To try something different I’m going to cover using the official ProtonVPN Linux CLI tool. As of typing this their instructions page (and staff responses to questions/comments) is full of more info than this post hopes to cover so that’s worth a look. You should also consult that page for options beyond installation and configuration that we’ll cover here.
Note: Your ProtonVPN username/password is NOT for the Linux CLI tool, it’s for the other official GUI applications (OSX, Windows, IOS, Android). The credentials you’ll be using shortly will instead be the same as the ones you’d use in OpenVPN.
As you can see above this is spelled out pretty well in the account screen but I managed to screw it up by not really checking as I was trying to setup the client where it asks for your login credentials.
Note: I am running the below commands as the root user, it is possible to instead use your local non-privileged user instead by passing environment variables into the Systemd service being setup (see comments on this post that reader @cohen has provided if you want to do this).
Download the CLI Tool
First download the CLI tool, I just cloned the Github repository for it:
git clone https://github.com/ProtonVPN/protonvpn-cli
You’re also going to need openvpn and dialog, I’ll leave that up to you as to how to install it. For me on Fedora it was simply:
dnf install openvpn dialog -y
Run the Setup
Next you’re going to run the CLI setup which will generate certificates/keys, add your username/password (OpenVPN credentials from above) to a static file where it can be fed into openvpn and setup some local configuration values. I did all this as the root user and kept it in roots home directory.
cd protonvpn-cli/ ./protonvpn-cli.sh -init
Note: On EL-based distributions (CentOS, RHEL, Fedora) there is no resolvconf package available, that’s ok – it’s been changed to a bash function that is integrated when you choose Y during the installation questions. All it does is provide a way for protonvpn-cli to update your DNS servers anyway.
# ./protonvpn-cli.sh -init [!] Error: update-resolv-conf is not installed. Would you like protonvpn-cli to install update-resolv-conf? (y/N): y
If all goes well you should now be prompted with the setup part. Use your OpenVPN credentials above and for the free account choose option 1 here.
Enter OpenVPN username: testuser Enter OpenVPN password: [.] ProtonVPN Plans: 1) Free 2) Basic 3) Plus 4) Visionary Enter Your ProtonVPN plan ID: 1
It will ask you if you want to use a custom DNS server, I chose yes here because I’m using Pi-hole as my DNS server at home for further privacy and security. You should go with the defaults here unless you’re doing something purposefully different.
Lastly it will prompt you if you want to decrease OpenVPN privileges, this sounds like a good thing to enable. I chose Y here (default). It demotes the openvpn service user to the nobody user.
Connecting to ProtonVPN with Linux CLI
Now you should be ready to connect to ProtonVPN via the CLI to test things out.
You’ll be prompted with a list of servers to connect to and then protocol (udp/tcp). Once that proceeds you should be connected.
Connecting... [$] Connected! [#] New IP: 185.244.XXX.XX
Great, if all goes well you can install symlinks to /usr/local/bin/pvpn which we’ll use for setting up a persistent, service-based connection.
Now you should have a pvpn binary (symlink) in your $PATH.
# ls -ln /usr/local/bin/pvpn lrwxrwxrwx. 1 0 0 28 Dec 27 12:52 /usr/local/bin/pvpn -> /usr/local/bin/protonvpn-cli # which pvpn /usr/local/bin/pvpn
Setting up a Persistent ProtonVPN Service
Nothing stops you from just using good old NetworkManager or nmcli or even the regular openvpn command line but I like the idea of using systemd to provide connection persistence. The ProtonVPN CLI also provides the -f option which chooses the fastest connection to you.
This can be done in a few easy steps, first create the systemd service itself:
cat > /etc/systemd/system/protonvpn.service <<EOF [Unit] Description=ProtonVPN After=syslog.target network-online.target Wants=network-online.target [Service] Type=forking ExecStart=/usr/bin/pvpn -f ExecStop=/usr/bin/pvpn -d ExecReload=/usr/bin/pvpn -f Restart=always [Install] WantedBy=multi-user.target EOF
Now issue a daemon reload
Now you can either set the service to start automatically on boot as you choose (via systemctl enable protonvpn) or simply on-demand. The above Restart=always should ensure that if it fails it’ll get restarted automatically.
Let’s start it and see what happens.
systemctl start protonvpn systemctl status protonvpn
All looks good.
● protonvpn.service - ProtonVPN Loaded: loaded (/etc/systemd/system/protonvpn.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2018-12-27 13:00:58 GMT; 14s ago Process: 3753 ExecStart=/usr/bin/pvpn -f (code=exited, status=0/SUCCESS) Main PID: 3890 (openvpn) CGroup: /system.slice/protonvpn.service └─3890 openvpn --daemon --config /root/.protonvpn-cli/protonvpn_openvpn Dec 27 13:00:50 host-01 systemd: Starting ProtonVPN... Dec 27 13:00:50 host-01 pvpn: Fetching ProtonVPN servers... Dec 27 13:00:52 host-01 pvpn: Connecting... Dec 27 13:00:58 host-01 pvpn: [$] Connected! Dec 27 13:00:58 host-01 pvpn: [#] New IP: 89.XX.XXX.XXX
Cool, Let’s Break It!
Ok, let’s manually kill the openvpn process and see if it restarts itself.
# ps -ef | grep openvpn nobody 3890 1 0 13:00 ? 00:00:00 openvpn --daemon --config
Now let’s abruptly kill the openvpn PID.
# kill 3890 # systemctl status protonvpn
Now we see a new IP address (you’ll have to trust me on this) as well as new connection log timestamps indicating a reconnection.
Dec 27 13:02:19 host-01 systemd: Starting ProtonVPN... Dec 27 13:02:20 host-01 pvpn: Fetching ProtonVPN servers... Dec 27 13:02:21 host-01 pvpn: Connecting... Dec 27 13:02:27 host-01 pvpn: [$] Connected! Dec 27 13:02:27 host-01 pvpn: [#] New IP: 89.XX.XXX.XXX
Great, everything restarted as it should. This would be especially useful for an always-connected machine but also useful if you just wanted connection persistence in general.
The free tier account is suitable enough for having a reliable VPN connection in a pinch, I didn’t see anything wrong speed-wise though when downloading things I was noticeably throttled. If privacy is your primary concern and you don’t intend to push any P2P traffic this is probably fine.
I was able to stay connected for several days or longer without disconnection issues which prompted me to just spring for the basic plan for $48/year. I like the service, I like ProtonMail prior to that and I want to support them. It was also worth it to me to have access to such a large range of VPN servers spread across the world so that pvpn -f would indeed find the best endpoint closest to me, especially if I was out of the country.
Speed and Traffic
For comparison purposes using the speedtest-cli Python program available via pip here are some test numbers before and after on a CentOS7 VM.
I am providing my setup instructions here for posterity:
yum install python-pip python-virtualenv -y virtualenv speedtest cd speedtest/bin source activate pip install speedtest-cli
Testing Regular Connection Speed
This is simply running speedtest without being connected to ProtonVPN
# speedtest-cli Retrieving speedtest.net configuration... Testing from Virgin Media Ireland (79.XX.XXX.XXX)... Retrieving speedtest.net server list... Selecting best server based on ping... Hosted by IP Telecom (Dublin) [1.78 km]: 16.305 ms Testing download speed............................................. Download: 184.26 Mbit/s Testing upload speed............................................... Upload: 24.47 Mbit/s
Testing ProtonVPN Connection Speed
This is after I’ve connected to ProtonVPN from the fastest endpoint, for some reason it wanted to use the Amsterdam speedtest servers. Ok then:
# speedtest-cli Retrieving speedtest.net configuration... Testing from WorldStream B.V. (89.XX.XXX.XXX)... Retrieving speedtest.net server list... Selecting best server based on ping... Hosted by Tele2 Netherlands B.V. (Amsterdam) [1.75 km]: 50.135 ms Testing download speed............................................. Download: 83.63 Mbit/s Testing upload speed............................................... Upload: 23.74 Mbit/s
Testing P2P Traffic
For P2p traffic I downloaded some Fedora and CentOS ISO’s on a test VM using an in-country VPN endpoint and saw between 3.3 to 4.1 MB/s (26.4 to 32.8 megabits) where I’d normally see 9 to 11 MB/s (72 to 88 megabits/sec). There is some VM overhead there I am sure also.
For more exhaustive speed testing between the free versus plus plan see the following thread on Reddit.
NOTE: P2P traffic is allowed only on servers from Netherlands, Singapore and Sweden, so for example you would want to use the following pvpn command in your systemd service file instead of /usr/bin/pvpn -f where NL#1 is the server that allows P2P traffic from the Netherlands for example.
ExecStart=/usr/bin/pvpn -c NL#1 ExecReload=/usr/bin/pvpn -c NL#1
After the above changes to /etc/systemd/system/protonvpn.service you’ll want to reload your unit file.
There are a lot of legitimate purposes for using P2P protocols like bittorrent and I do not condone using P2P traffic for anything that might be illegal in your country as it pertains to digital copyright, consult the laws in your country.
Testing DNS Leaking
A potential chink in the armor of any VPN service is what DNS services you are using. While all of your transport traffic is encrypted and hidden your actual DNS queries may be leaking. ProtonVPN provides secure, private DNS servers for your connections that do not leak your DNS queries. This is the default unless you changed it.
You can test this via visiting a site like DNS Leak Test.
When I am at home I am using Pi-hole for my local DNS anyways for the additional filtering and ad-blocking but I always use the ProtonVPN DNS server defaults when connecting abroad or while traveling and all tests I’ve done show that no DNS queries are leaked.
ProtonVPN on Mac OSX
I have an older personal Macbook Air 11″ that I use for travel sometimes as it’s super lightweight. Setting up ProtonVPN on OSX was straightforward. One humorous thing to note is it looks like one of those futuristic Hollywood “hacker” programs. “I’m in!”
Once connected to the ProtonVPN.
ProtonVPN on IOS
I briefly installed and used the ProtonVPN service on an Iphone. The native application worked great, integrated into the innate IOS VPN settings and everything was responsive and easy to use. I didn’t do any further testing past this.
Other Privacy Features: Secure Core and TOR
One feature that I did not try out as it’s only available in the Plus and beyond plans is the secure core feature. This obfuscates your ingress connection into any of the VPN endpoints making it very difficult for things like a correlation attack. There’s a full explanation of the service here and the benefits.
There are lots and lots of VPN providers out there with many, many countries and endpoints to choose from. ProtonVPN sticks out because their free tier is really free (though understandably limited). They also support bitcoin for payment which is cool.
I believe you could find better speeds if you shopped around, but I also like the security focus of ProtonVPN/ProtonMail and the speeds for me are good enough (encryption overhead is encryption overhead) that I’m happy supporting them via the basic plan however your mileage may vary.
I’m glad they seem to be actively developing their Linux CLI, and the other official applications I’ve tried appear polished and easy-to-use. One small nitpick on the Linux CLI is that without the systemd service approach there is no persistent connection option, though there’s a Github issue for this.
Lastly, the username and password is kept in cleartext on the system. This could probably be salted/hashed somewhere but the CLI is still relatively new (it’s a shell script) and seems to be garnering a lot of improvement quickly. The counter argument you can make here is if someone has access to this you have bigger problems than someone borrowing your ProtonVPN (OpenVPN only) credentials.
It’s been over a month since I’ve been running ProtonVPN persistently via the systemd service and I have had no issues. Disconnections, while rare, are reconnected automatically as expected.