Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

Automaticlly update CRL

Hi All,
Is possible configure auto-update the CRL?
I have BIG-IP v 11. From CA I have downloaded and imported the CRL file. In the Client SSL profile I have configured: Cert - required ... and CRL => imported file.

So, how I can configure the aoutomatically update of the CRL file?
Is it possible set from GUI, or CLI only?

THX
0
Rate this Question
Comments on this Question
Comment made 13-Aug-2014 by Lucas Thompson
Note that for the APM use case of: 1- Request and get client certificate. 2- Validate certificate against CA cert. 3- Check client certificate against CRL hosted on an external HTTP server during Access Policy execution.. It now works correctly. Versions prior to 11.4.0 did not support CRLDP via HTTP. 11.4.0+ does support this, so for APM client use, the problem should be resolved and any kind of script should not be required.
0

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
F5's approach to this problem is poor. This problem must be widespread, but is never adequately addressed, either here in the forum nor on the support site or documentation.

Once again, the need for CRL updates has come up for us. In addition to downloading the CRL, we also had the following issues:
* The IP address of the CRL server cannot be known in advance (it apparently changes from time to time). We need to use DNS to locate it
* We cannot download the file using the DNS name because the internet is not accessible through the default route domain.
* The CRL as downloaded is in DER format, so we need to convert it to PEM per the LTM's requirement
* Even when a new CRL is in place, the tmm does not read it, so we have to "touch" the config to force it to reload it.

We are currently using the following shell script, run once a day from cron, to achieve this. Note that this uses the bigpipe utility, which will not work in v11. It also needs a bit more error checking.
------------------------------------------------------------------------
#!/bin/sh
cd /var/tmp

# delete the old temporary files
rm demo.crl demo.pem

# get the current IP address of the CRL server
CRLIP4=`dig demo.example.com A | grep '^demo.*[0-9]$' | awk '{print $5}'`

# convert it to the IPv6 route domain 5 address
CRLIP6=`rdip $CRLIP4\%5`
if [ $? -eq 0 ]; then
# download the CRL faking the host header because we're using an IP address in the request
  curl -v -O -H 'Host: demo.example.com' -g http://[$CRLIP6]/crl/demo.crl
  if [ -f demo.crl ]; then
# convert the CRL from DER to PEM
    openssl crl -inform der -in demo.crl -out demo.pem
    rm demo.crl
    mv demo.pem /config/ssl/ssl.crl/
# set the administrative parition to update the config
    bigpipe shell write partition mypartition
# 'touch' the clientssl profile so tmm re-reads the crl
    bigpipe profile clientssl demo-clientssl crl file demo.pem
  fi
fi
------------------------------------------------------------------------

