Forum Discussion
Problem solved. Setting Client Certificate to "request" in the SSL client profile was the right move. Once I resolved the browser errors (which were totally misleading) everything started working as expected. I still don't understand why "ignore" seems to overwrite the "SSL::cert mode require" statement in the iRule.
As for the browser errors, they were entirely misleading. I discovered in the log this error which led me to the real solution: - Illegal argument. Can't execute in the current context. (line 1) invoked from within "HTTP::release "
In some cases my iRule was trying to run HTTP::release when HTTP::collect had never run. I solved that problem by just tracking when HTTP::collect was run and only running HTTP::release in those cases.
The working iRule is:
when CLIENT_ACCEPTED { set collected 0 }
when HTTP_REQUEST { if { [HTTP::uri] starts_with "/protected/" } { log local0. "Protected URI requested: [HTTP::uri]" if { [SSL::cert count] <=0 } { set collected 1 HTTP::collect SSL::authenticate always SSL::authenticate depth 9 SSL::cert mode require SSL::renegotiate } } }
when CLIENTSSL_CLIENTCERT { if { $collected eq 1 } { HTTP::release } if { [SSL::cert count] < 1 } { log local0. "No Certificate Provided" reject } }
- dctechs_180672May 15, 2015NimbostratusAnother update: With the change to "request" I needed to make sure un-protected URIs didn't get rejected during CLIENTSSL_CLIENTCERT so I added an if statement to only check for a certificate for protected URIs (tracked by the $protected variable). when CLIENT_ACCEPTED { set collected 0 set protected 0 } when HTTP_REQUEST { if { [HTTP::uri] starts_with "/protected/" } { set protected 1 log local0. "Protected URI requested: [HTTP::uri]" set collected 1 HTTP::collect SSL::authenticate always SSL::authenticate depth 9 SSL::cert mode require SSL::renegotiate } } when CLIENTSSL_CLIENTCERT { if { $collected eq 1 } { log local0. "HTTP release" HTTP::release } if { $protected eq 1 } { if { [SSL::cert count] < 1 } { log local0. "No Certificate Provided" reject } else { log local0. "Certificate Provided!" if { [class match [X509::serial_number [SSL::cert 0]] equals test-serial-num-list] } { log local0. "Client Accepted - IP:[IP::client_addr] Serial:[X509::serial_number [SSL::cert 0]]" accept client cert } else { log local0. "Client Rejected -IP:[IP::client_addr] Serial:[X509::serial_number [SSL::cert 0]]" reject } } } }