Forum Discussion

Livius's avatar
Livius
Icon for Altostratus rankAltostratus
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"
        }
    }