I'm running an OpenVPN-server for some IoT-devices and many of those devices need their certificates replaced because the old ones expire. Updating those certificates is a fragile, manual process using slow mobile connections and additionally those devices can be accessed using OVPN only. For this reason, I want to make extra sure that the certificates have been replaced successfully and new connections are established using those. The problem is that I'm unable to find a somewhat easy way to get enough details from OVPN to e.g. see the serials or issue time of of the replaced certs.
So, how to log details of certificates for each connection in OpenVPN?
Best would be some additional column in the status log, but even --status-version 2 doesn't seem to provide any additional details from the certs. Things like common name of the certs are the same between old and new ones. Is there any support for additional custom columns based on internally available data?
I've additionally increased the log level up to 9, but besides logging lot of low level packet-related stuff, I didn't see any additional certificates details of clients as well. Depending on the log level, things could be easily missed, though, so something logging only those certificate details itself would be preferred anyway.
Concepts like "--client-connect" and "--learn-address" seem to provide common names as well only. Additionally, because things are of temporary interest only, I would like to avoid implementing some too custom software for this case.
Thanks!
How to log details of certificates for each connection in OpenVPN?
Moderators: TinCanTech, TinCanTech, TinCanTech, TinCanTech, TinCanTech, TinCanTech
Forum rules
Please use the [oconf] BB tag for openvpn Configurations. See viewtopic.php?f=30&t=21589 for an example.
Please use the [oconf] BB tag for openvpn Configurations. See viewtopic.php?f=30&t=21589 for an example.
-
- OpenVpn Newbie
- Posts: 17
- Joined: Tue Jan 28, 2020 7:47 pm
-
- OpenVpn Newbie
- Posts: 17
- Joined: Tue Jan 28, 2020 7:47 pm
Re: How to log details of certificates for each connection in OpenVPN?
My question contains two parts actually: How to log something of interest and how to achieve my goal of making sure no old certificate is used anymore. So the answer differs as well.
Logging
While I didn't find a simple configuration to log additional details like cert serials, that can be implemented customly with the help of --tls-verify. That expects a script and for that script OVPN sets multiple environment variables, e.g. containing the serial of some cert.
> --tls-verify cmd Run command cmd to verify the X509 name of a pending TLS connection that has otherwise passed all other tests of certification (except for revocation via –crl-verify directive; the revocation test occurs after the –tls-verifytest).
The supported environment variables:
While not strictly logging, --tls-export-cert might be of interest as well, because it makes the whole cert of some client available at the server for detailed analysis in theory.
> --tls-export-cert directory Store the certificates the clients uses upon connection to this directory. This will be done before –tls-verify is called. The certificates will use a temporary name and will be deleted when the tls-verify script returns. The file name used for the certificate is available via the peer_cert environment variable.
Reject invalid certs
My ultimate goal is to make sure that a replaced certificate is used as expected. One approach doing so is using a certificate revocation list and OVPN supports a very easy way to do so: One doesn't need any concrete file format or such with the certs, but can simply add some file names to some configured directory and all certs containing the serial number corresponding to some file name are blocked. The most important thing to keep in mind is that the file names need to be cert-serials in decimal writing, everything else is pretty easy.
> --crl-verify crl [‘dir’] Check peer certificate against the file crl in PEM format.[...]If the optional dir flag is specified, enable a different mode where crl is a directory containing files named as revoked serial numbers (the files may be empty, the contents are never read). If a client requests a connection, where the client certificate serial number (decimal string) is the name of a file present in the directory, it will be rejected.
server.conf simply contains the following additional config:
Which maps to the following directory:
The files in crl and crl_staging are simply the decimal cert serials and can be moved between the directories as necessary. If a serial is available in crl, connection is blocked, otherwise it succeeds. An example error message in the logs looks like the following:
Logging
While I didn't find a simple configuration to log additional details like cert serials, that can be implemented customly with the help of --tls-verify. That expects a script and for that script OVPN sets multiple environment variables, e.g. containing the serial of some cert.
> --tls-verify cmd Run command cmd to verify the X509 name of a pending TLS connection that has otherwise passed all other tests of certification (except for revocation via –crl-verify directive; the revocation test occurs after the –tls-verifytest).
The supported environment variables:
Code: Select all
tls_id_{n}
tls_serial_{n}
tls_serial_hex_{n}
> --tls-export-cert directory Store the certificates the clients uses upon connection to this directory. This will be done before –tls-verify is called. The certificates will use a temporary name and will be deleted when the tls-verify script returns. The file name used for the certificate is available via the peer_cert environment variable.
Reject invalid certs
My ultimate goal is to make sure that a replaced certificate is used as expected. One approach doing so is using a certificate revocation list and OVPN supports a very easy way to do so: One doesn't need any concrete file format or such with the certs, but can simply add some file names to some configured directory and all certs containing the serial number corresponding to some file name are blocked. The most important thing to keep in mind is that the file names need to be cert-serials in decimal writing, everything else is pretty easy.
> --crl-verify crl [‘dir’] Check peer certificate against the file crl in PEM format.[...]If the optional dir flag is specified, enable a different mode where crl is a directory containing files named as revoked serial numbers (the files may be empty, the contents are never read). If a client requests a connection, where the client certificate serial number (decimal string) is the name of a file present in the directory, it will be rejected.
server.conf simply contains the following additional config:
Code: Select all
crl-verify 'crl' 'dir'
Code: Select all
crl
7
8
9
crl_staging
12
13
14
openvpn-status.log
server.conf
Code: Select all
ovpn-server[15859]: 00-0a-14-81-d9-e1/34.252.35.124:35231 TLS: new session incoming connection from [AF_INET]34.252.35.124:35231 (via [AF_INET][...]%eth1)
ovpn-server[15859]: 00-0a-14-81-d9-e1/34.252.35.124:35231 VERIFY OK: depth=1, C=DE, ST=[...], O=[...], OU=[...], CN=[...], emailAddress=[...]
ovpn-server[15859]: 00-0a-14-81-d9-e1/34.252.35.124:35231 VERIFY CRL: certificate serial number 10 is revoked
ovpn-server[15859]: 00-0a-14-81-d9-e1/34.252.35.124:35231 OpenSSL: error:1417C086:SSL routines:tls_process_client_certificate:certificate verify failed
ovpn-server[15859]: 00-0a-14-81-d9-e1/34.252.35.124:35231 TLS_ERROR: BIO read tls_read_plaintext error
ovpn-server[15859]: 00-0a-14-81-d9-e1/34.252.35.124:35231 TLS Error: TLS object -> incoming plaintext read error
ovpn-server[15859]: 00-0a-14-81-d9-e1/34.252.35.124:35231 TLS Error: TLS handshake failed