FreeRADIUS and CRLs – Done the right way [Update]

May 28, 2012

Update: I changed the FreeRADIUS in-line CRL verification to an external program – running it now for several month at it works without restart of FreeRADIUS.

While I was implementing 802.1x EAP-TLS with FreeRADIUS I googled for documentation on how to implement Certificate Revocation Lists (CRL) in FreeRADIUS. The first text was in the eap.conf:


# Check the Certificate Revocation List
#
# 1) Copy CA certificates and CRLs to same directory.
# 2) Execute 'c_rehash '.
# 'c_rehash' is OpenSSL's command.
# 3) uncomment the line below.
# 5) Restart radiusd
check_crl = yes
CA_path = /etc/freeradius/certs/CA/

Which is basically correct, but it is so short on information that I googled on and found following posts:

Both where not the solution I needed as I didn’t want to restart FreeRADIUS all the time and I have multiple sub CAs. I than started googling for more information on c_rehash, as the version on RHEL5/CentOS5/SL5 don’t need to have a man page. Take a look at this online man page.

And just as info as it is not that clear which package has c_rehash: yum provides "*/c_rehash" --> yum install openssl-perl. Basically c_rehash needs to be provided a directory with .pem files in it (also the CRLs need to be name .pem) and it than creates symlinks with the hashes of the files as names. After I got a prototype working but before I wrote this blog, Erik Inge Bolso wrote this blog post describing the same thing.

You need at least FreeRADIUS 2.1.10 (shipped with Centos/RHEL 5 (inc. updates) and later) for this solution to work.

After I got the prototype working I wrote a script which does download multiple CRLs, converts them from DER (e.g. used by Windows CAs) to PEM, verifies them and than uses c_rehash to hash them for FreeRadius. You need to do following steps to get it working for you.

  1. Create some directories
    mkdir /var/tmp/cacheCRLs
    mdir /etc/pki/crl/
  2. download thisĀ script cacheCRLs4FreeRadius.py to /usr/local/sbin/
    cd /usr/local/sbin/
    wget http://robert.penz.name/wp-content/uploads/2012/05/cacheCRLs4FreeRadius.py
  3. edit /usr/local/sbin/cacheCRLs4FreeRadius.py and change the URLs and names to your CAs
  4. run /usr/local/sbin/cacheCRLs4FreeRadius.py, no output means no error and check the content of /etc/pki/crl/
  5. check that your radius config contains following and restart FreeRADIUS after the change
    # we're using our own code for checking the CRL
    # check_crl = yes
    CA_path = /etc/pki/crl/
    ....
    tls {
    ....
    verify {
    tmpdir = /var/tmp/radiusd
    client = "/usr/local/sbin/checkcert.sh ${..CA_path} %{TLS-Client-Cert-Filename}"
    }
    }
  6. /usr/local/sbin/checkcert.sh should contain following
    #!/bin/sh
    output=`/usr/bin/openssl verify -CApath $1 -crl_check $2`

    if [ -n "`echo $output | /bin/grep error`" ]; then
    RC=1
    else
    RC=0
    fi
    echo $output
    exit $RC

  7. If you need more performance replace the shell script a C program, as this program is started at every authentication request.
  8. Try to authenticate with an revoked certificate and you should get following. If you’re running FreeRADIUS with -X you should see following (this log looks a little bit different when using the external program, which is the method I’m using now) :

    [eap] Request found, released from the list
    [eap] EAP/tls
    [eap] processing type tls
    [tls] Authenticate
    [tls] processing EAP-TLS
    [tls] eaptls_verify returned 7
    [tls] Done initial handshake
    [tls] < << TLS 1.0 Handshake [length 05f8], Certificate --> verify error:num=23:certificate revoked
    [tls] >>> TLS 1.0 Alert [length 0002], fatal certificate_revoked
    TLS Alert write:fatal:certificate revoked
    TLS_accept: error in SSLv3 read client certificate B
    rlm_eap: SSL error error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
    SSL: SSL_read failed in a system call (-1), TLS session fails.
    TLS receive handshake failed during operation
    [tls] eaptls_process returned 4
    [eap] Handler failed in EAP/tls
    [eap] Failed in EAP select
  9. run the script via cron in intervals that are required in your setup. e.g. once a day or once every hour

Powered by WordPress
Entries and comments feeds. Valid XHTML and CSS. 25 queries. 0.040 seconds.