Install, and build a PKI
Installing OpenVPN on Debian is one command, and the real work is the public key infrastructure (PKI): a small certificate authority that signs a certificate for the server and one for each user. Debian packages easy-rsa for exactly this.
apt install openvpn easy-rsa
The lab image installs both at build time; these are the versions this lesson was tested with.
Build the CA and the certificates
make-cadir creates a private copy of easy-rsa in your home directory, so the CA's files never live inside a package directory. Then:
init-pkicreates an empty PKI.build-cacreates the CA: a private key and a self-signed certificate. Everything else trusts this key, so protect it.build-server-full servercreates and signs the server's key and certificate.build-client-full alicedoes the same for each user. One certificate per user means one user can be removed without touching anyone else.gen-crlcreates the certificate revocation list (CRL): the list of certificates the server must refuse. It starts empty.
The lab uses --batch and nopass so it can be scripted. On a real server, give the CA key a passphrase (leave out nopass on build-ca), and ideally keep the CA on a separate machine that only ever signs requests. Anyone with the CA key can mint a valid user.
The tls-crypt key
openvpn --genkey secret makes one more key, shared by the server and every user. With tls-crypt, every packet of the TLS handshake is encrypted and authenticated with it, so the server silently ignores anyone who doesn't have it: port scanners, attackers probing for TLS bugs, or someone who found an old certificate. It also hides which certificate a user presents from anyone watching the network.
root@vpn:~# cat /etc/debian_version; dpkg-query -W openvpn easy-rsa nftables
13.7
easy-rsa 3.2.2-1
nftables 1.1.3-1
openvpn 2.6.14-1+deb13u3- Line 2: Debian 13 (trixie).
- Lines 3–5: easy-rsa 3.2, nftables 1.1 and OpenVPN 2.6, from Debian's own repository.
root@vpn:~# make-cadir ~/easy-rsa && ls ~/easy-rsa
easyrsa
openssl-easyrsa.cnf
vars
x509-types
root@vpn:~/easy-rsa# ./easyrsa init-pki
Using Easy-RSA 'vars' configuration:
* /root/easy-rsa/vars
Notice
------
'init-pki' complete; you may now create a CA or requests.
Your newly created PKI dir is:
* /root/easy-rsa/pki
Using Easy-RSA configuration:
* /root/easy-rsa/vars
root@vpn:~/easy-rsa# ./easyrsa --batch --req-cn="TTR Lab VPN CA" build-ca nopass
Using Easy-RSA 'vars' configuration:
* /root/easy-rsa/vars
[... 2 lines trimmed: key generation progress ...]
Notice
------
CA creation complete. Your new CA certificate is at:
* /root/easy-rsa/pki/ca.crt
Create an OpenVPN TLS-AUTH|TLS-CRYPT-V1 key now: See 'help gen-tls'
Build-ca completed successfully.
root@vpn:~/easy-rsa# ./easyrsa --batch build-server-full server nopass
Using Easy-RSA 'vars' configuration:
* /root/easy-rsa/vars
[... 2 lines trimmed: key generation progress ...]
-----
Notice
------
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /root/easy-rsa/pki/reqs/server.req
* key: /root/easy-rsa/pki/private/server.key
Using configuration from /root/easy-rsa/pki/5c863e2b/temp.6.1
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'server'
Certificate is to be certified until Jan 23 05:17:34 2029 GMT (825 days)
Write out database with 1 new entries
Database updated
Notice
------
Inline file created:
* /root/easy-rsa/pki/inline/private/server.inline
Notice
------
Certificate created at:
* /root/easy-rsa/pki/issued/server.crt
root@vpn:~/easy-rsa# for u in alice bob branch; do ./easyrsa --batch build-client-full $u nopass; done
Using Easy-RSA 'vars' configuration:
* /root/easy-rsa/vars
[... 2 lines trimmed: key generation progress ...]
-----
Notice
------
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /root/easy-rsa/pki/reqs/alice.req
* key: /root/easy-rsa/pki/private/alice.key
Using configuration from /root/easy-rsa/pki/1264e4b7/temp.6.1
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'alice'
Certificate is to be certified until Jan 23 05:17:34 2029 GMT (825 days)
Write out database with 1 new entries
Database updated
Notice
------
Inline file created:
* /root/easy-rsa/pki/inline/private/alice.inline
Notice
------
Certificate created at:
* /root/easy-rsa/pki/issued/alice.crt
[... 67 lines trimmed: the same output for bob and branch ...]
root@vpn:~/easy-rsa# ./easyrsa gen-crl
Using Easy-RSA 'vars' configuration:
* /root/easy-rsa/vars
Using configuration from /root/easy-rsa/openssl-easyrsa.cnf
Notice
------
An updated CRL DER copy has been created:
* /root/easy-rsa/pki/crl.der
An updated CRL has been created:
* /root/easy-rsa/pki/crl.pem
IMPORTANT: When the CRL expires, an OpenVPN Server which uses a
CRL will reject ALL new connections, until the CRL is replaced.
root@vpn:~/easy-rsa# ls pki pki/issued pki/private
pki:
ca.crt
certs_by_serial
crl.der
crl.pem
index.txt
index.txt.attr
index.txt.attr.old
index.txt.old
inline
issued
private
reqs
revoked
serial
serial.old
vars.example
pki/issued:
alice.crt
bob.crt
branch.crt
server.crt
pki/private:
alice.key
bob.key
branch.key
ca.key
server.key- Lines 1–5: A private copy of easy-rsa in root's home, with its own
varssettings file. - Lines 21–33: The CA:
ca.crt(public, given to everyone) andca.key(secret, signs everything). The lab skips the passphrase; a real CA shouldn't. - Lines 36–68: The server's key and certificate, signed by the CA. Valid for 825 days, easy-rsa's default.
- Lines 71–105: One certificate per user. Each can be revoked on its own later.
- Lines 107–121: The certificate revocation list, empty for now. Note easy-rsa's warning about it expiring.
- Lines 143–154: What you end up with. Everything in
private/stays secret;ca.keymost of all.
Check your understanding
Why give every user their own certificate, instead of one shared certificate for the whole team?
- So one person can be removed by revoking their certificate, without reissuing everyone else's.
- Because OpenVPN refuses two connections with the same certificate.
- Shared certificates are slower.
- To avoid needing a CA.