easy-rsa

sudo apt install easy-rsa
sudo cp /usr/share/easy-rsa /usr/local/
cd /usr/local/easy-rsa/
sudo cp vars.example vars
sudo editor vars

Edit in vars:

set_var EASYRSA_KEY_SIZE        4096
set_var EASYRSA_CERT_EXPIRE     <<time in days>>
set_var EASYRSA_CERT_RENEW      <<time in days>>
cd ..
chown <<user>> easy-rsa
./easy-rsa init-pki
./easyrsa build-ca

Password needed for new certs. Store well. Of course you can always install a new ca.crt on the openVPN server and sign all client certificates again.

In this example, all keys and signing requests are doene on the same system and then distributed to all servers and clients. Can only be done this way, if you have physical access to all systems and can use an usb-stick or similar to load keys on all machines.

./easyrsa build-server-full <keyname> nopass
./easyrsa build-client-full <keyname>
./easyrsa gen-dh

The last command will take quite a while. The build-client-full above generates client keys with password protection. If your client is unable to store that password (for example in the machines password storage), you may want to use the nopass option for client keys as well.

Certificates will be in ./pki/issued/
Private Keys will be in ./pki/private/
Each client will need the ca.crt, its own crt and its own key file.
The server will need the ca.crt, its own crt and key file and the dh.pem

TLS-auth

(Text from community.openvpn.net/openvpn/wiki/Hardening) The --tls-auth option uses a static pre-shared key (PSK) that must be generated in advance and shared among all peers. Generate a PSK with:

openvpn --genkey --secret ta.key

And reference it in the configs as such. The 0/1 value is arbitrary and must be the opposite between peers (or omitted entirely.)

# server-example
--tls-auth ta.key 0
# client-example
--tls-auth ta.key 1