Forum Discussion

Brad_10788's avatar
Brad_10788
Icon for Nimbostratus rankNimbostratus
Jul 08, 2010

Selective request of Certificate and passing in header rule

New to irules so bear with me. Trying to create an irule that will only request a client cert for certain urls so I will not have the SSL client setting for the profile requesting the cert for all requests. We are passing this cert to an Oracle App Server for login purposes. I have 2 irules in test that both accomplish a piece of what I want but having trouble getting it all together. The 1st rule only requests cert for a particular URL and errors out OK. The 2nd rule works to pass the cert properly for our login configuration but it is assuming that the LB has already requested the cert from the browser through the ssl client profile. I am missing something with the flow here to get these 2 together. Any help GREATLY appreciated.(BIG-IP 10.0.1)

 

--------------

 

will request the cert like I want

 

--------------

 

brad-test1

 

when CLIENT_ACCEPTED {

 

set session_flag 0

 

set cert_error 0

 

set allzeros [string repeat "0" 64]

 

}

 

when HTTP_REQUEST {

 

if { [HTTP::uri] ends_with "certinfo.jsp" } {

 

log local0. "Certificate required for: [HTTP::uri]"

 

Remaining issue is cashed sessions and how to deal with them b/c afer a failure the session will pass through the check

 

if { [SSL::cert count] == 0} {

 

log local0. "No cert found. Holding HTTP request until a client cert is presented..."

 

HTTP::collect

 

log local0. "HTTP::collect"

 

set session_flag 1

 

log "session_flag 1"

 

SSL::authenticate always

 

log local0. "SSL::authenticate always"

 

SSL::authenticate depth 9

 

log local0. "SSL::authenticate depth 9"

 

SSL::cert mode request

 

SSL::cert mode require

 

log local0. "SSL::cert mode request"

 

SSL::renegotiate

 

log local0. "SSL::renegotiate"

 

 

set id [SSL::sessionid ]

 

set the_cert [session lookup ssl $id]

 

log local0. "we are here near the end"

 

log $id

 

log $the_cert

 

}

 

else {

 

HTTP::redirect ""

 

log local0. "HTTP::redirect to ssologin_nocert.php"

 

}

 

}

 

else {

 

log local0. "No certificate needed for: [HTTP::uri]"

 

}

 

}

 

when CLIENTSSL_HANDSHAKE {

 

log "cert count=[SSL::cert "count"]"

 

set ssl_cert [SSL::cert 0]

 

set sid [SSL::sessionid]

 

Trying to test and see if i can force a check for certs? set ask [session lookup ssl $sid]

 

log $ssl_cert

 

log $sid

 

 

if { [SSL::cert count] == 0 } {

 

log local0. "when client handshake,ssl cert count is 0,pass"

 

if { $ssl_cert == "" && $session_flag == 1} {

 

log local0. "this is our second pass and the cert is still null "

 

This event could be caused by an invalid cert, card, and or pint.

 

How can we capture the failure and present it to an alternative page?

 

set cert_error 1

 

log local0. $cert_error

 

log local0. $session_flag

 

Currently the release will happen for the authentication but will contain a redirection

 

to the cac issues page

 

HTTP::release

 

}

 

if { ssl_cert != "" } {

 

log "cert is nothing"

 

}

 

}

 

else {

 

log "test 2"

 

log "when clent handshake , two way cert founded and the cert count is [SSL::cert "count"] "

 

HTTP::release

 

}

 

log "test 4"

 

}

 

when HTTP_REQUEST_SEND {

 

log "HTTP_REQUEST_DATA"

 

}

 

 

when HTTP_RESPONSE {

 

log "HTTP_RESPONSE"

 

if { $cert_error == 1 && $session_flag == 1} {

 

HTTP::respond 200 content {hum}

 

HTTP::redirect ""

 

log local0. "ah s hit 333333333"

 

set session_flag 0

 

set cert_error 0

 

Lets clean up the failed session

 

SSL::renegotiate

 

SSL::session invalidate

 

}

 

}

 

----------------------------------

 

Will pass the cert like I need it

 

---------------------------------

 

brad-test2

 

when CLIENTSSL_HANDSHAKE

 

{

 

set cur [SSL::sessionid]

 

set ask [session lookup ssl $cur]

 

if { $ask eq "" } {

 

session add ssl [SSL::sessionid] [SSL::cert 0]}

 

}

 

when HTTP_REQUEST

 

{

 

HTTP::header replace HTTPS on

 

set id [SSL::sessionid]

 

set the_cert [session lookup ssl $id]

 

if { $the_cert != "" }

 

{

 

set ssl_cert [SSL::cert 0]

 

log local0. "[X509::whole $ssl_cert]"

 

log local0. "what is going on.."

 

HTTP::header insert SSL-Client-Cert [ join [string trim [string map { "-----BEGIN CERTIFICATE-----" "" "-----END CERTIFICATE-----" ""} [X509::whole $ssl_cert ] ] ] "" ]

 

log local0. "ok now we know that we have a cert count > 1 can we assume that thats a valid cert?"

 

log local0. "**************************************************************************************"

 

log local0. [ join [string trim [string map { "-----BEGIN CERTIFICATE-----" "" "-----END CERTIFICATE-----" ""} [X509::whole $ssl_cert ] ] ] "" ]

 

log local0. "*************************************************************************************"

 

set headernames [HTTP::header names]

 

log local0. $headernames

 

set headersslclientcertvalue [HTTP::header value SSL-Client-Cert]

 

log local0. $headersslclientcertvalue

 

 

log local0. "We know that the cert has something ******************************"

 

log local0. $the_cert

 

} else {

 

HTTP::respond 200 content "

 

 

Access Denied

 

Access to this resource is denied without a valid

 

DOD Common Access Card. If you do not have one,

 

please visit the Assistance Nightmare website for information on obtaining a CAC card. Otherwise, please insert your CAC card into your reader, close this window, and try accessing this website again.

 

"

 

}

 

}

 

No RepliesBe the first to reply