Forum Discussion
hui_37443
Nimbostratus
Feb 24, 2010auth_result fired twice?
We have implemented an iRule to do OCSP check, based on the prize winner http://devcentral.f5.com/Default.aspx?tabid=108. When it encounters an error, it doesn't resume the suspended SSL::handshake.
when AUTH_RESULT {
if {[info exists tmm_auth_ssl_ocsp_sid] and $tmm_auth_ssl_ocsp_sid eq [AUTH::last_event_session_id]} {
set tmm_auth_status [AUTH::status]
log local0.debug "authentication status of round 1 $tmm_auth_status"
if {$tmm_auth_status eq 0} {
Success
log local0.debug "OCSP verfication succeeded"
SSL::handshake resume
lset ssl_array 1 "auth_success"
} elseif {$tmm_auth_status eq 1} {
Failure
log local0.debug "OCSP verfication failed"
SSL::handshake resume
lset ssl_array 1 "auth_failure"
} elseif {$tmm_auth_status eq -1} {
Error
log local0.debug "OCSP verfication error"
lset ssl_array 1 "auth_failure"
}
else {
Not authorised
log $tmm_auth_status
log local0.debug "OCSP verfication not authorised"
reject
}
session add ssl "$id any pool" $ssl_array 21600
}
}
From the client browser, we can see the error page shown promptly. However, in the log there is an TCL parsing error:
Feb 22 17:35:10 tmm tmm[1786]: 01220001:3: TCL error: cbz_ocsp_action - can't read "ssl_array": no such variable while executing "lset ssl_array 1 "auth_failure"
From the timestamp, it is more a couple of minutes later than the OCSP check. Looks like to me the event AUTH_RESULT is fired twice. Once right after the OCSP check, and the other a while later.
Not sure whether I need to resume the SSL::handshake?
- hoolio
Cirrostratus
In the example iRule, ssl_array is set in the CLIENTSSL_CLIENTCERT event. Is it possible that this event isn't triggering when a client doesn't present a cert? Else, can you add logging to the rest of the rule, reproduce the problem and post the logs? - Craig_Reeve
Nimbostratus
Sorry for hijacking your issue Hui but mine sounds very similar to yours and my investigation my assist us both in getting a resolution :-) - hui_37443
Nimbostratus
Aaron, - hoolio
Cirrostratus
Hi Hui,http://devcentral.f5.com/wiki/default.aspx/iRules/client_cert_request_by_uri_with_ocsp_checking.html TODO: If the OCSP responder is an LTM VIP (used for load balancing multiple OCSP servers) you could add a check here of the OCSP server pool before attempting the OCSP validation. Just change my_ocsp_http_pool to the actual OCSP server pool name. Check if the OCSP server pool does not have any if {[active_members my_ocsp_http_pool] == 0}{ OCSP servers are not available!! log local0.emerg "$log_prefix: OCSP auth pool is down! Resuming SSL handshake and blocking HTTP request." Audit logging if {$::ocsp_audit_log_level > 0}{ catch {log -noname local0. "cc_audit: $log_prefix; status_text=OCSP server pool is unavailable. Blocking request."} } We could send an HTTP response from this event, but it doesn't actually get sent until the CLIENTSSL_HANDSHAKE event anyhow. So track that this is an invalid request and set the app auth status code to indicate OCSP validation of the cert failed. set invalidate_session 1 SSL::handshake resume return } TODO END:
- hui_37443
Nimbostratus
Hi, - Craig_Reeve
Nimbostratus
Hi Hui, - hoolio
Cirrostratus
Thanks for the tip Craig. Hui, if that doesn't work for you, can you edit your post or reply again with the iRule in [ code ] [/ code ] blocks (without the spaces) to preserve the iRule spacing? - hui_37443
Nimbostratus
Craig, I've tried your solution but with no luck. However, it is quite interesting to notice that the second auth_result event fires 310 secs later, instead of original 300! Therefore it suggests that the auth profile idle time setting dictates when the second auth_result event occurs (if there is one). In other words, the second auth_result is actually a timeout.when CLIENT_ACCEPTED { set tmm_auth_ssl_ocsp_sid [AUTH::start pam default_ssl_ocsp] log local0.debug "inside event CLIENT_ACCEPTED $tmm_auth_ssl_ocsp_sid" } when CLIENTSSL_CLIENTCERT { set ssl_cert [SSL::cert 0] set id [SSL::sessionid] set hash [b64encode [sha1 $ssl_cert]] set ssl_array [list blah1 blah2 $hash] lset ssl_array 0 [X509::verify_cert_error_string [SSL::verify_result]] log local0.debug "verify result [lindex $ssl_array 0]" if {[matchclass 1 equals $::cbz_ocsp_check]} { AUTH::cert_credential $tmm_auth_ssl_ocsp_sid $ssl_cert AUTH::cert_issuer_credential $tmm_auth_ssl_ocsp_sid [SSL::cert issuer 0] AUTH::subscribe $tmm_auth_ssl_ocsp_sid AUTH::authenticate $tmm_auth_ssl_ocsp_sid log local0.debug "doing OCSP" SSL::handshake hold } else { log local0.debug "ocsp bypassed" lset ssl_array 1 "ocsp_bypassed" session add ssl "$id any pool" $ssl_array 21600 } } when AUTH_RESULT { if {[info exists tmm_auth_ssl_ocsp_sid] and $tmm_auth_ssl_ocsp_sid eq [AUTH::last_event_session_id]} { set tmm_auth_status [AUTH::status] log local0.debug "authentication status of round 1 $tmm_auth_status, $tmm_auth_ssl_ocsp_sid" if {$tmm_auth_status eq 0} { Success log local0.debug "OCSP verfication succeeded" SSL::handshake resume lset ssl_array 1 "auth_success" } elseif {$tmm_auth_status eq 1} { Failure log local0.debug "OCSP verfication failed, [AUTH::response_data]" SSL::handshake resume lset ssl_array 1 "auth_failure" } elseif {$tmm_auth_status eq -1} { Error log local0.debug "OCSP verfication error, [AUTH::response_data]" lset ssl_array 1 "auth_failure" } else { Not authorised log local0.debug "OCSP verfication not authorised" reject } session add ssl "$id any pool" $ssl_array 21600 } } when HTTP_REQUEST priority 100 { log local0. "Inside ocsp" if {not([matchclass [string tolower [HTTP::path]] contains $::cbz_data_static])} { if {[matchclass 1 equals $::cbz_ocsp_check]} { set id [SSL::sessionid] set ssl_array1 [session lookup ssl "$id any pool"] set ssl_data0 [lindex $ssl_array1 0] set ssl_data1 [lindex $ssl_array1 1] log local0.debug "session id: $id ssl_data0: $ssl_data0 ssl_data1: $ssl_data1" if { $ssl_data0 contains "expired" } { log local0.debug "Certificate expired" HTTP::path "/common/common.web/html/CertificateExpired.html" } elseif { $ssl_data1 contains "auth_failure" } { log local0.debug "Authentication failure" HTTP::path "/Common/Common.Web/html/OcspFailed.html" } elseif { $ssl_data0 contains "ok" } { HTTP::header insert SSLCLientCertStatus $ssl_data1 } else { log local0.debug "unknow error" HTTP::path "/common/common.web/html/CertificateError.html" } } else { log local0.debug "Generate ocsp bypass header" HTTP::header insert OcspBypassed 1 } } }
- hoolio
Cirrostratus
Hui, - Craig_Reeve
Nimbostratus
Hui, It's a shame this didn't work out for you but sounds like you may have another piece in your puzzle. Maybe 310 secs is too still low for your situation but at the end of the day the sessions should terminate cleanly anyway and hence these timeouts shouldn't be invoked. We never found out why most of our customers worked correctly and only a handful consistently failed with the duplicate AUTH_RESULT. Given that the client devices were exactly the same running the same code we put it down to either their internal network configuration, their ADSL modem vendor, or their ISP, or a mixture of those, or something we just hadn't thought of. In other words we have no idea but as the 310 sec timeout change resolved the issue for these very few occurrences we stopped looking. I think Aaron is right in suggesting you open a support case as if your issue and mine are loosely related, maybe having two sets of different data may assist F5 in determining the cicumstances that causes this to happen.
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects