Forum Discussion

ashbeyk_127079's avatar
ashbeyk_127079
Icon for Nimbostratus rankNimbostratus
Sep 22, 2005

Conditional client cert and LDAP auth

I am trying to create a reverse proxy using iRules. This requires that certain URLs require client certs, others dont and that certain URLs require LDAP auth, others dont.

 

I am checking the passed URL in an irule attached to an LDAP auth profile configuration (HTTP_REQUEST event) and forcing an SSL::renegotiate if a cert is required, however I can't then get this same rule to send back a 401 message to require LDAP auth. The only way I can see is to set a variable ie "set need_ldap 1" then check this in the HTTP_RESPONSE event. This works but doesnt seem very efficient. Any thoughts?
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    I'm not sure I fully understand the sequence of steps you are trying to force, but it does sound like you could force a response when you know you want LDAP. Try "HTTP::respond 401" in the HTTP_REQUEST event.
  • This is part of my code:

     

    when HTTP_REQUEST {

     

    .

     

    .

     

    if {$target_app != 0} {

     

    if {([lsearch -exact $::apps_needing_cert $target_app] != -1) && ($have_cert == 0)} {

     

    log local0. "Cert required, forcing renegotiate"

     

    HTTP::collect

     

    SSL::cert mode require

     

    SSL::renegotiate

     

    set need_cert 1

     

    set need_ldap 1

     

    log local0. "Setting need_cert to 1"

     

    log local0. "Setting need_ldap to 1"

     

    log local0. "Cert required, sent renegotiate"

     

    if I put the 401 here it doesnt work-I just get a "not found" page.

     

    HTTP::respond 401 content "" "WWW-Authenticate" "BASIC realm=\"$::realm\""

     

     

    The HTTP::release is here:

     

     

    when AUTH_SUCCESS {

     

    log local0. "auth success event"

     

    if {$tmm_auth_ldap_sid eq [AUTH::last_event_session_id]} {

     

    log local0. "ldapauth success"

     

    set have_ldap 1

     

    log local0. "have_ldap set to 1"

     

    HTTP::release

     

    }

     

     

     

    I'm doing this at the moment which works:

     

    when HTTP_RESPONSE {

     

    .

     

    .

     

    if {($have_cert eq "needs_renew") && ($target_app ne $::cert_renewal_app) } {

     

    log local0. "expiring cert-redirecting to $::cert_renewal_page"

     

    HTTP::redirect $::cert_renewal_page

     

    } elseif {($need_ldap == 1) && ($have_ldap == 0)} {

     

    log local0. "ldap required"

     

    HTTP::respond 401 content "" "WWW-Authenticate" "BASIC realm=\"$::realm\""

     

  • The sequence of events is:

     

    In HTTP_REQUEST:

     

    1) Check incoming URL

     

    2) If target needs a client cert then do SSL::renegotiate

     

    3) If target also needs LDAP auth (which should be prompted for after the cert auth), send back a 401

     

     

    If I try to do both 2 and 3 in the HTTP_REQUEST section I see the following when running some snooping software on the IE browser:

     

    ERROR_INTERNET_SECURITY_CHANNEL_ERROR

     

     

    The only way I can get it to work is to allow the connection through to the back end server then intercept the response with HTTP_RESPONSE and change it to send a 401 back to the browser. This works but I dont want any traffic to reach the back end server before all auth has completed.

     

     

    Firefox behaves differently-the LDAP auth dialog appears first followed by the cert dialog ~ 20 seconds later. Again this is not ideal.

     

     

    So, is there any way to do conditional cert auth and LDAP auth after examining the incoming URL but before any traffic has reached the target server?

     

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    This does seem broken to me. Can you open a support case so we can collect the necessary information to try to reproduce it here.

     

    Thanks.