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

# Tutorial: Configure External PKI with OpenSSL

## 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 an external PKI using **OpenSSL**.

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 the server CA using OpenSSL commands.
3. Generate the server certificate and key via OpenSSL commands.
4. Generate the client certificate and key via OpenSSL commands.
5. Create the **TLS\_auth** key.
6. Generate Diffie-Hellman parameters.
7. Import the necessary certificate and key files to Access Server.
8. Provide certificate/key pairs in a P12/PFX file to the VPN client.
9. Generate and download a server-locked profile for the client.

## Prerequisites

- An installed Access Server.
- A machine with OpenSSL installed. This could be the same Linux where Access Server is installed or an external machine.
- Console access and the ability to get root access.
- An OpenVPN client that supports the macOS Keychain and Windows certificate store.

## 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: Generate the CA key and certificate via OpenSSL commands

1. Run the below command to generate the CA key:

   ```
   openssl genpkey -algorithm RSA -out ca.key -pkeyopt rsa_keygen_bits:2048
   ```
2. Run the below command to generate the CA certificate:

   ```
   openssl req -new -x509 -key ca.key -out ca.crt -days 3650 -subj "/CN=OpenVPN CA"
   ```

   - From the above commands, you get two files:
     1. CA key (ca.key)
     2. CA certificate (ca.crt)

## Step 3: Create a custom OpenSSL file for the server

1. Copy the default OpenSSL configuration file to a new file named `openssl-server.cnf`:

   ```
   OUT="/etc/ssl/openssl-server.cnf"
   cp /etc/ssl/openssl.cnf "$OUT"
   ```
2. Update the **\[ req \]** section:

   ```
   sed -i '/^\[ req \]/,/^\[/{/req_extensions/ d}' "$OUT"
   sed -i '/^\[ req \]/,/^\[/{/x509_extensions/ a\
   req_extensions = v3_req
   }' "$OUT"
   ```
3. Update the **\[ v3\_req \]** section:

   ```
   sed -i '/^\[ v3_req \]/,/^\[/{s/basicConstraints.*/basicConstraints = critical, CA:FALSE/}' "$OUT"
   sed -i '/^\[ v3_req \]/,/^\[/{s/keyUsage.*/keyUsage = critical, digitalSignature, keyEncipherment/}' "$OUT"
   sed -i '/^\[ v3_req \]/,/^\[/{/extendedKeyUsage/ d}' "$OUT"
   sed -i '/keyUsage = critical, digitalSignature, keyEncipherment/ a\
   extendedKeyUsage = serverAuth
   ' "$OUT"
   ```

## Step 4: Create a custom OpenSSL file for clients

1. Copy the default OpenSSL configuration file to a new file named `openssl-client.cnf`:

   ```
   OUT="/etc/ssl/openssl-client.cnf"
   cp /etc/ssl/openssl.cnf "$OUT"
   ```
2. Update the **\[ req \]** section:

   ```
   sed -i '/^\[ req \]/,/^\[/{/req_extensions/ d}' "$OUT"
   sed -i '/^\[ req \]/,/^\[/{/x509_extensions/ a\
   req_extensions = v3_req
   }' "$OUT"
   ```
3. Update the **\[ v3\_req \]** section:

   ```
   sed -i '/^\[ v3_req \]/,/^\[/{s/basicConstraints.*/basicConstraints = critical, CA:FALSE/}' "$OUT"
   sed -i '/^\[ v3_req \]/,/^\[/{s/keyUsage.*/keyUsage = critical, digitalSignature/}' "$OUT"
   sed -i '/^\[ v3_req \]/,/^\[/{/extendedKeyUsage/ d}' "$OUT"
   sed -i '/^\[ v3_req \]/,/^\[/{/nsCertType/ d}' "$OUT"
   sed -i '/keyUsage = critical, digitalSignature/ a\
   extendedKeyUsage = clientAuth
   ' "$OUT"
   sed -i '/extendedKeyUsage = clientAuth/ a\
   nsCertType = client
   ' "$OUT"
   ```

## Step 5: Generate the server key and certificate via OpenSSL commands

1. Run the below command to generate the server key:

   ```
   openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048
   ```
