Privacy is hard
If you are concerned about your privacy, and happen to have access to ProtonVPN‘s beta test and are using a pfsense firewall as router, then this might be in your interest.
The rough how to is not intended as a step-by-step howto, and I assume you have a little more than basic knowledge of networking, so not all of the steps will be demonstrated with screenshots. It might be applied to other firewalls (which give you similar options) as well, but that is not detailed.
Disclaimer: I am not affiliated in any way with ProtonVPN, ProtonMail or pfsense, other than using their services with a paid account. This blog entry is a review of my first impressions after a “hackfull” evening, playing around and learning a lot about pfsense as well (Linux as a secure firewall got shaky lately).
Know your threats!
Why do you actually need a VPN?
Why do you need a VPN in the first place? Who/what are you going against? Do you need to fake the Country you want to appear in, or is your life depending on it? Remember, the path to your browser does not matter if you have a cookie in your Browser that tells them who you are.
Having VPN is a nice thing, but it only keeps your ISP out of the loop, ALL the websites tracking you will still keep tracking you, just like they did yesterday without a VPN.
Decide which VPN provider you trust!
Trust is something that has to be earned, but initially you need a basis on which you can start. A good thing to look up is where the company’s seat is located in, since for example not so long ago a court in the US ruled that Google has to hand over information that is in its posession, but physically not in the country, so take your time to research these things.
Research the technology and the security they are providing
Are they using up-to-date technology? Forget PPTP, it is just a joke about security. Also a lot of providers’ Settings pages or How to’s are like someone googled about VPN and copy-pasted together something from 2003, where MD5 and PSKs were still valid setups. If you see “our own crypto”, better Ctrl+W that Tab ASAP.
Decide what traffic to run through your VPN tunnel.
How important is it for you to run ALL traffic through the VPN Tunnel? Is it worth to not run some dedicated traffic through the VPN? VOIP for example is quite sensitive to latency, and forcing it over a VPN jump could distort the voice quality dramatically.
How about always-encrypted traffic that is always authenticated and tracked anyway? The VPN Tunnel does (almost certainly) not provide you the same bandwidth as your native speed is. Talking about streaming providers like Netflix or similar: is streaming your movies worth having it streamed over a VPN? Yes is still a valid answer, but keep the question in mind.
Another important question is if your internet should go black if the VPN tunnel is down, or do you want to fall back to your default, un-VPN-ed gateway until the connection can be re-established? Ask your wife / your husband as well :-), she/he might have a strong opinion about not having internet during the day. If it’s so important, do not rely on one sole provider but use multiple ones!
Get an account
You need access to the closed beta, which is available for Visionary and Plus customers of ProtonMail, or have to wait until it will be available to the public (?), which is currently advertised as “Coming in Spring 2017”.
For those having access to it, there should be a new icon in Settings, just right below “Keys”, which takes you to a page where you can generate a random username and set a new password for it.
Get the config
They have also a fancy Windows Download-Next-Next-Finish clicky-bunty Native-Client, which can be used directly with your ProtonMail login credentials, and the random username and dedicated password are only required if you plan to use a third-party client, like openvpn.
Well, for native OpenVPN clients they actually provide a downloadable zipped collection of .ovpn files, which we will make use of to set up our pfsense. You can find them on their support page for linux at Additional resources.
The Security in a nutshell
The quality of a VPN Provider can be more or less measured by the technical aspects of how to configure the Tunnel, what crypto it uses and how much bandwidth / latency you need to sacrifice. ProtonVPN uses up-to-date settings, let’s have a quick look at them.
The crypto cipher being used is AES-256-CBC with a HMAC of SHA512, so not the old SHA1 with AES-128 that you tend to see. They also include a 2k static key for tls-auth the packages.
Embedded there is a CA to authenticate the remote side. which was issued by “C=CH, O=ProtonVPN AG, CN=ProtonVPN Root CA” and is a 4k RSA key with SHA-512 signature, which is currently considered “secure”.
All connections use the standard udp/1194 port, so in situations where this outgoing port is filtered, you might hit it’s limits. Some captive portals or firewalls (like at airports) let udp/53 pass without auth and/or are limiting outgoing ports to tcp80/443 even after logged in, so having a listener on those might also be worth to think about…
ProtonVPN presents a feature that is called “Secure Core“. This consist of Servers located either in Sweden or Iceland, but have a second hop at an endpoint in a different location, and your data travels like You->Sweden->France, so your public IP is in a different country than your VPN Server you connect to.
This is quite good for privacy, but relatively bad for latency: it adds about +100ms to +500ms, which has to be considered when choosing a permanent tunnel for a fixed location.
The speedtest with the Secure Core was “acceptable”, my 50/10MBit line measured around 39/6MBit throughput and a latency of +120ms totaling around ~125ms.
The current setup will show a random Japanese server being used with one dedicated IP net being routed through the VPN (accessing my workplace’s VPN should be routed directly).
The pfsense box itself is running on a 3-NIC APU2 Board from PC Engines, which has 4core / 4GB RAM with AES-NI in CPU, so it should handle this burden with ease. At the time of writing the latest version was 2.3.3-RELEASE-p1 [I updated to 2.3.4 during writing the blog entry].
Open the .ovpn config file for your favorite VPN Tunnel and keep it within reach, you’ll need it for a lot of copy+paste work.
First of all, we need to import the ProtonVPN RootCA, so get to:
System => Certificate Manager => CAs => + Add
For the Name, enter something that you know of what this is, using “ProtonVPN RootCA” is probably the best approach for this.
On “Method” you can keep the default of “Import an existing CA“.
The “Certificate Data” Field is where the content of the <ca> … </ca> section goes, including the lines with the many dashes and BEGIN/END CERTIFICATE.
After saving you should have an entry back at CA’s showing you a self-signed certificate like this:
O=ProtonVPN AG, CN=ProtonVPN Root CA, C=CH
Valid From: Wed, 15 Feb 2017 15:38:00 +0100
Valid Until: Mon, 15 Feb 2027 15:38:00 +0100
New OpenVPN Client
Go and create a new OpenVPN Client connection at:
VPN => OpenVPN => Clients => + Add
Now simply follow the fields and use your copy+paste foo:
Server host or address => IP on "remote" line in .ovpn Server Port => Keep in on 1194 (or whatever is after the upper IP)
User authentication settings
Username => Random-Generated Username from ProtonMail GUI Password => Password for Username
Automatically generate a shared TLS authentication key => uncheck Key => Paste value from <tls-auth> .. </tls-auth>, excluding comment with # Peer Certificate Authority => Choose the RootCA we set up earlier Encryption Algorithm => Choose AES-256-CBC (or whatever is at line "cipher") Auth digest algorithm => Choose SHA-512 (512 bit) (or whatever is on line "auth")
Compression => Enabled with Adaptive Compression Don't pull routes => If you want to route ALL your traffic over VPN, keep it unckeced, otherwise check.
Custom options => Add: remote-cert-tls server tun-mtu 1500 tun-mtu-extra 32 mssfix 1450 fast-io
It should look like this at the end.
Now save it, it should connect automatically if not disabled with the very first checkbox. You can go and check it out on Status => OpenVPN. It should show “up” with a virtual IP address in the 10.8.8.0/24 IP Range:
All Your Traffic Are Belong To US
The most secure way
If you have chosen to route ALL your traffic over the VPN at the OpenVPN setup, you will need to add additional outgoing NAT rules for the OpenVPN interface, so go to:
Firewall => NAT => Outbound
Here you need to check the radio button telling “Manual Outbound NAT rule generation. (AON)“.
After that, select on each rule one-by-one the icon of “Add a new mapping based on this one” in the column of Action, and duplicate them with just changing the Interface to OpenVPN.
This is required because the remote server pushes routes that will change your routing table to go over their gateway via “redirect-gateway def1“, so you need to allow all traffic to being NAT-ed via OpenVPN.
This step is also nicely illustrated by PIA’s How to:
We decide ourself what to send via VPN
If we chose not to pull the routes, we will need to get a little more configuration and set up our own routing rules, since we don’t get the default routes pushed, but it makes much more fun 🙂
Add a new Interface
Interfaces => (assign)
Here we create a new interface for our OpenVPN connection we set up earlier. On the “Available network ports” line pick the ovpncX interface. This will create you an OPTX interface, depending on how many interfaces you already have.
Click on its name to open and edit it. Make sure to choose a Description that will match your setup, since after you got it used by a Gateway, pfsense does not allow you to change it. I have chosen PROTONVPN. Make sure to check “Block bogon networks” but do not check to block private Addresses, since the VPN has a subnet of 10/8, which would be blocked otherwise.
Click here to see the whole page. After saving, you should see the new interface being show in the Interfaces drop down menu.
Add a new gateway
Now we need to tell pfsense what traffic we want to use the VPN. For that, we need to defined the PROTONVPN interface we just created as a Gateway, that can be used to send traffic towards The Internet. Just navigate to:
System => Routing
You should see the PROTONVPN_VPNV4 and PROTONVPN_VPNV6 gateways created by default. I have chosen to customize them and set up a ping monitoring against Google’s DNS Server 220.127.116.11, and have tuned the ping times higher to compensate with possible reconnects and latency introduces by some of the remote vpn servers. You can see the whole config page here.
Depending on if you want to have more VPN tunnels set up to load-balance your traffic, or if you want your Internet not go black if the tunnel is down, you will need to create a Gateway Group. You can skip this part and pay attention at the Firewall rules if you want all your traffic to pass through the tunnel.
I have chosen my traffic to fallback to the default Gateway if the VPN is not available, so you have to add the PROTONVPN with Tier 1 and the WAN with Tier 2, and keep the rest unchanged.
We have created the Gateway called “VPN“, which uses the ProtonVPN Tunnel, but if that is not reachable, falls back to the default WAN route. This is good to have your wife not call you during the day if the VPN tunnel goes down for maintenance 🙂
Firewall => Aliases
I personally utilize the Aliases of pfsense, which comes handy to define destinations like WORK_VPN or YOUTUBE or NETFLIX, for which you can find IP subnets after some searching. Later I bundle them together in a DIRECT_ACCESS alias, which holds the separate entries, so I don’t have to touch the NAT Rules after editing this list.
Firewall => NAT => Outbound
Here we need to change “Automatic outbound NAT rule generation” to “Manual Outbound NAT rule generation” to get the freedom to reorder and edit the entries, so they make sense.
I have for VOIP Telephony a Fritz!Box, which is in my DMZ, but it is latency-sensitive, and needs a direct port NAT-SIP protocol is not that big of a mess, so that goes on top.
I have created three additional NAT rules, that define how the translation will happen if the package arrives from my home network (it’s represented by the USG_DMZ alias). The remaining are the default rules for the outgoing WAN packets, which have been generated by the automatic rule generation.
This is the most challenging part, since you need to design your network routes now. We have set up the proper VPN Gateway with monitoring and fallback to the WAN gateway, defined how the packages need to behave if they are sent out via the PROTONVPN interface, now we only need to ensure the packages actually take the right interfaces on their path. Navigate to the proper interface where your Internet-facing traffic arrives to the pfsense box. For me, this is the DMZ interface, but for you it might be LAN.
Firewall => Rules => <Interface>
These rules are processed from top to bottom, and the first rule that applies is processed, and if none matches, default is to drop the package. In order to allow some dedicated traffic direct access bypassing our VPN Tunnel, we need first to create an entry that matches the destination we have defined in the DIRECT_ACCESS Alias. For the Source, you could choose LAN Net or the gateway your internet flows through, which in USG_DMZ for me. See here the whole config page
The next in the list should be a generic rule that catches all remaining traffic to go through the VPN gateway. To achieve this, we will need to open the Advanced options and scroll way down to Gateway, keeping everything else as it is. Here at Gateway you can choose either the PROTONVPN_VPNV4 for VPN-Only, or our Gateway Group called VPN for WAN fallback.
The whole settings page can be viewed here.
For all this to work, we need to make sure the ordering is correct, so first we add a specific rule, and below it on that catches all remaining traffic.
If everything went well, you only have to fire up your command line and run a traceroute against an address included and one not included in the DIRECT_ACCESS rule. You should see something like this if the traffic is flowing over the VPN:
Tracing route to japan.go.jp [18.104.22.168] over a maximum of 30 hops: 1 1 ms 1 ms 1 ms 192.168.1.1 2 379 ms 408 ms 408 ms 10.8.8.1 3 337 ms 338 ms 339 ms 169.254.192.75 4 339 ms 372 ms 403 ms ae12.dar02.tok02.networklayer.com [22.214.171.124] 5 381 ms 397 ms 392 ms ae9.bbr01.eq01.tok01.networklayer.com [126.96.36.199] 6 374 ms 406 ms 409 ms ae-20.r00.tokyjp03.jp.bb.gin.ntt.net [188.8.131.52] 7 * 364 ms 408 ms ae-14.r30.tokyjp05.jp.bb.gin.ntt.net [184.108.40.206] 8 418 ms 409 ms 407 ms ae-2.r03.tokyjp05.jp.bb.gin.ntt.net [220.127.116.11]
If you want to choose a different tunnel, just rewrite the IP on the OpenVPN Client settings, it will reconnect and no other changes have to be re-done.
I have tried to add multiple VPN Tunnels from ProtonVPN, but apparently they provide you with the same 10.8.8.0/24 IP Subnet, regardless of which VPN tunnel you use, so load balancing between them is currently not possible: having the same IP Subnet with the same Gateway IP of 10.8.8.1 is not something a router can handle.
One could add different VPN Providers and round-robin over the different gateways, but as for example Troy Hunt has also pointed out quite good in his long blogpost, putting all your (and family’s) traffic through a VPN does mean they know A LOT of information about you, even if most of it is encrypted.
So bottom line is, since there is actually no organization overseeing them, the VPN Provides can be initially measured by the technical implementation of their service, but in the very end, it’s the customer’s trust they have to earn by behaving like they care about security and privacy, how they react to events regarding their customers or themselves, and are not just shipping your IP Traffic from A to B.
The screenshots were taken with the Chrome Plugin “Full Page Photo Capture“
Awesome guide! Small question I had about the “firewall rules” section: You state “Navigate to the proper interface where your Internet-facing traffic arrives to the pfsense box. For me, this is the DMZ interface, but for you it might be LAN”…do you mean traffic that originates internal to your network and is destined externally (like to a website)? I guess I’m confused whether by “internet-facing” you mean “internet-bound” or not, or literally the interface facing the internet (which would be WAN usually).
Hi. Yes, basically the “internet destined”, I will correct that part of the writing. You see, my pfsense is not directly my default gateway on my LAN, but has a connection to it (via it’s LAN interface).
I have an additional Ubiquiti Security Gateway that plays DHCP and its doing NAT between LAN and DMZ, and so my traffic is basically flowing with a setup like:
The security gateway issues leases to LAN devices. However, the pfsense also allows the use of its LAN address as gateway, but does not route that traffic through the VPN, only the WAN.
So if you I have to send some traffic via direct internet uplink, I configure the ip settings manually.
I known it’s double NAT, but unfortunately there is no option in the USG to set an upstream router without having NAT.
That makes sense. Thank you!
Very good guide! Thank you for taking your time to write this!!! You saved me a lot of time! 🙂
Thanks for your guide. I was up and running in a couple of hours and have never used pfsense before.
I had to do a little troubleshooting because the routing gateway of vpn interface had a state ‘pending’. A reboot solved this.
What I cannot get to work is a second Gateway as fallback. Once the second client is defined and up, I lose all connections. When the second client is disabled, everything works as normal.
If you have any ideas , I would appreciate all help.
Do you mean a second ProtonVPN gateway? That’s because they all share the same 10 internal subnet, or you can gave the same monitor ip?
You have to have different IPs set up to being monitored for the GW being up, so you could choose either your ISP’s DNS Server or some well-known public IPs, like the Google DNS Servers (18.104.22.168 / 22.214.171.124) or similar. I also had trouble after setting up both Gateways with the same IP to monitor.
Thank you for your great guide!
What is the speed that you saw using ProtonVPN and the APU2 board? Did it max out your internet connection? How much load did you see on the APU2 machine?
I have a 50MBit up 10MBit down VDSL2 line, I mostly have speeds around ~45MBit/8Mbit over the VPN tunnel. The load avg is between 5-7, after I log in over the GUI and it has to render the graphs and serve the UI it spikes to ~10, but not something the OS/HW cannot handle. I have never had the APU2 board being the bottleneck, but more like the Powerline I have some devices connected with 🙂
In section All Your Traffic Are Belong To US, The most secure way” you write “openVPN”. I guess you mean change to “ProtonVPN”?
and what I don’t get, how you can bundle your Aliases “Youtube”, “Netflix” and so in another Aliases like “Direct-Access”.
Awesome guide! I am using OPNsense and it is working as well. But unfortunately I guess Netflix is checking the source IP address and they mapped all the ones used by VPN ISPs since they show the message about being behind a proxy.
I was also thinking of that, and one way to solve is to make the DNS resolver be a dnsmasq, and use it’s feature to put all resolved IP-s of a domain into an IP set, which you can then sync into the router.
See ref: http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
Places the resolved IP addresses of queries for one or more domains in the specified Netfilter IP set. If multiple setnames are given, then the addresses are placed in each of them, subject to the limitations of an IP set (IPv4 addresses cannot be stored in an IPv6 IP set and vice versa). Domains and subdomains are matched in the same way as –address. These IP sets must already exist. See ipset(8) for more details.
Hey I run Proton VPN on my PFsense for over a year now and been running nicely. You have any experience in Remote Accessing you PFsense router running Proton VPN? I’ve been trying using a OPENVPN setup to dial in but with little success, I feel it might be because the Proton VPN in play and won’t let me access the router from a another location. Any pointers would be relay appreciated.
Well you get a private IP within ProtonVPN and that is NAT’ted to a public one, there is no portforwarding backwards, so this is not going to work in this case. You will need to setup a dyndns or somilar that will point to your real public IP address, to which you could set up firewall rules that allow access, but then the question is, how do you restrict it…
Hello, beautifull post here! Congrats. I dont have much experience with pfsense, routes, NAT´s, etc…, and now with a peculiar situation: My pfsense is my network gateway (dhcp server, dns fowarder, etc…), I have 2 wan conections (1 pppoe – fiber – tier1 on gw group / 1 static ip – tier2 on gw group) in failover already setup. Everything works fine, i already tested this. Now i create (configure and setup OpenVPN client) on Proton, the conection says it is up and good. I dont use VLAN cause of my internal infrastructure and money limitations. I create some static dhcp leases configured for some devices. All devices should navigate on wan1 (pppoe) normally, with failover to wan2 (static), but i need 2 internal IPs always going to VPN (regardless in what wan the network is configured), and this is the trick part. Can you help with this impossible task for me?
Leave a comment