Raspberry Pi OpenVPN Server for ChromeBooks
Tags: chromebook, openvpn, raspberrypi
Published: 2020-02-04 19:05:19

How to connect a ChromeBook client to an OpenVPN server running on Raspberry Pi.

Running [OpenVPN](https://github.com/OpenVPN/openvpn) on a [Raspberry Pi](https://www.raspberrypi.org/) located on your home network is a great way to securely tunnel into your home network while you're away, allowing you to connect to all the devices in your home. It also serves to keep your traffic secure while you're roaming on untrusted public WiFi networks. [ChromeBooks](https://www.google.com/chromebook/) are an interesting alternative to more fully fledged laptops when you're travelling and want to stay connected. This article shows how this OpenVPN setup works with ChromeBooks, which are rather picky when it comes to configuring them as OpenVPN clients. It doesn't require the ChromeBook to be able to run Android apps, which also allows it to work on older ChromeBooks.

## Overview

There are a considerable number of articles one can find about setting up an OpenVPN server on their home network. There are also many ways how they go about getting it done. Surprisingly though, finding a setup that works for letting you connect with a ChromeBook to your OpenVPN turns out more challenging than expected. In the rest of this article we'll go through all the steps you need to arrive at a fully functional setup that does work with an [Acer C720](https://www.theverge.com/2013/10/23/4948120/acer-c720-chromebook-review) ChromeBook. This is one of the earlier ChromeBook models and probably on the more restrictive side when it comes to OpenVPN setups. Of course this OpenVPN setup also works for other clients like PCs, Macs, Android phones and tablets etc. which are a bit more forgiving with respect to the parameters they support. The following steps are necessary:
* **Dynamic DNS**: If you want to be able to connect to your home network from the outside, you'll need a way to find it's IP address. Most internet service providers, like cable or telephone companies, don't assign a fixed static IP address to you which you could use. The solution is to associate your Raspberry Pi with a dynamic DNS name and update that with the public IP address of your home internet connection whenever that IP address changes.
* **OpenVPN Setup**: Setting up OpenVPN requires picking a number of configuration parameters that are compatible with the OpenVPN server and the set of expected OpenVPN clients. Once the right parameters are picked you'll have to create a number of encryption keys. We'll walk you through all that.
* **Router Configuration**: To connect to the OpenVPN server on your home network from the outside world you need to make sure that the Router allows the OpenVPN traffic through and direct it to your Raspberry Pi.
* **ChromeBook Setup**: The last step will be setting up the ChromeBook as an OpenVPN client connected to the OpenVPN server on your Raspberry Pi.

## Dynamic DNS

In order to access the Raspberry Pi on your home network by name, you need to set up a Dynamic DNS record that associates that name with the IP address that is currently assigned to your home by your internet service provider. On your Raspberry Pi you need to install a Dynamic DNS update agent that maintains this association. We'll use *ddclient* for this purpose which is a generic update agent that works with a wide range of Dynamic DNS service providers.

If you happen to own a domain name, you can use your domain registrar to set up a Dynamic DNS record under your domain. Different registrars have different interfaces how to do that, so you have to read their documentation to find out. For example, if you're using [Google Registrar](https://domains.google.com/) for your domain, in its web UI it has an entry for *DNS* -> *Synthetic records* that allows you to add entries for *Dynamic DNS* as a sub-domain in your domain. You could use *vpn.&lt;mydomain>* as the Dynamic DNS record for your home VPN setup. That UI shows you a *Username* and *Password* which you'll have to copy to your ddclient configuration on the Raspberry Pi. More on that later.

If you don't own a domain name it's not a problem either. There are a number of Dynamic DNS providers out there with different sets of features and prices. We'll walk you through using [No-IP](https://no-ip.com/) which offers a free plan for up to 3 Dynamic DNS records. A disadvantage of this free plan is that every 30 days you'll have to manually confirm that you're still using it. That's the price for *free*. Here is how to set it up:
* Sign up for a free No-IP account at [https://www.noip.com/sign-up](https://www.noip.com/sign-up)
  * Fill in the *Email* and *Password* fields. Note that this is also the password that you'll have to store (in clear text) in your Raspberry Pi ddclient configuration. So I'd advise to use a [generated password](https://passwordsgenerator.net/plus/).
  * Instead of filling in a *Hostname*, check *Create my hostname later*.
  * Agree to the terms of service and click *Free Sign Up*
  * You'll get sent an email to the address you entered, which contains a link to finish the signup. Wait for that email and click the *Confirm Account* link in it.
  * On the page that opens, click on *My Account* on the top menu.
  * Add a *User Name* and *Security Question* as requested by the page. This *User Name* will also need to get stored in the Raspberry Pi ddclient configuration later. This concludes your account setup.
* Click on *Dynamic DNS* in the left-hand sidebar menu, then click *Create Hostname*
  * Fill in the *Hostname* with a unique name for your VPN and pick a domain from the *Free Domains*. I'll pick *ddns.net* as an example.
  * Set *Record Type* to *DNS Host(A)* for an IPv4 address.
  * Your currently assigned IPv4 address should already be filled in, just leave as is. But don't worry if it's not, ddclient will fill it in later.
  * Click *Create Hostname*. If you get an error message that the name is already taken pick a different hostname - it must be unique across all people using this service.

You have now set up a Dynamic DNS record on the No-IP site. The next step is to configure an update client that keeps that Dynamic DNS record up to date with the public IP address of your home network. For that, log in to your Raspberry Pi and install *ddclient*:
```bash
sudo apt-get update
sudo apt-get install ddclient
```
Once installed you need to configure it. Make sure the `/etc/default/ddclient` file contains the following lines:
```
run_dhclient="false"
run_ipup="false"
run_daemon="true"
```
If any of those flags are set differently, change them and save the file. Then edit the `/etc/ddclient.conf` file. It was filled in with some rudimentary settings by the ddclient installation. Overwrite those with the following contents:
```
# no-ip.com
protocol=dyndns2
use=web, web=checkip.dyndns.com, web-skip='IP Address'
ssl=yes
server=dynupdate.no-ip.com
login=<your-noip-username>
password=<your-noip-password>
<your-noip-hostname>.ddns.net
```
Here `<your-noip-username>`, `<your-noip-password>`, and `<your-noip-hostname>` should be the *User Name*, *Password*, and *Hostname* you have chosen earlier in the account setup on the No-IP web site. If you have your own domain, use the corresponding values from your domain registrar's Dynamic DNS settings instead. Once this file is saved restart ddclient:
```bash
sudo systemctl restart ddclient
sudo systemctl status ddclient
```
You should see that ddclient has started successfully. If there were errors it might be helpful to look into the `/var/log/syslog` file for error messages - search for `ddclient`.

## OpenVPN Setup

The next task is to set up the OpenVPN server on your Raspberry Pi. Out of the many options to do this, I'll describe a simple one that involves a [setup script](https://github.com/angristan/openvpn-install) that already does all the work for you, you just have to answer some questions. On your Raspberry Pi first install the setup script
```bash
curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh
chmod +x openvpn-install.sh
```
and then run it
```bash
sudo ./openvpn-install.sh
```
This script will ask you a series of questions and then configure OpenVPN and easy-rsa appropriately. Answer the questions as follows:
* **IP address**: it'll suggest your local IP address which should be fine
* **Public IPv4 address or hostname**: set this to `<your-noip-hostname>.ddns.net`, i.e. the Dynamic DNS name that you have chosen and set up earlier in the `/etc/ddclient.conf` file.
  * Side note: This is only used for `/etc/openvpn/client-template.txt` which is the header for generating clients' \*.ovpn files. The \*.ovpn file header can be edited later to change things by hand if necessary.
* **Do you want to enable IPv6 support (NAT)?**: leave default 'n'
* **Port choice** : leave default '1', *port 1194*
* **Protocol**: leave default '1', *UDP*
* **DNS**: I like to pick Google '9', but pick whatever you feel comfortable with
* **Enable compression**: leave default 'n'
* **Customize encryption settings**: pick 'y' (not default)
  * This is how we're going to set up OpenVPN in a way that is compatible with ChromeBook VPN clients.
* **Cipher**: pick '3', *AES-256-GCM* (not default)
* **Certificate Type**: pick '2', *RSA* (not default)
  * The Acer C720 ChromeBook doesn't support the default setting which uses elliptic curve cryptography.
* **RSA Key Size**: leave default '1', *2048 bits*
* **Control channel cypher**: pick '2' *ECDHE-RSA-AES-256-GCM-SHA384* (not default)
* **DH key type**: pick '2', *DH* (not default)
  * The Acer C720 ChromeBook doesn't support the default setting which uses elliptic curve cryptography.
* **DH key size**: leave default '1', *2048 bits*
* **Digest algorithm**: pick '2', *SHA-384* (not default)
* **Control channel additional security mechanism**: pick '2', *tls-auth* (not default)
  * The Acer C720 ChromeBook doesn't support the default setting with encryption for TLS
* Press return to let the installation and configuration run. It'll install all necessary software packages and configures the OpenVPN server according to the answers to the previous questions.
  * Side note: This sets up:
    * `/etc/openvpn` and inside of that `easy-rsa`
    * `/etc/systemd/system/openvpn@.service`, which is a copy of `/lib/systemd/system/openvpn@.service` with some modifications
    * `/etc/iptables`: `add-openvpn-rules.sh` and `rm-openvpn-rules.sh`
    * `/etc/systemd/system/iptables-openvpn.service` which starts iptables rules
* Once done it asks you to set up your first OpenVPN client. We'll set up the ChromeBook client.
  * **Client name**: &lt;mychromebook> (pick whatever name you want for your ChromeBook OpenVPN client configuration file)
  * **Add passwordless client**: leave default '1'. For this example we won't put a password on the OpenVPN client configuration, but you can if you want to.

Now the setup process is complete and you should have the shell prompt back. The last part of the setup process, client setup, has created a file `<mychromebook>.ovpn` in your home directory on the Raspberry Pi. In order to be a bit more organized I like to create a separate directory where I keep all OpenVPN client files:
```bash
export MYCHROMEBOOK=<mychromebook>
mkdir -p ~/vpn
mv ~/$MYCHROMEBOOK.ovpn ~/vpn/
```
In order to add more clients later just rerun `sudo ./openvpn-install.sh` and choose the option *Add a new user* which will ask you for the next client name.

If the client configuration is for another type of client instead of a ChromeBook, it is quite likely that it could import the \*.ovpn file directly. E.g. the [Tunnelblick client](https://tunnelblick.net/) for MacOSX or the [OpenVPN Connect client](https://play.google.com/store/apps/details?id=net.openvpn.openvpn) for Android can both directly import \*.ovpn files to configure the connection to an OpenVPN server.

## Router Configuration

The Raspberry Pi in your home is typically behind some router which is the interface between the outside world and your home network. When you're out and about, your OpenVPN client machine is on one side of that router whereas your OpenVPN server machine, the Raspberry Pi, is on the other side of that router.

What you need to do is go to your router's configuration page and allow the OpenVPN traffic to pass through. We've set up OpenVPN to use **UDP port 1194**, so find the appropriate router settings, add that port to the allowed traffic, and have the router send it to your Raspberry Pi's internal IP address on your home network.

Since all routers are different I can't give detailed instructions on how to do that on your router. If you can't figure it out by yourself, there should be plenty of instructions floating around the internet that show how to do that for your particular router.

## ChromeBook Setup

Now for the last part, setting up the OpenVPN client on the ChromeBook. Unfortunately ChromeBooks can't import \*.ovpn files directly. Also, their GUI for setting up VPN connections is extremely restrictive, not allowing access to most of the settings we need. ChromeBooks do, however, understand a different type of VPN configuration file called \*.onc file. But they're very picky about this file and give you little help figuring out what the problem is if something goes wrong. What we need to do is convert the \*.ovpn file to a \*.onc file and import that on the ChromeBook.

To do that, first download the `onc_converter.py`:
```
curl -O https://gist.githubusercontent.com/ArturKlauser/ed5af568ed9ccf9be1c0a1ffb833587d/raw/a33f0ac031d44a4dd0f5a8b168308e1be885045d/onc_converter.py
chmod 755 onc_converter.py
```
And then run it on the .ovpn file you generated earlier:
```
./onc_converter.py --infile vpn/$MYCHROMEBOOK.ovpn --name "user-friendly VPN name" --outfile vpn/$MYCHROMEBOOK.onc
```
The *user-friendly VPN name* is the name by which the VPN connection will show up on your ChromeBook later.

Now copy the `vpn/$MYCHROMEBOOK.onc` file to your ChromeBook, e.g. via USB stick, and import it:
* On your ChromeBook, in a new browser window/tab, type: `chrome://net-internals/#chromeos`
* In the 'Import ONC files' section, click 'Choose File'.
* Select your $MYCHROMEBOOK.onc file, e.g. from your USB stick if that is how you are transferring the file.
* In a new browser window/tab, type: `chrome://settings/certificates`
* Click on 'Authorities'.
* Find your CA name, which is of the form org-cn\_\* and click '...' -> 'Edit'.
* Check 'Trust this certificate for identifying websites' and click OK.
* In a new browser window/tab, type: `chrome://settings/networks?type=VPN`
* Verify that you have a 'VPN' entry in the 'Network' section with the *user-friendly VPN name* you set earlier in the .ovpn to .onc conversion process.
* Attempt to connect.
* The first time you will be prompted for a password which isn't actually used for anything (same as the user name) but you must fill in something arbitrary, i.e. you can't leave it blank.
* Scroll to the bottom and make sure that *Saving identity and password* is turned on so the (useless) password is saved and you're not asked again.

That's it, your ChromeBook should be connected to the OpenVPN server running on the Raspberry Pi in your home network. You can see that by the little key symbol next to the network/wifi symbol.

2020–02–03 - [Eddies in Entropy](https://nexus.eddiesinentropy.net/)

## References

This article is partially based on information found in the following references: 
* [Creating an OpenVPN Configuration for ChromeOS](https://gist.github.com/pkutzner/47a2d6f7c4a7df75b2172c68c972841a)
* [OpenVPN on ChromeOS](https://docs.google.com/document/d/18TU22gueH5OKYHZVJ5nXuqHnk2GN6nDvfu2Hbrb4YLE/pub)
* [Open Network Configuration](https://chromium.googlesource.com/chromium/src/+/master/components/onc/docs/onc_spec.md)
* [openvpn-install](https://github.com/angristan/openvpn-install/blob/master/README.md)
* [How to run your own OpenVPN server on a Raspberry PI](https://www.freecodecamp.org/news/running-your-own-openvpn-server-on-a-raspberry-pi-8b78043ccdea/)