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

Humair_167681's avatar
Humair_167681
Icon for Nimbostratus rankNimbostratus
Aug 06, 2015

iRule to log SSL cipher version

Hi all,

 

I need to know which of the following iRules would log,

 

  1. Requested Ciphers
  2. Agreed Cipher
  3. the fact that a cipher was not agreed, so connection was not allowed.

iRule 1: when CLIENTSSL_CLIENTHELLO { log local0. [IP::client_addr] log local0. [SSL::cipher name] log local0. [SSL::cipher version]}

 

iRule 2: when CLIENTSSL_HANDSHAKE { if {[SSL::cipher version] eq "SSLv3"}{ log local0. "[IP::client_addr] [SSL::cipher version]"}}

 

iRule 3: when HTTP_REQUEST { HTTP::header insert "SSL_PROTOCOL" [SSL::cipher version] HTTP::header insert "SSL_CIPHER" [SSL::cipher name]}

 

Which one of these will produce the results and what do I need to add to one of these iRules to make sure that I get all the information that I am looking for?

 

6 Replies

  • Technically all of these will have access to the agreed upon cipher and version, though semantically only the CLIENTSSL_HANDSHAKE and HTTP_REQUEST events should have the "chosen" cipher. The CLIENTSSL_HANDSHAKE event will only fire once per SSL handshake, while the HTTP_REQUEST event will fire repeatedly throughout the HTTP application.

     

    When you say "requested ciphers", do you really need to see all of the ciphers that the client presents? That is usually a pretty large list. You'd also need to collect this information in a layer 4 (TCP) event.

     

  • Hi Kevin,

     

    Yes, we would ideally like to see the list of ciphers presented by the client Smiley Happy

     

    Also, how can we log failed cipher negotiations when client and server fail to agree on using any cipher?

     

    Thank you for your help.

     

    H

     

  • So funny thing. I was working on a binary scan iRule to pull the client's cipher list out of the ClientHello message, almost finished, then Jason Rahm tells me he's already done this...

     

    https://devcentral.f5.com/articles/irules-101-17-mapping-protocol-fields-with-the-binary-scan-command

     

    And so not to reinvent the wheel, here's a customization of that code:

     

    when CLIENT_ACCEPTED {
        TCP::collect
    }
    when CLIENT_DATA {
        binary scan [TCP::payload] cSS rtype sslver rlen
    
        if { $rtype == 22 } {
    
            Collect rest of the record if necessary
            if { [TCP::payload length] < $rlen } {
                TCP::collect $rlen
            }
    
            skip record header and random data
            set field_offset 43
    
            set the offset
            binary scan [TCP::payload] @${field_offset}c sessID_len
            set field_offset [expr {$field_offset + 1 + $sessID_len}]
    
            Get cipherlist length
            binary scan [TCP::payload] @${field_offset}S cipherList_len
    
            Get ciphers, separate into a list of elements
            set field_offset [expr {$field_offset + 2}]
            set cipherList_len [expr {$cipherList_len * 2}]
            binary scan [TCP::payload] @${field_offset}H${cipherList_len} cipherlist
    
            set clist [list]
            for { set i 0 } { $i < [string length $cipherlist] } { incr i 4 } {
                lappend clist [string range $cipherlist $i [expr $i + 3]]
            }
            set cliststr [join $clist ","]
            log local0. "Client: [IP::client_addr] attempts SSL with ciphers: $cliststr"
        }
        TCP::release
    }
    when CLIENTSSL_HANDSHAKE {
        log local0. "Client: [IP::client_addr] successfully negotiates [SSL::cipher name]"
    }
    

    From that you'll get log statements like the following:

     

    : Client: 10.70.0.1 attempts SSL with ciphers: 00ff,c024,c023,c00a,c009,c008,c028,c027,c014,c013,c012,c026,c025,c005,c004,c003,c02a,c029,c00f,c00e,c00d,006b,0067,0039,0033,0016,003d,003c,0035,002f,000a,c007,c011,c002,c00c,0005,0004,00af,00ae,008d,008c,008a,008b
    : Client: 10.70.0.1 successfully negotiates DHE-RSA-AES256-SHA
    

    These 4 character hex values directly correlate to RFC-based cipher strings:

     

    http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml

     

    And as Jason does you're welcome to add all 300+ cipher strings and hex codes to a datagroup to get the literal string in the log.

     

    This doesn't specifically address your last requirement (logging a failed handshake and what cipher they tried), but that's a bit more complex and wanted to get this out first.

     

  • Fantastic work Sir!

     

    Thank you so much for your help with this.

     

    Will wait for your update about the last piece that is left Smiley Happy

     

    Regards,

     

    H

     

  • The thing is, that last requirement isn't something you can really do with an iRule. If you're looking for a handshake failure based on non-acceptance of a given set of client-supplied ciphers, then

     

    1. This essentially happens before or rather in lieu of the server's first SSL handshake response - the connection is reset (FIN).

       

    2. There's no response event in the client side context (as in an event triggered when the BIG-IP responds to a client), so there's really no way to collect the BIG-IP's SSL alert message.

       

    That said, as a programmable platform there isn't much the BIG-IP can't do, and so I'd caveat my last statements by saying that it technically can be done, but the solution may be a bit more complex. The idea is basically something called "VIP targeting". This is where you put one virtual server in front of another and use a special virtual command in an iRule on the external VIP to steer traffic to the internal VIP.

     

    when CLIENT_ACCEPTED {
        virtual internal-vs
    }

    In this way you can actually create a response event in the client context because the internal VIP's response (the one you care about) is a response in the server side context of the external VIP. Confusing yet?

     

    client -> external VIP -> internal VIP -> server

    Assuming you continued to do SSL offload on the internal VIP and used the external VIP as a layer 4 proxy, it would be able to see an SSL handshake alert coming from the internal VIP. Coincidentally, because the previous iRule is collecting data at layer 4 and because the client's cipher list is presented in an unencrypted portion of the SSL handshake, you could move all of that code minus the CLIENTSSL_HANDSHAKE event to the external VIP. And so the your second requirement you'd just watch for the internal VIP's ServerHello to grab the selected cipher.

     

    Ultimately though, you may be better off simply not trying to capture the failure and troubleshooting SSL as it happens, in favor of not adding the additional complexity as described.

     

  • Kevin,

     

    I really appreciate all your help.

     

    I never expected to receive such a detailed response from anyone.

     

    Can't thank you enough for this!

     

    Regards,

     

    Humair