The above script refers to a script "rdip", which we pinched from elsewhere on the forums. It converts an IPv4 address with the route domain number appended to the special IPv6 address.
This is shown below:
------------------------------------------------------------------------
#!/bin/bash
F5_RD_HEADER="2620:0:c10:f501:0:"
#F5_RD_HEADER="2610:0:c10:f501:0:"
HOST_ADDRESS=${1/\%*}
ROUTE_DOMAIN=${1/*\%}
if [ ! -z $ROUTE_DOMAIN ]; then
    host_parts=($(echo $HOST_ADDRESS | grep -Po "\d+"))
    printf "%s%x:%x:%x\n" $F5_RD_HEADER $ROUTE_DOMAIN $(((${host_parts[0]} << 8) + ${host_parts[1]})) $(((${host_parts[2]} << 8) + ${host_parts[3]}))
    exit 0
fi
------------------------------------------------------------------------

I hope this helps

2
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi Petras,

You could potentially script this, but there isn't a facility within BIG-IP to auto-update the CRL. If you want realtime checking of client certs you could use APM or the Advanced Client Auth module to do OCSP verification.

Aaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi Hoolio,
thank you for answer. Do you have any idea how to script the download? The CA publish the CRL file only as http.
ThX
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Here is the manual section on validating certificate revocation status. This section covers CRLs, OCSP, and CRLDP.

-George
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi folks, 

Came across similar issue when a PKI I was working with did not support OCSP and the CRLDP setup would not work due to the CRLDP info in the cert being without a hostname i.e. ldap:///CN=... (http://support.f5.com/kb/en-us/solutions/public/12000/900/sol12975.html?sr=22851678)
  
So only workaround was implementing a scripted download/update to CRL file, from an 11.1 box, so thought I'd add what I did here, basically modifying the above script to suit with a few extras.

Note that if you save the script in /root/ then I am told the script won't be wiped out if you upgrade OS/apply hotfix etc. However, the crontab entry may be wiped out if you upgrade OS/apply hotfix I believe - havn't tested it.  The script also has some additional error checking and emails out a notification if there's an error in curl getting the file.


#!/bin/sh
# NOTE:
# - Remember that you need to manually import a CRL file through the GUI with the same name as the one use by this
# script FIRST, otherwise the config 'touch' will fail.  Load it through Local Traffic -> SSL Certificate List 
# - Remember to make this script executable (chmod 700 or as applicable) and test it from CLI first
# - Add it to crontab (crontab -e), e.g. if you want to run it on the hour every hour add 0 * * * * /root/demo_crl.sh

cd /root

# delete the old file if it exists

if [ -f demo.crl]; then
    mv demo.crl demo.crl.old
fi

if [ $? -eq 0 ]; then
        # Download CRL faking the host header because we're using an IP address in the request
        # rdexec only available in v11.1 - runs a CLI command against a specific route domain see sol13472
        # Change to your route domain ID (you can omit rdexec entirely for Common route domain)
        # Change or remove --ntlm -u : if you need AD credentials to download
        # Enter the name and IP of your PKI server instead of and <1.2.3.4>

        rdexec curl -o demo.crl --ntlm -u : -H 'Host: ' -g http://<1.2.3.4>/certsrv/certcrl?Type=base&Renewal=0&Enc=bin
        wait
        
  if [ -f demo.crl ]; then

        # convert the CRL from DER to PEM - ONLY IF NEEDED, my CRL was in PEM format already from above
        #    openssl crl -inform der -in demo.crl -out demo.pem
        #    rm demo.crl
        #    mv demo.pem demo.crl

        # This is the v11 location and TMSH command to 'touch' the config
        # Change to the relevant partition name (or Common) and to the relevant client ssl profile

        cat demo.crl > /config/filestore/files_d/_d/certificate_revocation_list_d/\:\:demo.crl_1
        tmsh modify ltm profile client-ssl // crl-file //demo.crl

  else
        # Email notify someone if this failed for any reason - need to setup mailhub in /etc/ssmtp/ssmtp.conf ref sol13180

        mail -s "CRL retrieval failed" admin@example.com < /dev/null
  fi
fi
 

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Nice Evan. Very similar to my script once I converted to v11. One thing I would do differently is not overwrite the old crl when you download the new one, test if the new one exists, them rename it. That way if the download fails you still have the original crl.

I very much prefer the rdsh and rdexec commands over the old structured IPv6 addresses :)
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Another suggestion. You can import the file using tmsh. This is the 11.1 syntax, it looks like it might be different for 11.2

tmsh modify /sys file ssl-crl democrl source-path file:/root/demo.crl 
This moves the file into place and 'touches' the config.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Another version. Note that this is only tested on 11.1.x and a F5 active/standby cluster.

REMOVED

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Removed post. Code contained error.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Wth is wrong with this board? I can't even edit posts decently... Anyway, this is the correct bugfix:

#!/bin/sh
#
# NOTE:
# - Remember that you need to manually import a CRL file through the GUI with
# the same name as the one use by this script FIRST, otherwise the config
# 'touch' will fail. Load it through Local Traffic -> SSL Certificate List.

TMSH="/usr/bin/tmsh"
TMPFILE=`/bin/mktemp` || { echo "Failed to create temp file. Exiting"; exit 1; }

if [ -e "$TMSH" ]; then
    STATUS=`$TMSH show sys failover`
else
    echo "tmsh not found"
    exit 1
fi

case "$STATUS" in
    *active*)
        echo "Active F5: Continuing..."
        ;;
    *standby*)
        echo "Standby F5: Exiting."
        ;;
    *)
        echo "Unknown status: Exiting."
        exit 1
esac

/usr/bin/curl -f -o $TMPFILE -H 'Host: HOSTNAME' -g http://HOSTNAME/demo.crl

if [ $? -ne 0 ]; then
    echo "Error getting CRL file. Exiting."
    exit 1
fi

if [ -f $TMPFILE ] && [ -s $TMPFILE ]; then
    # convert the CRL from DER to PEM - ONLY IF NEEDED, my CRL was in PEM
    # format already from above
    # openssl crl -inform der -in demo.crl -out demo.pem
    # rm demo.crl
    # mv demo.pem demo.crl
    $TMSH modify /sys file ssl-crl demo.crl source-path file:$TMPFILE
    if [ $? -eq 0 ]; then
        $TMSH run /cm config-sync to-group /Common/CLUSTERNAME
    else
        echo "crl upload fail. Exiting."
        /bin/rm $TMPFILE
        exit 1
    fi
else
    echo "No crl file found or crl file empty. Exiting."
    exit 1
fi

/bin/rm $TMPFILE

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Always love a good scripting challenge. ;) Here's another version that adds some capabilities:

1. Aggregates multiple CRLs into a single file - in the event that you have multiple CAs in your CA bundle and have to validate against multiple CRLs.
2. Checks the expiration date against an established threshold value before updating.

There are two files:

1. The INI file that lists the CRL publishers. I created a special directory under /config to hold this, and it lists each CRL path on a separate line. Here's a sample of the INI file:

http://ca.alpha.com/crl/crl.alpha.com.crl
http://ca.bravo.com/crl/crl.bravo.com.crl


2. The script:

#!/bin/bash

###### set path to staged CRLs
crl_path=/config/dev/crl/

###### set client SSL profile name
clientssl_prof=test-sslcrof

###### set INI file path
crl_ini=/config/dev/crlupdate.ini

###### set acceptable threshold in seconds (172800 seconds = 2 days)
crl_threshold=172800

###### FUNCTIONS ######
GET_CURRENT_CRL() {
   remote_path=$1
   remote_name=$2
   ## get the current CRL (or retrieve if missing)
   if [ ! -f $crl_path$remote_name ]
   then
      ## file does not exist - go get it
      logger -p local0.info -t CRLUPDATE "Error: File ($crl_path$remote_name) doesn't exist - attempting to retrieve it"
      ret=`curl --url $remote_path$remote_name --remote-name --silent --write-out "%{http_code}"`
      if [ $ret -eq 200 ] && [ -f $remote_name ]
      then
         ## got a new CRL (and we know/assume it's current)
         mv $remote_name $crl_path
         ## convert a copy to PEM format
         openssl crl -in $crl_path$remote_name -inform DER -outform PEM -out $crl_path$remote_name.PEM
         HAS_UPDATED=1
         return 0
      else
         ## didn't get CRL - error and log
         rm -f $remote_name
         logger -p local0.info -t CRLUPDATE "Error: Could not retrieve CRL ($remote_name) from ($remote_path)"
         return 1
      fi
   else
      ## already have the CRL - now check to see if it's valid     

      ## get the current date
      this_date=`date +%s`

      ## extract the date from the current CRL
      this_crl_date_literal=`openssl crl -in $crl_path$remote_name -inform DER -noout -nextupdate |sed s/nextUpdate=//`
      this_crl_date=`date -d "$this_crl_date_literal" +%s`

      ## compare current date and current CRL date for threshold
      if [ $this_date -ge $(($this_crl_date - $crl_threshold)) ]
      then
         ## crl date exceeds threshold - crl is about to expire or has expired - fetch the new crl
         logger -p local0.info -t CRLUPDATE "Error: Current CRL exceeds the threshold (is expired or about to expire)"
         ret=`curl --url $remote_path$remote_name --remote-name --silent --write-out "%{http_code}"`
         if [ $ret -eq 200 ] && [ -f $remote_name ]
         then
            ## got a new CRL (and we know/assume its current)
            mv $remote_name $crl_path
            ## convert a copy to PEM format
            openssl crl -in $crl_path$remote_name -inform DER -outform PEM -out $crl_path$remote_name.PEM
            HAS_UPDATED=1
            return 0
         else
            ## didn't get CRL - error and log
            rm -f $remote_name
            logger -p local0.info -t CRLUPDATE "Error: Could not retrieve CRL ($remote_name) from ($remote_path)"
            return 1
         fi
      else 
         ## CRL is current
         return 0
      fi
   fi
}
###### END FUNCTIONS ######

HAS_UPDATED=0

## loop through CRL ini file to retrieve listed CRLs
while read p
do
   file=${p##*/}
   path=`echo $p |sed s/$file//`
   GET_CURRENT_CRL $path $file
