OpenVPN connection

The VPN setup pages in Chrome OS appear to support OpenVPN. ProtonVPN also supports OpenVPN connections, and configuration files are available for download. However, it turns out that OpenVPN doesn’t actually work with Chromebooks quite as easily as it should — long discussions are easily found, solutions not so much. One of the main issues is that the visual configuration dialogs don’t support all the options OpenVPN offers, and which are used by configuration files such as those supplied by ProtonVPN and other VPN providers. The Chromium project has its own format called ONC, but OpenVPN configuration files end in .ovpn.

Converting

The first thing I did was convert the .ovpn file I downloaded from ProtonVPN to the ONC format. Fortunately Steve Woodrow created a simple Python conversion script that saves a lot of work with this step.

> cat uk.protonvpn.com.udp.ovpn | python onc_converter.py > uk.protonvpn.com.udp.converted.onc

After this, I had to make several changes to the file before things started to work.

Required Changes

Step 0: For some probably unintentional reason, the ProtonVPN configuration file for the UK shows the server name as gb.protonvpn.com. This name doesn’t even resolve in DNS — the correct one appears to be uk.protonvpn.com. I will report this to the ProtonVPN guys as soon as I’m done with this post, so it may be fixed soon.

Step 1: If you search for the setting Password in the converted .onc file, you’ll see that the converter simply adds not_used in that place. I changed the file to include my username and password, as well as the UserAuthenticationType setting as per the docs.

...
"UserAuthenticationType": "Password",
"Username": "...",
"Password": "...",
...

The username and password should be the special OpenVPN credentials provided by ProtonVPN, as described here.

Note: I did some limited tests to see which of these fields are strictly required for the ONC import to work correctly. It appears that an ONC file with only the Password field, as created by the conversions script, is not accepted by the importer.

Step 2: I assigned a name to the VPN profile by changing the line that says "Name": null to "Name": "ProtonVPN via ONC".

Note: Again, according to my tests the ONC importer won’t accept a configuration without a name.

Step 3: I played around quite a while before I figured this one out. The converter script statically sets the option IgnoreDefaultRoute to true in the ONC file it generates. This means that a default network route is not configured for the VPN tunnel, so unless you plan on fiddling with routing tables yourself the VPN is simply not going to be used by your network traffic even if it connects correctly. According to the ONC spec linked above, the default value for IgnoreDefaultRoute is false. However, I found that it is not sufficient to change the line to false. I reckon this is a bug, but connection logs (open chrome://system/ in the browser and expand the item called netlog) clearly show the line Ignoring default route parameter as requested by configuration (as generated by this code) as long as IgnoreDefaultRoute appears in the ONC file, regardless of its value. Based on my findings, you must remove the line for IgnoreDefaultRoute from the ONC file in order to have a default VPN tunnel route configured.

Importing the ONC file

Go to chrome://net-internals/#chromeos to find the ONC import functionality. Be aware that there is no reaction after the import, whether it worked or not! However, if everything is good you should see the new item appear immediately in the list of VPN configurations. Unfortunately I have not been able to find any log that shows errors if an ONC file is not imported due to some issue. I can only suggest to start with a configuration like the one I described above, and to read the specs linked above if necessary.

Make sure the connection works!

You should be able to connect the VPN at this point. Before you do, I suggest you go to a site that displays your own IP address (for example iplocation.net, or simply do curl -s https://api.ipify.org from a Linux commandline). Then connect the VPN and reload the IP information — it should have changed, indicating that traffic is now routed through the VPN. If your publicly visible IP address doesn’t change, the VPN tunnel is not being used!

Status

I hate it when I read technical blogs and there is not enough information for me to figure out whether the details apply to me or not — technology changes so quickly, and while I was researching the various issues I encountered I came across loads of completely outdated information. For this post, I’ll list my Chrome version: 76.0.3809.136. And the CHROMEOS_RELEASE_VERSION shows as 12239.92.0.