Icinga 2

Using a Certificate Revocation List (CRL) with Icinga 2

Before you start: There is a bug in Icinga 2 (at least up to version 2.6.2) that prevents a CRL from being loaded, so you have to ensure that you use a newer version or patch the bug yourself.

Icinga 2 makes managing the CA easy by using the icinga2 pki commands. However, it does not provide any commands for generating a CRL. This means that the regular openssl tool needs to be used for that. The functions for generating a CRL are part of the ca module, so one first has to create a CA configuration for OpenSSL. For the rest of this tutorial, we assume that the certificates for Icinga 2 are stored in the default location (/var/lib/icinga2/ca).

First, we create the directory /var/lib/icinga2/ca/crl and a number of files needed in this directory:

   1 mkdir /var/lib/icinga2/ca/crl
   2 cd /var/lib/icinga2/ca/crl
   3 touch index.txt
   4 echo "0000" >crlnumber.txt
   5 touch crl.pem

Next, we create the configuration file for OpenSSL as /var/lib/icinga2/ca/crl/openssl.cnf:

# OpenSSL configuration for CRL generation
#
####################################################################
[ ca ]
default_ca      = CA_default            # The default ca section

####################################################################
[ CA_default ]
database = /var/lib/icinga2/ca/crl/index.txt
crlnumber = /var/lib/icinga2/ca/crl/crlnumber.txt
certificate = /var/lib/icinga2/ca/ca.crt
private_key = /var/lib/icinga2/ca/ca.key

crl_extensions  = crl_ext               # name of the section containing the
                                        # CRL extensions
default_crl_days        = 365           # how long before next CRL
default_crl_hours       = 0
default_md      = sha256                # use SHA256 for signing the CRL
unique_subject  = no                    # do not enforce unique certificate
                                        # subjects

####################################################################
[ crl_ext ]
# CRL extensions.

Finally, we want two shell scripts. One for generating the CRL and one for revoking a certificate.

/var/lib/icinga2/ca/crl/gen-crl.sh:

   1 #!/bin/bash
   2 
   3 # Find the path to this file (this script might be referenced through a
   4 # symbolic link).
   5 CURRENT_WORKING_DIRECTORY="`pwd`"
   6 THIS_FILE="$0"
   7 cd "`dirname "$THIS_FILE"`"
   8 THIS_FILE="`basename "$THIS_FILE"`"
   9 while [ -L "$THIS_FILE" ]; do
  10   THIS_FILE="`readlink "$THIS_FILE"`"
  11   cd "`dirname "$THIS_FILE"`"
  12   THIS_FILE="`basename "$THIS_FILE"`"
  13 done
  14 THIS_FILE="`pwd -P `/$THIS_FILE"
  15 cd "$CURRENT_WORKING_DIRECTORY"
  16 BASE_DIR="`dirname "$THIS_FILE"`"
  17 
  18 openssl ca -config "$BASE_DIR/openssl.cnf" -gencrl -out "$BASE_DIR/crl.pem"

/var/lib/icinga2/ca/crl/revoke.sh:

   1 #!/bin/bash
   2 
   3 # Find the path to this file (this script might be referenced through a
   4 # symbolic link).
   5 CURRENT_WORKING_DIRECTORY="`pwd`"
   6 THIS_FILE="$0"
   7 cd "`dirname "$THIS_FILE"`"
   8 THIS_FILE="`basename "$THIS_FILE"`"
   9 while [ -L "$THIS_FILE" ]; do
  10   THIS_FILE="`readlink "$THIS_FILE"`"
  11   cd "`dirname "$THIS_FILE"`"
  12   THIS_FILE="`basename "$THIS_FILE"`"
  13 done
  14 THIS_FILE="`pwd -P `/$THIS_FILE"
  15 cd "$CURRENT_WORKING_DIRECTORY"
  16 BASE_DIR="`dirname "$THIS_FILE"`"
  17 
  18 for cert in "$@"; do
  19   openssl ca -config "$BASE_DIR/openssl.cnf" -revoke "$cert"
  20 done

Do not forget to make the shell scripts executable:

   1 chmod a+x /var/lib/icinga2/ca/crl/gen-crl.sh
   2 chmod a+x /var/lib/icinga2/ca/crl/revoke.sh

You might also want to change the owner of these files, though this step is entirely optional:

   1 chown -R nagios:nagios /var/lib/icinga2/ca/crl

Now in order to revoke a certificate, you call revoke.sh with the certificate file as the parameter. For example:

   1 /var/lib/icinga2/ca/crl/revoke.sh /var/lib/icinga2/ca/host.example.com.crt

After revoking a certificate, you have to regenerate the CRL in order to include the revoked certificate in the CRL:

   1 /var/lib/icinga2/ca/crl/gen-crl.sh

In order to actually use the CRL, you have to distribute it to the Icinga 2 nodes. How to do this is outside of the scope of this tutorial. One might simply use scp or one could use a configuration management tool like SaltStack.

One thing to consider when distributing the CRL is its validity period: When using a CRL, Icinga 2 will start to reject all certificates (even the ones which have not expired yet and have not been revoked either) when the CRL has expired. This means that a new CRL has to be distributed before the old one expires. Choosing a longer validity period (by changing the crldays and crlhours options in the OpenSSL configuration) might help so that you can distribute the CRL less often. For example, the certificiates generated by Icinga 2 are valid for 5475 days (approximately 15 years). However, in contrast to certificates, there is no way to revoke a CRL. This means that if an attacker got hold of a CRL (which is not unlikely because a CRL is generally considered public information) and found a way to inject that CRL in the distribution process, he might be able to make a node use an old version of the CRL, thus accepting certificates that have been revoked in the meantime. When using a secure channel (like SSH) for distributing the CRL, you might not be worried too much about this scenario.

In order to make Icinga 2 use the CRL, it has to be registered with the API listener. The following configuration (typically stored in /etc/icinga2/features-available/api.conf) assumes that the CRL is stored in /etc/icinga2/pki/crl.pem.

/**
 * The API listener is used for distributed monitoring setups.
 */

object ApiListener "api" {
  cert_path = SysconfDir + "/icinga2/pki/" + NodeName + ".crt"
  key_path = SysconfDir + "/icinga2/pki/" + NodeName + ".key"
  ca_path = SysconfDir + "/icinga2/pki/ca.crt"
  crl_path = SysconfDir + "/icinga2/pki/crl.pem"

  ticket_salt = TicketSalt
}


CategoryEnglish CategoryNetwork

Network/Icinga_2 (last edited 2017-03-16 14:21:27 by SebastianMarsching)