---
title: 'Tutorial: Configure External PKI with Access Server''s certool Script'
canonical: https://openvpn.net/as-docs/tutorials/tutorial--epki/
product: Access Server Docs
description: How to set up the Access Server External PKI (Public Key Infrastructure) feature with the certool.
---

# Tutorial: Configure External PKI with Access Server's certool Script

## Overview

The Access Server external public key infrastructure (PKI) feature integrates Access Server with third-party tools for X.509 PKI management instead of using the built-in certificate management capabilities.

When configured for external PKI usage, Access Server doesn't manage client certificates directly; instead, the customer's third-party PKI software generates and distributes client certificate/key pairs to client machines and a server certificate/key pair to the OpenVPN server.

This tutorial shows you how to set up external PKI using Access Server's **certool**

When you use a third-party tool outside of Access Server, refer to the software's documentation for specific instructions. Here we outline the steps and provide an example using Access Server's **certool** script. With **certool**, you can create your own new PKI structure, as described in these instructions.

At a high level, these are the steps for your configuration:

1. Modify **as.conf** to set Access Server in external PKI mode.
2. Create certificate/key pair with external PKI tool.
3. Create the **TLS\_auth** key.
4. Generate Diffie Hellman parameters.
5. Import the necessary certificate and key files.
6. Provide certificate/key pairs to VPN client and server.

When configuring your Access Server in production, follow these high-level steps using your third-party PKI tool. We provide an example below using Access Server’s **certool** script, so the steps pertain to that tool.

## Prerequisites

- An installed Access Server.
- An external PKI tool.
- Console access and the ability to get root access.
- An OpenVPN client that supports the macOS Keychain and Windows certificate store.

  > **Note**
  >
  > OpenVPN Connect supports the macOS Keychain and the Windows certificate store as valid sources to fetch the client certificate.
  >
  > When the user attempts to connect using a profile set up for external PKI, the client backend enumerates the user's host OS certificate store and automatically selects the certificate/key pair issued by Access Server. If more than one certificate/key pair is eligible, the certificate with the latest expiration date is used.

## Step 1: Set Access Server to external PKI mode.

1. Connect to the Access Server console and get root privileges.
2. Edit **as.conf** for external PKI usage:

   ```
   nano /usr/local/openvpn_as/etc/as.conf
   ```
3. Comment out **certs\_db**:

   ```
   # certificates database
   # certs_db=sqlite:///~/db/certs.db
   ```
4. Save and exit the file — Ctrl-X, Y, then Enter.
   - Access Server no longer uses the certificate database. Instead, an external system must handle this.

## Step 2: Create the necessary PKI files

1. Initialize the external PKI files in the **epki** directory, including the CA cert/key:

   ```
   cd /usr/local/openvpn_as/scripts
   mkdir -p epki/root
   ```
2. Create a root cert for signing intermediate CAs:

   ```
   ./certool --dir epki/root --cn "EPKI Root Test" --type ca
   ```
3. Create the intermediate CA:

   ```
   ./certool --dir epki/root --type intermediate --serial 1 --cn "EPKI Intermediate" --name inter
   cp epki/root/inter.crt epki/ca.crt
   cp epki/root/inter.key epki/ca.key
   cat epki/root/ca.crt epki/ca.crt >epki/cabundle.crt
   ```
4. Create a certificate/key pair for the OpenVPN server:

   ```
   ./certool --dir epki --type server --serial 1 --cn server
   ```
5. Create a **tls\_auth** key for the OpenVPN server:

   ```
   ./certool --dir epki --tls_auth
   ```
6. Generate Diffie Hellman parameters for the OpenVPN server:

   ```
   openssl dhparam -out epki/dh.pem 2048
   ```
7. Load the newly generated files into the Access Server config database:

   ```
   ./sacli --key "external_pki.ta_key" --value_file epki/ta.key ConfigPut
   ./sacli --key "external_pki.ca_crt" --value_file epki/cabundle.crt ConfigPut
   ./sacli --key "external_pki.server_crt" --value_file epki/server.crt ConfigPut
   ./sacli --key "external_pki.server_key" --value_file epki/server.key ConfigPut
   ./sacli --key "external_pki.dh_pem" --value_file epki/dh.pem ConfigPut
   ```
8. For Access Server 2.7 and newer, you must also generate your auth token and add the generated file:

   ```
   ./certool --dir epki --auth_token
   ./sacli --key "external_pki.auth_token_key" --value_file epki/auth_token.key ConfigPut
   ```
9. Configure X509 explicit/extended key usage based on RFC3280 TLS Rules:

   ```
   ./sacli --key "external_pki.remote_cert_usage" --value eku ConfigPut
   ```