2. Run the below command to generate the server CSR with the server key and the custom OpenSSL file created in [Step 3](https://openvpn.net/as-docs/tutorials/tutorial--epki-with-openssl/#step-3--create-a-custom-openssl-file-for-the-server):

   ```
   openssl req -new -key server.key -out server.csr -subj "/CN=OpenVPN Server" -config /etc/ssl/openssl-server.cnf
   ```
3. Run the below command to generate the server certificate with the custom OpenSSL file created in [Step 3](https://openvpn.net/as-docs/tutorials/tutorial--epki-with-openssl/#step-3--create-a-custom-openssl-file-for-the-server):

   ```
   openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -extfile /etc/ssl/openssl-server.cnf -extensions v3_req
   ```

   - From the above commands, you get three files:
     1. Server key (server.key)
     2. Server certificate (server.crt)
     3. Server CSR (server.csr)

## Step 6: Generate the client key, certificate, and P12 file via OpenSSL commands

1. Run the below command to generate the client key:

   ```
   openssl genpkey -algorithm RSA -out client.key -pkeyopt rsa_keygen_bits:2048
   ```
2. Run the below command to generate the client CSR with the client key and the custom OpenSSL file created in [Step 4](https://openvpn.net/as-docs/tutorials/tutorial--epki-with-openssl/#step-4--create-a-custom-openssl-file-for-clients):

   ```
   openssl req -new -key client.key -out client.csr -subj "/CN=etest" -config /etc/ssl/openssl-client.cnf
   ```
3. (Optional) Test test auto-login, generate an auto-login cert/key pair for **etest**:

   ```
   openssl req -new -key client.key -out client.csr -subj "/role=AUTOLOGIN/CN=etest" -config /etc/ssl/openssl-client.cnf
   ```
4. Run the below command to generate the client certificate with the custom OpenSSL file created in [Step 4](https://openvpn.net/as-docs/tutorials/tutorial--epki-with-openssl/#step-4--create-a-custom-openssl-file-for-clients):

   ```
   openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -extfile /etc/ssl/openssl-client.cnf -extensions v3_req
   ```
5. Generate a P12 file with the client certificate and key:

   ```
   openssl pkcs12 -export -inkey client.key -in client.crt -out etest.p12 -name "etest"
   ```
6. You will be prompted to insert a password for the P12 file. Type it twice.
   - From the above commands, you get four files:
     1. Client key (client.key)
     2. Client certificate (client.crt)
     3. Client CSR (client.csr)
     4. Client P12 file (etest.p12)

   > **Tip**
   >
   > If you encounter a 'friendlyName' import error, refer to this support article: [OpenVPN Connect v3.5.x Certificate/Key Import Error When "friendlyName" is Missing in the P12 File](https://support.openvpn.com/hc/en-us/articles/30763012369563-OpenVPN-Connect-v3-5-x-Certificate-Key-Import-Error-When-friendlyName-is-Missing-in-the-P12-File).

## Step 7: Configure the necessary files on Access Server

1. Connect to the Access Server console and get root privileges.
2. Create a directory:

   ```
   mkdir epki && cd epki
   ```
3. Place the CA certificate, server certificate, and key generated from the OpenSSL commands in the new **epki** directory:

   ```
   cp ../ca.crt ./
   cp ../server.crt ./
   cp ../server.key ./
   ```
4. Create a **tls\_auth** key for the OpenVPN server:

   ```
   /usr/local/openvpn_as/scripts/certool --tls_auth
   ```
5. Generate Diffie Hellman parameters for the OpenVPN server:

   ```
   openssl dhparam -out dh.pem 2048
   ```
6. For Access Server 2.7 and newer, you must also generate your auth token and add the generated file:

   ```
   /usr/local/openvpn_as/scripts/certool --auth_token
   ```
7. Configure X509 explicit/extended key usage based on RFC3280 TLS rules:

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

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

   ```
   /usr/local/openvpn_as/scripts/certool --tls_crypt2_server
   ```
10. Load the newly generated files into the Access Server config database:

    ```
    /usr/local/openvpn_as/scripts/sacli --key "external_pki.ta_key" --value_file ta.key ConfigPut
    /usr/local/openvpn_as/scripts/sacli --key "external_pki.ca_crt" --value_file ca.crt ConfigPut
    /usr/local/openvpn_as/scripts/sacli --key "external_pki.server_crt" --value_file server.crt ConfigPut
    /usr/local/openvpn_as/scripts/sacli --key "external_pki.server_key" --value_file server.key ConfigPut
    /usr/local/openvpn_as/scripts/sacli --key "external_pki.dh_pem" --value_file dh.pem ConfigPut
    /usr/local/openvpn_as/scripts/sacli --key "external_pki.auth_token_key" --value_file auth_token.key ConfigPut
    /usr/local/openvpn_as/scripts/sacli --key "external_pki.tls_cryptv2_server" --value_file tls_crypt2.key ConfigPut
    ```
11. Start Access Server:

    ```
    systemctl restart openvpnas
    ```

## Step 8: Configure a test client

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

1. Sign in to the Admin Web UI.
2. Select **User Management → User Permissions**.
3. Create the new user, **etest**, and select **More Settings** to enter a password.
4. Select **Save Settings** and **Update Running Server**.
5. Generate a server-locked profile. The profile will be stored in **etest.ovpn**:

   ```
   /usr/local/openvpn_as/scripts/sacli GetGeneric >etest.ovpn
   ```
6. Copy these two files to the client machine:
   - Client P12 file (etest.p12)
   - Client profile (etest.ovpn)
7. Install the profile and P12 file in OpenVPN Connect v3:
   1. Launch OpenVPN Connect v3.
   2. Import the connection profile, **etest.ovpn**.
   3. Select **Certificate & Tokens**.
   4. Under **PKCS#12**, select the **Add** icon.
   5. Select your client P12 file **etest.p12**.
   6. Enter the password you configured for this file in Step 6, then click OK.
   7. Select **My Profiles** and edit the profile.
   8. Under **Certificates**, use the **Select** button to add the external certificate to the profile.
   9. Select the P12 file.
   10. Select **Save Changes**.
   11. 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.

---

Prev: [Tutorial: Configure External PKI with Access Server's certool Script](https://openvpn.net/as-docs/tutorials/tutorial--epki.md)
Next: [Tutorial: Configure External PKI with Microsoft Active Directory Certificate Services (AD CS)](https://openvpn.net/as-docs/tutorials/tutorial--epki-with-microsoft-ad-cs.md)
Index: https://openvpn.net/as-docs/llms.txt
