When you sit down to write a piece of technical documentation, it’s always surprising that the section you thought would be really complicated is astonishingly simple; and the things you thought would be finished in minutes steal days. Configuring an OpenVPN connection on Chrome was one of these things — it stole an entire day, but I finally got it working (and working repeatably, which is the sticky wicket!).
First of all, ChromeOS doesn’t really support OpenVPN despite the UI allowing you to add a connection. The options you’d need to configure it successfully aren’t there, and the version of OpenVPN that runs on the system is very old — 2.3.2, which doesn’t support TLS 1.2 or higher (not cool). There’s no third party client available and you can’t import OpenVPN ovpn configuration files into ChromeOS’ network manager UI — you’ve got to use ONC (Open Network Configuration) format…and ChromeOS is pretty finicky when it comes to parsing and consuming these files (not to mention that the location where you import these files is…very much hidden from view). You’re also required to be able to Bind to Device when installing client certificates — and for some popular ChromeOS virtual machine images (like Cloud Ready), this isn’t possible.
It’s disappointing, because Chromebooks are neat little tools — and users of neat little tools should be able to connect to a VPN server without having to use Developer mode. Everyone should be able to use a VPN.
But all is not lost; there’s a way to get OpenVPN connections up and running without enabling Developer mode. To make things easier (because crafting a working ONC file is non-trivial, I wrote a script that you can use against any OpenVPN server.conf file and easy-rsa-generated PKI store to generate a working ONC file. From beginning to end, here’s how you do it:
Generate Your ONC File
Gather your server.conf and certificate store information. The script itself assumes you’re running it on the server and that your server.conf file resides at /etc/openvpn/server.conf and that your PKI store is at /etc/openvpn/easy-rsa/pki. You can change these values, however.
Clone the scripts:
git clone https://github.com/jenh/OVPNOncorator.git
Move into the OVPNOncorator directory and run the script:
cd OVPNOncorator && sudo python ovpnocorator.py
Note that this assumes an installation of /etc/openvpn for your server.conf and /etc/openvpn/easy-rsa/pki for your PKI store. You can change these values with –config and –keystore, respectively:
sudo python ovpnoncorator.py -c /path/to/my/server.conf -k /path/to/my/keystore-directory
This will place an ONC and p12 file (for use on ChromeOS) and an ovpn file (for use on all other platforms) in the current directory.
Install the configuration on Chromebook
On your Chromebook, open Chrome, and open
chrome://settings/certificatesin the browser.
Click Import & Bind to Device and select the p12. When prompted for a password, enter the password
chrome. (Currently, this is given an insecure “chrome” password on generation; you can change this in the python script if you want.) Note that if you don’t have the ability to bind to a device (i.e., you’re on a virtual machine image), you unfortunately won’t be able to use OpenVPN. (If anyone knows a way around this, let me know.)
Then, inside the browser, open
chrome://net-internalsand click ChromeOS (at the bottom of the navigation menu).
Click Import ONC, navigate to your generated onc file, and click Import. The interface will tell you “no file chosen,” but if you tap your wifi network icon in the system tray, and tap VPN Connections, it should show up unless there was a parsing error. (If you find out where or whether these parsing errors get logged anywhere, lemme know - couldn’t find ‘em in /var/log/*)
Tap the wifi network icon in the system tray, tap VPN Connections, select your network connection, then tap Connect. If you set up a username and password in your server configuration, enter that when prompted. If you’re just using certificate-based authentication, you can enter anything in the username and password fields. The server doesn’t care if it doesn’t need it, but Chrome won’t let you connect without username and password values specified.
As discussed at the beginning of this post, ChromeOS uses an old version of OpenVPN without TLS 1.2 support. If enabled on the server, it will never connect. Please do a solid and star the Chromium bug. (And any other OpenVPN-Chrome bugs you happen to see: OpenVPN support in Chrome needs serious love and encouragement!)
Also, if you aren’t running your own instance of OpenVPN already and want to give it a whirl (it’s a lot easier — and secure — than you think, I promise!), check out this script.