10. Configure the use of the X509 “role” attribute for the declaration of auto-login permission:

    ```
    ./sacli --key "external_pki.autologin_x509_spec" --value "role,,AUTOLOGIN" ConfigPut
    ```
11. Generate the tls-crypt-v2 key (for Access Server 2.9.0 and higher only):

    ```
    ./certool --dir epki --tls_crypt2_server
    ./sacli --key "external_pki.tls_cryptv2_server" --value_file epki/tls_crypt2.key ConfigPut
    ```
12. Restart Access Server:

    ```
    systemctl restart openvpnas
    ```

> **Important**
>
> When using an external PKI tool, designate all certificates generated by your PKI management tool as explicitly client or server. This protects against a man-in-the-middle attack where a client certificate could be used to impersonate the server. There are two ways to do this:
>
> 1. X509 explicit/extended key usage based on RFC3280 TLS rules. Configure as follows: `./sacli --key "external_pki.remote_cert_usage" --value eku ConfigPut`
> 2. Netscape certificate type (deprecated). Configure as follows: `./sacli --key "external_pki.remote_cert_usage" --value ns ConfigPut` or for version 2.9.0 and newer, `./sacli --key "external_pki.remote_cert_usage" --value ns-cert ConfigPut`

## Step 3: Configure a test client

To test our example, we generate a test client, **etest**.

1. Sign in to the Admin Web UI.
2. Click **User Management \> User Permissions**.
3. Create the new user, **etest**, and click **More Settings** to enter a password.
4. Select **Save Settings** and **Update Running Server**.
5. From the console, generate a cert/key pair for **etest**:

   ```
   ./certool --dir epki --type client --serial 2 --cn etest --cabundle epki/cabundle.crt --pkcs12
   ```

   - The key is encrypted with a password you enter at the prompt, and **certool** generates the file **epki/etest.p12**, which contains the cert/key pair.
6. To test auto-login, generate an auto-login cert/key pair for **etest**:

   ```
   ./certool --dir epki --type client --serial 3 --cn etest --name etestauto --cabundle epki/cabundle.crt --pkcs12 role=AUTOLOGIN
   ./sacli --user etest --key prop_autologin --value true UserPropPut
   ```
7. Finally, generate a server-locked profile. The profile will be stored in **client.ovpn**:

   ```
   ./sacli GetGeneric >client.ovpn
   ```

   > **Important**
   >
   > Starting from 2.12.0, **certool** doesn't allow generating user certificates with empty passphrases. If you still want to generate a user's certificate with an empty passphrase, you can do so using the **openssl** command-line tool. Or you can remove the passphrase from a generated .p12 file using the **openssl** command-line tool:
   >
   > ```
   > openssl pkcs12 -in epki/etest.p12 -nodes -out epki/temp.pem ## Enter passphrase and press enter
   > openssl pkcs12 -export -in epki/temp.pem -out epki/etest_nopass.p12 ## Press Enter twice
   > rm epki/temp.pem
   > ```
8. Copy these three files to the client machine:

   |  |  |
   | --- | --- |
   | **epki/etest.p12:** | The userlogin cert/key pair for user **etest**. |
   | **epki/etestauto.p12:** | The autologin cert/key pair for user **etest**. |
   | **client.ovpn:** | The server-locked profile for the Access Server. |

   > **Tip**
   >
   > In a production setting, the client cert/key pairs (the **.p12** files) are distributed to clients using the external PKI tool. The **client.ovpn** is distributed in the same manner as existing server-locked profiles:
   >
   > - Using OpenVPN Connect.
   > - Using a client software push capability — for example, on macOS, you can generate a pre-configured client installer, ‘mac\_v3’, with the server-locked profile:
   >   - For Access Server 2.12.0 and newer:
   >
   >     ```
   >     ./sacli --dest_dir=[DESTINATION-DIRECTORY] --itype=mac_v3 --profile_type=serverlocked GenerateInstaller
   >     ```
   >   - For Access Server 2.11.x and older:
   >
   >     ```
   >     ./sacli --itype mac_v3 -o . GetGenericInstaller
   >     ```
9. Install the certificate/key pair:
   - Launch OpenVPN Connect v3.
   - Import the connection profile, **client.ovpn**.
   - Select the **Menu** icon.
   - Select **Certificate & Tokens**.
   - Under **PKCS#12**, select the **Add** icon.
   - Select your Client P12 File (etest.p12).
   - Enter the password previously configured, then select **OK**.
   - Select **My Profiles** and edit the profile.
   - Under **Certificates**, use the **Select** button to add the external certificate to the profile.
   - Select the p12 file.
   - Select **Save Changes**.
   - Select **Connect** to start the profile connection.

## Simplified ePKI client configuration (Access Server 2.14.2 and later)