done < $crl_ini

if [ $HAS_UPDATED == 1 ]
then
   ## only proceed if some CRLs have been updated
   logger -p local0.info -t CRLUPDATE "Some CRLs have been updated - push to client SSL profile"

   ## delete existing crl concat files in path
   rm -f crl.*

   ## concat the existing PEM CRLs
   this_date=`date +%s`
   big_crl=crl.$this_date
   for f in $crl_path*.PEM
   do
      echo "### $f" >>$big_crl
      cat $f >>$big_crl
   done

   ## upload the new CRL to the system
   tmsh install sys crypto crl $big_crl from-local-file $big_crl

   ## get the current CRL from the stated client SSL profile and replace with new CRL
   curr_crl=`tmsh list ltm profile client-ssl $clientssl_prof crl-file |grep crl-file |sed s/crl-file//`
   tmsh modify ltm profile client-ssl $clientssl_prof crl-file $big_crl

   ## remove the old CRL from the system
   tmsh delete sys crypto crl $curr_crl
else
   ## no CRL has been updated
   logger -p local0.info -t CRLUPDATE "All CRLs are up to date"
fi


There are 4 variables that you have to modify:

###### set path to staged CRLs
crl_path=/config/dev/crl/

This is where you'll stage and cache the CRLs.

###### set client SSL profile name
clientssl_prof=test-sslcrof

