Forum Discussion

Clayton_63491's avatar
Clayton_63491
Icon for Nimbostratus rankNimbostratus
May 28, 2009

SSL Certificate Info put in HTTP Header after Renegotiate

I am trying to create a virtual server that can route traffic to different pools based on the URI, and can require client certificates only for specific URI patterns.

 

 

When the client certificates are required, I need to renegotiate the SSL and pass the client certificate subject in an http header to the pool destination. I need to be able to change the SSL profile to “clientprofile_1IBE_LCMX_cert_required” before the renegotiate so that the browser will present only certificates issued by a certain CA.

 

 

I have found numerous examples of pieces of this and have created the scenario below. It works as far as requiring a client cert only for the URI that begins with /certreq, but I then the request never gets sent to the selected pool.

 

 

In looking at my debug statements in the log, it looks like the HTTP_REQUEST_SEND event is not triggered after the SSL::renegotiate is done and the client certificate is sent. Is there something else that I have to do to release the http request after the SSL::renegotiate.

 

 

I am a newbie with irules, so any help would be appreciated. We are using version 9.4.7.

 

 

virtual vs_1IBE_MyApp {

 

snat automap

 

pool pool_1IBE_App1_dev

 

destination 192.168.1.18:20000

 

ip protocol tcp

 

rules irule_1IBE_ssl_renegotiate

 

httpclass

 

http_1IBE_LCMX_App1_a0

 

http_1IBE_LCMX_App2_a0

 

profiles

 

clientprofile_1IBE_LCMX_nocert

 

f5-dev-crypto-server

 

http

 

oneconnect

 

tcp

 

}

 

 

 

rule irule_1IBE_ssl_renegotiate {

 

when CLIENTSSL_CLIENTCERT {

 

log local0. "MyApp SSL verify_result is [SSL::verify_result]"

 

log local0. "MyApp SSL cert count is [SSL::cert count]"

 

set certcnt [SSL::cert count]

 

if { $certcnt > 0} {

 

log local0. "LCMatrix client certificate found. HTTP::release"

 

set ssl_cert [SSL::cert 0]

 

set ssl_subject [X509::subject $ssl_cert]

 

log local0. "LCMatrix client certificate subject is $ssl_subject for session [SSL::sessionid]"

 

session add ssl [SSL::sessionid] $ssl_subject 1200

 

log local0. "MyApp client certificate found. HTTP::release"

 

HTTP::release

 

}

 

}

 

when HTTP_REQUEST {

 

log local0. "MyApp request received for [HTTP::uri]"

 

if { [HTTP::uri] starts_with "/certreq" } {

 

set ssl_subject [session lookup ssl [SSL::sessionid]]

 

log local0. "MyApp client certificate required for: [HTTP::uri]"

 

if { $ssl_subject equals "" } {

 

log local0. "MyApp client certificate not found. Holding HTTP request until a client cert is presented..."

 

HTTP::collect

 

SSL::authenticate always

 

SSL::authenticate depth 9

 

SSL::cert mode require

 

SSL::renegotiate

 

set ssl_subject [session lookup ssl [SSL::sessionid]]

 

}

 

session add ssl [SSL::sessionid] $ssl_subject 1200

 

}

 

}

 

when HTTP_REQUEST_SEND {

 

clientside {

 

if { [HTTP::uri] starts_with "/plintl00" } {

 

pool pool_1IBE_LCMX_App2_a0

 

HTTP::header insert "X-SSL-Client-Cert-Subject"[X509::subject [SSL::cert 0]]

 

log local0. "MyApp subject header inserted [X509::subject [SSL::cert 0]]"

 

}

 

log local0. "MyApp request sent for [HTTP::uri]"

 

}

 

}

 

}

 

 

 

profile clientssl clientprofile_1IBE_LCMX_cert_required {

 

defaults from clientssl

 

key "keyf5cloudtest.key"

 

cert "cerf5cloudtest.crt"

 

client cert ca "ca-CommercialRSA.crt"

 

peer cert mode ignore

 

}

 

profile clientssl clientprofile_1IBE_LCMX_nocert {

 

defaults from clientssl

 

key "default.key"

 

cert "default.crt"

 

}

 

profile serverssl f5-dev-crypto-server {

 

defaults from serverssl

 

key "datapower_cert.key"

 

cert "datapower_cert.crt"

 

chain none

 

ca file none

 

ciphers "DEFAULT"

 

passphrase "abcdefghij"

 

options

 

dont insert empty fragments

 

modssl methods disable

 

renegotiate period indefinite

 

renegotiate size indefinite

 

unclean shutdown enable

 

strict resume disable

 

handshake timeout 60

 

alert timeout 60

 

cache size 20K

 

cache timeout 3600

 

}

 

 

 

profile httpclass http_1IBE_LCMX_App1_a0 {

 

defaults from httpclass

 

pool pool_1IBE_LCMX_App1_a0

 

redirect none

 

url rewrite none

 

asm disable

 

paths "/App1*"

 

}

 

profile httpclass http_1IBE_LCMX_App2_a0 {

 

defaults from httpclass

 

pool pool_1IBE_LCMX_App2_a0

 

redirect none

 

asm disable

 

paths "/App2*"

 

}

 

 

pool pool_1IBE_LCMX_App1_a0 {

 

monitor all https

 

members 192.168.1.18:10000

 

}

 

pool pool_1IBE_LCMX_App2_a0 {

 

monitor all https

 

members 192.168.1.18:20000

 

}

 

4 Replies

  • I noticed that after the SSL::renegotiate, the CLIENTSSL_CLIENTCERT event is triggered. The HTTP::release in the CLIENTSSL_CLIENTCERT event does not cause the HTTP_REQUEST_SEND event to be triggered. So the HTTP request is never sent to the pool. Is there any known problems in 9.4.7 that would prevent the HTTP::release from releasing the HTTP payload?
  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    That looks like it should work, but there's a lot going on and I didn't look in-depth. Can you add a line that logs in HTTP_REQUEST_DATA, just to see if that event fires after the HTTP::release?
  • Did you ever figure this out? Was it a post request? I wonder if you removed the HTTP classes whether it would affect the issue.

     

     

    Aaron
  • Actually, was the pool down, by chance? I saw HTTP_REQUEST_DATA not trigger in a test for a related iRule (Click here) when the pool was down.

     

     

    On the other hand, TMM was crashing for me on 9.4.7 when I tested with a client presenting a valid cert.

     

     

    Aaron