With the release of Access Server 2.14.2, we've made configuring client connection profiles for ePKI easier. Previously, creating these profiles required using the command line, as noted in the tutorial. However, in version 2.14.2 and later, you can now create and manage ePKI client connection profiles directly from Access Server's Client Web UI.

There are two types of ePKI profiles available:

1. **Generic ePKI profile:**
   - This profile requires the user to authenticate with a password when connecting.
   - Ideal for environments where a password-based security layer is needed in addition to certificate-based authentication.
2. **Auto-login ePKI profile;**
   - This profile automatically uses the certificate for authentication without requiring a password.
   - Suitable for unattended devices or systems where automatic, certificate-based login is needed.

In addition, the **Import Profile from URL** functionality in **OpenVPN Connect** allows users to import these connection profiles directly, making the configuration process faster and more seamless.

This update simplifies the ePKI setup, providing more flexibility and reducing the reliance on the command line.

## Certificate naming conventions

Currently, Access Server uses the following client certificate naming conventions:

1. The Common Name of the certificate must match the username of the connecting client.
2. Autologin certificates, which don't require username/password authentication (only client certificate authentication), must be tagged to indicate that they hold this right.

   > **Tip**
   >
   > In the example above, the X509 role attribute is set to `AUTOLOGIN`. To enable autologin in Access Server based on this attribute, modify the configuration with the following command:
   >
   > ```
   > ./sacli --key "external_pki.autologin_x509_spec" --value "role,,AUTOLOGIN" ConfigPut
   > ```
   >
   > This command tells Access Server to enable autologin if the `role` X509 attribute contains the substring `AUTOLOGIN`. If the `external_pki.autologin_x509_spec` setting is omitted, autologin will be disabled.
   >
   > The `external_pki.autologin_x509_spec` string has the following format:
   >
   > ```
   > <X509 Attribute>,<optional flags>,<enabling substring in attribute value>
   > ```
   >
   > Note that the flags parameter is reserved for future use and isn't currently implemented. For example, if `external_pki.autologin_x509_spec` is set to `"role,,AUTOLOGIN"`, Access Server will only allow autologin connections from client certificates where the `role` attribute contains the substring `AUTOLOGIN`.

## Advanced features

### Split CA, i.e. using a separate CA chain for client and server certificates

By default, one CA chain is assumed for both client and server certificates. To use a separate chain for each:

1. Enable split CA mode:

   ```
   ./sacli --key "external_pki.remote_cert_usage" --value split ConfigPut
   ```
2. Replace the following line (from above):

   ```
   ./sacli --key "external_pki.ca_crt" --value_file <CA_CERT_BUNDLE&> ConfigPut
   ```

   with:

   ```
   ./sacli --key "external_pki.server_ca_crt" --value_file <SERVER_CA_CERT_BUNDLE> ConfigPut
   ./sacli --key "external_pki.client_ca_crt" --value_file <CLIENT_CA_CERT_BUNDLE> ConfigPut
   ```
3. Then restart the service:

   ```
   ./sacli start
   ```

You don’t need to mark certificates as client or server when using split CA mode. Therefore, settings for Netscape certificate type or X509 explicit/extended key usage based on RFC3280 TLS rules can be omitted.

### Controlling CN/username requirement

By default, client logins must use a username that matches the Common Name on the client certificate. This requirement may be dropped by disabling the external\_pki.cn\_username\_requirement boolean key:

```
./sacli -k external_pki.cn_username_requirement -v false ConfigPut
```

### Error Message

```
"'Parameter \"external_pki.auth_token_key\" is missing from the configuration database. For more information, please visit the following URL: https://openvpn.net/static-links/documentation-external-pki': util/cdict:286,util/cdict:258,util/cdict:522,util/cdict:555 (exceptions.KeyError)"
```

**Issue:** This error occurs when upgrading an Access Server configured for external public key infrastructure (ePKI) from a version lower than 2.7 to version 2.7 and higher. This is expected behavior because this configuration key was missing for versions before 2.7 and must be added after you upgrade. You’ll also see “service failed to start or returned error status” in your log messages.

**Resolution:** This error can be resolved by running these commands with root privileges:

```
cd /usr/local/openvpn_as/scripts
mkdir epki
./certool --dir epki --auth_token
./sacli --key "external_pki.auth_token_key" --value_file epki/auth_token.key ConfigPut
```

Then restart the service:

```
systemctl start openvpnas
```

---

Prev: [Tutorial: How to Replace 1024-bit VPN Certificates for Access Server](https://openvpn.net/as-docs/tutorials/tutorial--replace-1024-bit-vpn-certificate.md)
Next: [Tutorial: Configure External PKI with OpenSSL](https://openvpn.net/as-docs/tutorials/tutorial--epki-with-openssl.md)
Index: https://openvpn.net/as-docs/llms.txt