This is the name of the client SSL profile that will be modified.

###### set INI file path
crl_ini=/config/dev/crlupdate.ini

This is the physical location of the INI file.

###### set acceptable threshhold in seconds (172800 seconds = 2 days)
crl_threshold=172800

This is the threshold that you specify before a CRL will be updated.

The script will parse the INI file and for each line (CRL path) run the GET_CURRENT_CRL function. If the CRL doesn't exist in the cache, as defined by crl_path, it'll go get a new one. If one does exist it'll check its date against the threshold and go get a new one if it exceeds the threshold. If it has to get a new CRL for any of the CRLs in the INI, it'll set HAS_UPDATED to 1, which will then cause the script to aggregate all of the CRLs into a single file and replace the existing CRL in the client SSL profile. It'll give the new CRL a name based on the date (ie. crl.date).
0
Comments on this Answer
Comment made 12-Nov-2013 by What Lies Beneath 6708
Hey Kevin. Firstly, thanks for the script. Secondly, a question regarding remote_path=$1 and remote_name=$2, what do I need to specify when launching the script to populate these variables please?
0
Comment made 12-Nov-2013 by Kevin Stewart
The "GET_CURRENT_CRL" function is called form within the script and is passed the $path and $file values derived from the INI file.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Thanks guys! Both examples scream "add me to the codeshare" :)

http://devcentral.f5.com/wiki/AdvDesignConfig.codeshare.ashx

Aaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Lovely script, just a side note

