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

AndOs's avatar
AndOs
Icon for Cirrostratus rankCirrostratus
Sep 22, 2012

Sporadic TCL erros from iRule after upgrade to 11.2.0

Hi!

We're using an irule to handle access to a webservice.

The irule matches the client certificate DN against a list of allowed DNs, and is the only irule assigned to the VIP.

After upgrading from v10.2.0 to 11.2.0 we're occasionally getting this error in /var/log/ltm

tmm err tmm[7146]: 01220001:3: TCL error: /Webservices/certificate_verify_irule - can't read "client_cert_ok": no such variable while executing "if {$client_cert_ok == 0} { HTTP::respond 403 content "Bad client certificate! ($subject_dn)" set client_cert_ok 0 }"

The error complains about not beeing able to read the variable client_cert_ok, but works most of the time.

Searching the forums I found this post (TCL Error:no such variable while executing)

The replies there talks about RULE_INIT, but in this case, putting client_cert_ok in RULE_INIT will make it global, right? And I need it to be "local" for each client.

Appreciate all tips on how to solve this.

I have a vague idea that it might be CMP related, but I'm not that skilled in irules to see if there's cmp issue with this one.

Thanks!

/Andreas

 Derived from https://devcentral.f5.com/wiki/default.aspx/iRules/ClientCertificateCNChecking.html

when RULE_INIT {
}

when CLIENTSSL_CLIENTCERT {

    init allowed/disallowed flag
    default not allowed.
   set client_cert_ok 0

    Check if client provided a cert
   if {[SSL::cert 0] eq ""} {

      log local0. "No client cert presented!"
       Reset the connection
      reject

   } else { 

       Get the subject DN from cert.
      set subject_dn [X509::subject [SSL::cert 0]]

       Check trusted certs.
      switch -glob [string tolower $subject_dn] {
          "...DN1..." -
          "...DN2..." {
                    Client cert is allowed. Set flag.
                   set client_cert_ok 1
                   log local0. "Matching client cert: $subject_dn | Client='[IP::client_addr]'"
            }
          default {
              log local0. "NO MATCHING CLIENT CERTIFICATE!: $subject_dn | Client='[IP::client_addr]'"
              reject
          }
      }
   }
}

when HTTP_REQUEST {

 Client sent an HTTP request.

     check if the client cert for this connection was trusted.
     if it was not, send an error message to the client.
    if {$client_cert_ok == 0} {
         HTTP::respond 403 content "Bad client certificate! ($subject_dn)"
         set client_cert_ok 0
    }
}

2 Replies

  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    If the client resumes an existing SSL session, they wouldn't hit the CLIENTSSL_CLIENTCERT event as they don't present the cert for that connection. You could change your check in HTTP_REQUEST to verify the variable exists and is set to 1:

    
    when HTTP_REQUEST {
    
    if { [info exists client_cert_ok] and $client_cert_ok == 1 }{
     Allow request
    } else {
    HTTP::respond 403 content "Bad client certificate!"
    }
    }
    

    Aaron
  • AndOs's avatar
    AndOs
    Icon for Cirrostratus rankCirrostratus
    Ah, ok.

     

    Thanks.

     

     

    And to track a client trough multiple requests, I guess I need to use the session table to keep it compatlible with CMP?

     

     

     

    /Andreas