For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

Livius's avatar
Livius
Icon for Cirrus rankCirrus
Jul 12, 2018

Connections to pool are failing when iRule is applied

Hi guys,

 

I have a strange issue going on a production F5. This iRule was running fine until people started to report that the Pool members are not getting any traffic. I quickly removed the following iRule and traffic started to flow to the pool members. Apparently the issue is with the HTTP_REQUEST clause, but I cannot find any clue why it stops sending traffic at all:

 

Below the code:

 

Code

This IRULE inspects the incoming session parameters and finds the CN number of the SSL certificate
it is possible that a SSL session is continued, so the IRULE will look at HTTP session start.


ensure cn is properly initialized. "when CLIENT_ACCEPTED" is triggered when the 3-way TCP handshake   is  completed
the CN is the critical info which contains a serial number of the authenticated device...

Lines that are commented out with double  are actual comments
Lines that are commented out with single  are logging/debugging commands that can be enabled on  demand


when CLIENT_ACCEPTED {

     Choose 1 to log DEBUG info
     static::CRL_DEBUG_LOCAL 1 enables logging to local log file /var/log/ltm
     static::CRL_DEBUG_REMOTE 1 enables logging to HSL server
     Use local DEBUG ONLY in lab tests - it will NOT scale well for production use
    set static::XDEV_DEBUG_LOCAL 1
    set static::CRL_DEBUG_REMOTE 1

     start with cleaning the cn value
    set cn "-"

    Set remote logging server pool (must be created via GUI first)
    set hsl_pool "HSL_pool"

     initiate handler to syslog publisher for HighSpeed logging
    set hsl [HSL::open -proto TCP -pool $hsl_pool]
}


 update cn in case a session was picked up
    when CLIENTSSL_CLIENTHELLO {
set connection "[IP::client_addr]:[TCP::client_port]->[IP::local_addr]:[TCP::local_port] sslsessionid=[SSL::sessionid]"

if { [SSL::cert count] > 0 } {
    Save the first cert in the client request
    the client sends a client certificate together with a client intermediate certificate. Client certificate must come first.
    set cert [SSL::cert 0]

    Save the cert fields to a list
    set fields [X509::cert_fields $cert [SSL::verify_result] subject]

    update the cn
    set cn [findstr [lindex $fields 3] "CN=" 3 ","]

    if { $static::XDEV_DEBUG_LOCAL } {      log local0. "$connection; client hello cn=$cn"}
    if { $static::XDEV_DEBUG_REMOTE } {     HSL::send $hsl "$connection; client hello cn=$cn"}

 }
    }


determine and save the CN when a client presented a cert after it was requested/required
when CLIENTSSL_CLIENTCERT  {
check if there is at least one certificate in the presented cert. chain
if { [SSL::cert count] > 0 } {
    log local0. " count = [SSL::cert count]"
    Save the first cert in the client request
    set cert [SSL::cert 0]
    set vfy [SSL::verify_result]
    if { $vfy !=  0 } {
                    if { $static::XDEV_DEBUG_LOCAL } {      log local0. "Client certificate verification    result - $vfy : [X509::verify_cert_error_string $vfy]"}
                    if { $static::XDEV_DEBUG_REMOTE } {     HSL::send $hsl "Client certificate verification result - $vfy : [X509::verify_cert_error_string $vfy]"}
    }

    Save the cert fields to a list
    set fields [X509::cert_fields $cert [SSL::verify_result] subject]

    update the cn
    set cn [findstr [lindex $fields 3] "CN=" 3 ","]
            if { $static::XDEV_DEBUG_LOCAL } {      log local0. "$connection handshake cn=$cn"}
            if { $static::XDEV_DEBUG_REMOTE } {     HSL::send $hsl "$connection handshake cn=$cn"}
}
}

write CN information from client certificate into X-DEV header
when HTTP_REQUEST {

HTTP::header insert "X-dev" $cn
if { $static::XDEV_DEBUG_LOCAL } {      log local0. "INSERTED XDEV-HEADER for client [IP::client_addr]: $cn"}
if { $static::XDEV_DEBUG_REMOTE } {     HSL::send $hsl "INSERTED XDEV-HEADER for client [IP::client_addr]: $cn"}

}

 

1 Reply

  • I have had experiences of variables set in CLIENTSSL_CLIENTCERT not being available in HTTP_REQUEST, especially if the client SSL profile doesn't always require the certificate. It's usual to write these values to the session table in these types of requests to avoid this issue. I can advise on this if it's something you'd like help with.

    For now, try changing your HTTP_REQUEST event to this to check if the $cn variable exists before trying to use it as your iRule may be generating a TCL error.

    when HTTP_REQUEST {
        if {([info exists cn]) && ($cn ne "")} {
            HTTP::header insert "X-dev" $cn
            if { $static::XDEV_DEBUG_LOCAL } { 
                log local0. "INSERTED XDEV-HEADER for client [IP::client_addr]: $cn"}
            if { $static::XDEV_DEBUG_REMOTE } { 
                HSL::send $hsl "INSERTED XDEV-HEADER for client [IP::client_addr]: $cn"}
        } else {
            log local0. "cn variable does not exist, header not inserted"
        }
    }