while read p do file=${p##*/} path=echo $p |sed s/$file// GET_CURRENT_CRL $path $file

done < $crl_ini

could be a bit cryptic. Could use dirname(1)

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Using tmsh:

tmsh modify ltm profile client-ssl [profile name] crl-file none
0
Comments on this Answer
Comment made 24-Jul-2014 by Anderson, Eric E. 0
Perfect, thank you! Works as expected.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

I have been using this script fine on 11.3 but just upgraded to 11.5.1 and now have an issue with the script updating the ssl profile. When running the script manually I see the below error

Image Text

I can then look in the client SSL profile CRL list and see a list of CRL's. Usually I can select the last one and it will work until it expires. Looks like the script is pulling the CRL creating the list adding it to the SSL profile but not forcing the ssl profile to use the new file. Maybe 11.5 puts some type of lock on the file and it can't replace it?

Has anyone that is using this upgrade to 11.5.1 and have this same problem?

0
Comments on this Answer
Comment made 14-Aug-2014 by Jon Bartlett
What are the permissions on the script? Which version of the script are you running? Do you see any useful messages in /var/log/local0.info(this path might be different) or /var/local/ltm?
0
Comment made 15-Aug-2014 by ehinkle 7
We are using the exact script that is posted above. I do not see a local0.info in var log, there is a var/log/ltm and below is what it shows. Aug 15 05:46:27 F5-VPN-X crit tmm[23679]: 01260001:2: Found CRL is expired - revoking all certificates until current CRL is available Aug 15 05:46:27 F5-VPN-X info tmm[23679]: Rule /Common/Log_ClientSSL_Cert <CLIENTSSL_CLIENTCERT>: Certificate Result: 72.208.178.216 - CRL has expired Aug 15 05:46:28 F5-VPN-X crit tmm[23679]: 01260001:2: Found CRL is expired - revoking all certificates until current CRL is available Aug 15 05:46:28 F5-VPN-X info tmm[23679]: Rule /Common/Log_ClientSSL_Cert <CLIENTSSL_CLIENTCERT>: Certificate Result: 72.208.178.216 - CRL has expired Aug 15 06:37:02 F5-VPN-X err tmm1[23679]: 01470000:3: iSession: Connection error: isession_handle_evt:2585: isession_handle_evt: bad transition:7 Aug 15 07:22:51 F5-VPN-X info CRLUPDATE: Error: Current CRL exceeds the threshold (is expired or about to expire) Aug 15 07:22:51 F5-VPN-X info CRLUPDATE: Some CRLs have been updated - push to client SSL profile Aug 15 07:22:52 F5-VPN-X err mcpd[7808]: 0107134a:3: File object by name (crl.1408112571) is missing. Aug 15 07:22:52 F5-VPN-X err tmsh[30855]: 01420006:3: 0107134a:3: File object by name (crl.1408112571) is missing. Aug 15 07:22:52 F5-VPN-X err mcpd[7808]: 01071349:3: File object by name (/Common/crl.1407920402.crl) is in use. Aug 15 07:22:52 F5-VPN-X err tmsh[30857]: 01420006:3: 01071349:3: File object by name (/Common/crl.1407920402.crl) is in use.
0
Comment made 21-Dec-2014 by Tomasz Mikolajczyk 0
modify this line: tmsh modify ltm profile client-ssl $clientssl_prof crl-file $big_crl by add .crl like this: tmsh modify ltm profile client-ssl $clientssl_prof crl-file $big_crl.crl
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hello everybody. Guys , how can I configure the automatically update of the CRL file in F5 version 13? Thanks.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Used this code to implement and automate process to update the CRL (THANK YOU EVERYONE above!), but have a dilemma. In some cases we may have an issue and need to 'back out' the CRL. Is there a command syntax to remove/disable the setting on the ssl profile? Our automated process automatically re-applies the setting but in all the online documentation, nothing shows how to nullify/remove/clear a value. Right now using "bigpipe profile clientssl demo-clientssl crl file demo.pem" in the above example.

-1