Skip to content

Instantly share code, notes, and snippets.

@pkutzner
Last active November 13, 2022 05:55
Show Gist options
  • Save pkutzner/47a2d6f7c4a7df75b2172c68c972841a to your computer and use it in GitHub Desktop.
Save pkutzner/47a2d6f7c4a7df75b2172c68c972841a to your computer and use it in GitHub Desktop.
Create ChromeOS VPN connection.

Creating an OpenVPN Configuration for ChromeOS

This assumes you already have an OpenVPN server set up that you'll be connecting to. OpenVPN server setup is not covered in this document.

NOTE: ChromeOS is VERY picky about adherance to the ONC filespec (second ref. link). If an option is marked as an integer, and you surround it in quotes, import of the file will fail silently. Booleans (true and false) seem to be an exception wherein you can either wrap, or not, the boolean value in quotes without it failing ¯\_(ツ)_/¯.

References:

ChromeOS supports both L2TP and OpenVPN VPN connections. However, adding an OpenVPN connection, other than a really basic one, is non-trivial, as many options are missing from the GUI; things such as setting the Cipher or the Auth types, setting CompLZO, or any myriad nonstandard options. To allow for configuration of these options, one must build a special file that ChromeOS uses to import these settings. The file is in JSON format, but Google calls it "Open Network Configuration". As such, the file you will be creating should have a .onc extension on it.

Pre-Preparation

You'll need:

  • A copy of the OpenVPN server's CA certificate, if it wasn't issued by a trusted CA.
  • A copy of the user's PKCS12 file, if required.
  • A copy of the OpenVPN TLS key, if required.
  • A copy of the user's cert file, if required.
  • A copy of the .ovpn file to translate settings from.

Depending on how you received your openvpn configuration, you might have any of the above required files.

If you only received a PCKS12 file, you can use the following commands to extract the client and CA certs as x509/pem and also format them in the way they'll need to be used in the .onc file:

  • openssl pkcs12 -in client.p12 -clcerts -nodes -nokeys | openssl x509 -out client.crt
  • openssl pkcs12 -in client.p12 -cacerts -nodes -nokeys | openssl x509 -out ca.crt

If you only received a cert and key file, you can use the following command to create a PKCS12 file:

  • openssl pkcs12 -export -in client.crt -inkey client.key -certfile ca.crt -name "FRIENDLY NAME" -out client.p12
    • Hit 'Return' 2x to save p12 without a password
  • Verify contents of p12 file using the following command:
    • openssl pkcs12 -nodes -info -in client.p12
    • Hit Enter when prompted for the password.
  • Format the client, CA, and TLS files for use in the .onc file. The certificates must be single strings. The CA cert should contain its BEGIN and END lines, the client certificate should not, and the TA key file should have its CR/LF characters converted to literal '\n' in the string. The following command lines do that for us:
    • Client Cert: perl -pe 's/^-.*$//s;' -pe 's/\r?\n//;' < client.crt > newfile.crt
    • CA Cert: perl -pe 's/\r?\n//;' < ca.crt > newcafile.crt
    • TA Key: grep -v '#' tls.key | perl -pe 's/\r?\n/\\n//;' > newtls.key
  • Generate 3 unique UUIDs. They don't need to be specific, just unique:

Create your .onc file

Open an editor and create a new file with whatever name you want and an .onc extension with the following contents:

{
    "Type": "UnencryptedConfiguration",
    "Certificates": [
        {
            "GUID": "{cacert-UUID}",
            "Type": "Authority",
            "X509": "PASTE CONTENTS OF newcafile.crt HERE"
        },
        {
            "GUID": "{clientcert-UUID}",
            "Type": "Client",
            "PKCS12": "PASTE CONTENTS OF newfile.crt HERE"
        }
    ],
    "NetworkConfigurations": [
        {
            "GUID": "{network-UUID}",
            "Name": "Name of VPN Connection",
            "Type": "VPN",
            "VPN": {
                "Type": "OpenVPN",
                "Host": "HOST_NAME_OR_IP",
                "OpenVPN": {
                    "Auth": "STRING", #(e.g. SHA256, default: SHA1)
                    "Cipher": "STRING", #(e.g. AES-256-CBC default: BF-CBC)
                    "ClientCertType": "Ref",
                    "CompLZO": "adaptive", #(default: adaptive, but can be true, false, or adaptive)
                    "NsCertType": "server",
                    "Port": 1194, # OpenSSL server port (default: 1194)
                    "Proto": "udp", #OpenSSL protocol (default: udp)
                    "SaveCredentials": true,  #(default: false)
                    "ServerCARef": "{cacert-UUID}",
                    "ClientCertRef": "{clientcert-UUID}",
                    "Verb": "3",
                    "ServerPollTimeout": 360,
                    "Username": "STRING", #Pre-populate username
                    "KeyDirection": "1",
                    "TLSAuthContents": "PASTE CONTENTS OF newtls.key HERE"
                }
            }
        }
    ]
}

Copy your ca.crt, client.p12, and filename.onc files either to your Google Drive, or to a USB key, then perform the following:

  • In ChromeOS, in a new browser window/tab, type: chrome://settings/certificates
  • Click on 'Authorities'
  • Click on 'Import'
  • Choose your ca.crt file either from Google Drive, or your USB key.
  • Check 'Trust this certificate for identifying websites.'
  • Click on 'Your Certificates' at the top of the page.
  • Click on 'Import and Bind'
  • Choose your client.p12 file, hitting enter at all the prompts.
  • In the URL field, type: chrome://net-internals/#chromeos
  • In the 'Import ONC files' section, click 'Choose File'
  • Select your .onc file
  • In the URL field, type: chrome://settings/networks?type=VPN
  • Verify that you have a 'VPN' entry in the 'Network' section.
  • Attempt to connect. You will be prompted for your password.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment