Improving OpenVPN security by revoking unneeded certificates

27 February 2013 — 17 Comments

openvpnOpenVPN is great, it allows for easy access in a secure way. But how do you keep it secure? I mean, what if someone leaves your company? Do you disable access to the OpenVPN server? You should! In this blog I’ll show you how to do it.

A feature called revoking exists in OpenVPN. Revoking a certificate means to invalidate a previously signed certificate so that it can no longer be used for authentication purposes. For this to work, we need to tell the OpenVPN server which certificates are no longer valid.

All connecting clients will then have their client certificates verified against the so-called CRL (Certificate Revoking List). Any positive match will result in the connection being dropped. Your former employees will no longer have access, even if they still have their certificates.

Creating a certificate to test with
Before we start, let’s generate a dummy certificate for testing purposes:

cd /etc/openvpn/easy-rsa/2.0/
 . ./vars
./build-key unwanted-client-name

Verify you can connect to the OpenVPN server using this certificate. Refer to my earlier post for more info. Now that this works, I’ll show you how to revoke this certificate so you will no longer be able to connect.

Revoking a certificate
To revoke a certificate, we’ll use the ‘easy-rsa’ toolset.

cd /etc/openvpn/easy-rsa/2.0

If it’s not there, look at the OpenVPN examples and copy it:

cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn
cd /etc/openvpn/easy-rsa/2.0

Run this command to revoke the certificate called ‘unwanted-client-name’:

./revoke-all unwanted-client-name

You should see output similar to this:

Using configuration from /etc/openvpn/easy-rsa/2.0/openssl-1.0.0.cnf
Revoking Certificate 03.
Data Base Updated
Using configuration from /etc/openvpn/easy-rsa/2.0/openssl-1.0.0.cnf
unwanted-client-name.crt: C = NL, ST = ZH, L = City, O = Name, OU = pi.example.org, CN = unwanted-client-name, name = unwanted-client-name], emailAddress = [email protected]
error 23 at 0 depth lookup:certificate revoked

Note the “error 23” in the last line. That is what you want to see, as it indicates that a certificate verification of the revoked certificate failed.

The index.txt file on keys directory will be updated. You’ll see an ‘R’ (for Revoked) on the first column from the left for your user when you run this:

cat keys/index.txt

You can also examine the CRL to see what’s in there:

openssl crl -in keys/crl.pem -text

Now copy the crl.pem file to the OpenVPN config directory:

cp keys/crl.pem /etc/openvpn/

Whenever you revoke a certificate, you’ve to copy it to the OpenVPN server.
Note: The CRL file is not secret, and should be made world-readable so that the OpenVPN daemon can read it after root privileges have been dropped.

Enable revoking support
Before it works, we need to setup the OpenVPN server to add support for revoking certificates. You’ve to do this only once.

Add the folowing line to the OpenVPN server config:

vim /etc/openvpn/server.conf
crl-verify /etc/openvpn/crl.pem

Reload the OpenVPN server to activate the revoke setting:

/etc/init.d/openvpn reload

Testing the revoked certificate
The final test: try to login again using the ‘unwanted-client-name’ certificate. It will not work anymore!

By revoking users, you disallow access to your OpenVPN server for users that previously had access. This should be done as soon as an user no longer needs access, as it is an important security feature.

17 responses to Improving OpenVPN security by revoking unneeded certificates

  1. 

    Will this approach persist across re-boots on routers with OpenVPN, e.g., TomatoUSB?

    In other words, is /etc/openvpn/ on a router in volatile on non-volatile memory?

    • 

      I’d guess it is persistent. But I don’t own such a device so I don’t know for sure. It is persistent on the Pi.

      I’d suggest having a look at the GUI, there might be an option to set this there as well. It’s definitely persistent in that case.

      Otherwise: just give it a try 🙂

  2. 

    can you un revoke a client key?

    • 

      Hi Tony,

      Yes, it can be done but I wouldn’t recommend doing so.

      If you really want it:
      edit index.txt and replace the ‘R’ (Revoked) with ‘V’ (Valid) and generate the new CRL and use that cert from now on.

      The best way is to generate a new certificate though.

  3. 

    This was incredibly helpful. In light of the recent Heartbleed concerns, I wanted to revoke my certificates and issue new ones. All guides discuss the revocation process, but none mention the requirement to add a line to the conf file, something easily overlooked. Luckily, this wasn’t one of those 5 days hair-pulling questions, since I found your blog after only a few hours trying to get this to work. This saved me probably days of frustration trying to diagnose why the revocation was not working.

    Thank you!!

  4. 

    Worked like a charm. Thank you so much Remi.

    • 
      Masood Khan 24 June 2015 at 13:32

      I have a openvpn I created the unwanted client to test however when I run the command /.revoke-all it says

      bash: ./revoke-all: No such file or directory

      i am running as su and I am in the openvpn folder however I see revoke-full file instead revoke-all (is it the same thing? Did they change the file name?)

      Thanks

  5. 

    Nice Remi, thanks a lot! 🙂

  6. 

    Warning! In certain distros (maybe all?) the OpenSSL default for CRL expiration is 30 days. It is absolutely imperative that you also mention that the CRL needs to be refreshed before expiration! Another (less secure?) option is to use an OpenSSL config file that specifies `default_crl_days` to the quantity desired.

  7. 

    I have OpenVPN 2.3.10 with OpenSSL 1.0.2g on Ubuntu 16 LTS. The above steps aren’t working for me. The DigitalOcean guide lists roughly the same steps, with no luck. After I get the crl.pem file created and copy it to the same directory as the server config file, and restart the service, no certificates work. I’ve tried putting the full path to the file in the config file, and that doesn’t work either. The only way to restore access is to comment out the “crl-verify /etc/openvpn/crl.pem” line and restart the service.

    Has the process to revoke certificates changed?

  8. 

    after adding crl.pem, the certificate which are not revoked are also having issues in connecting with. basically other clients timesout without being able to connect

    • 

      i see error: CRL signature failure:

      [root@ip-172-19-255-169 2.0]# ./revoke-full dumpty
      Using configuration from /usr/share/easy-rsa/easy-rsa/2.0/openssl-1.0.0.cnf
      ERROR:Already revoked, serial number 02
      Using configuration from /usr/share/easy-rsa/easy-rsa/2.0/openssl-1.0.0.cnf
      dumpty.crt: C = US, ST = CA, L = SanFrancisco, O = Fort-Funston, OU = MyOrganizationalUnit, CN = dumpty, name = EasyRSA, emailAddress = [email protected]
      error 8 at 0 depth lookup:CRL signature failure
      140435270043488:error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm:a_verify.c:206:

Leave a reply to Ibon Cancel reply