The goal of this recipe is to create an OpenVPN setup where the client certificates are signed by a "client-only" CA and the server certificate is signed by a different "server-only" CA. This provides an extra level of operational security, where one person is allowed to create only client certificates, whereas another is allowed to generate only a server certificate. This ensures that the client and server certificates can never be mixed for a Man-in-the-Middle attack.
Set up the server certificate using the first recipe from Chapter 2, Client-server IP-only Networks. Use the client certificate and the intermediary CA certificate from the previous recipe. For this recipe, the server computer was running CentOS 6 Linux and OpenVPN 2.3.10. The client was running Fedora 22 Linux and OpenVPN 2.3.10.
tls-server proto udp port 1194 dev tun server 192.168.200.0 255.255.255.0 ca /etc/openvpn/cookbook/ca+subca.pem cert /etc/openvpn/cookbook/server.crt key /etc/openvpn/cookbook/server.key dh /etc/openvpn/cookbook/dh1024.pem tls-auth /etc/openvpn/cookbook/ta.key 0 persist-key persist-tun keepalive 10 60 user nobody group nobody daemon log-append /var/log/openvpn.log
Save it as example4-9-server.conf
.
[root@server]# openvpn --config example4-9-server.conf
client proto udp remote openvpnserver.example.com port 1194 dev tun nobind tls-auth /etc/openvpn/cookbook/ta.key 1 ca /etc/openvpn/cookbook/ca.crt cert /etc/openvpn/cookbook/IntermediateClient.crt key /etc/openvpn/cookbook/IntermediateClient.key
Save it as example4-9-client.conf
. Note that we did not specify the ca+subca.pem
file in the client configuration.
[root@client]# openvpn --config example4-9-client.conf
... openvpnclient:49283 [IntermediateClient] Peer Connection Initiated with openvpnclient:49283
When the client connects to the server, the client (public) certificate is sent to the server for verification. The server needs to have access to the full certificate chain in order to do the verification; therefore, we stack the root CA certificate and the intermediary CA (or sub-CA) certificate together. This allows the client to connect to the server.
Vice versa, when the client connects, the server (public) certificate is also sent to the client. As the server certificate was originally signed by the root CA, we do not need to specify the full certificate stack here.
Note that if we had forgotten to specify the ca+subca.pem
file in the OpenVPN server configuration file, we would have received an error:
openvpnclient:49286 VERIFY ERROR: depth=0, error=unable to get local issuer certificate: C=US, O=Cookbook 2.4, CN=IntermediateClient
Apart from stacking the CA certificates, it is also possible to stack the CRLs or to use an entirely different mechanism to support multiple CA certificates and their corresponding CRLs.
Another way to include multiple CAs and CRLs in the OpenVPN server configuration is to use the following directive:
capath /etc/openvpn/cookbook/ca-dir
This directory needs to contain all CA certificates and CRLs using a special naming convention:
.0
.r0
For our root CA and intermediary CA, we can achieve this using the following commands:
$ cd /etc/openvpn/cookbook $ mkdir ca-dir $ openssl x509 -hash -noout -in keys/ca.crt bcd54da9
This hexadecimal number bcd54da9
is the hash of the root CA certificate:
$ cp keys/ca.crt ca-dir/bcd54da9.0 $ cp keys/crl.pem ca-dir/bcd54da9.r0
Similarly, for the intermediary CA certificate:
$ openssl x509 -hash -noout -in IntermediateCA/keys/ca.crt 1f5e4734 $ cp IntermediateCA/keys/ca.crt ca-dir/1f5e4734.0 $ cp IntermediateCA/keys/crl.pem ca-dir/1f5e4734.r0
When using many different CA certificates and corresponding CRLs, this method is far easier to manage than the "stacked" files.
3.144.94.220