Forum Discussion

Tom_Lebel_53961's avatar
Tom_Lebel_53961
Icon for Nimbostratus rankNimbostratus
Jul 07, 2006

need a rule to force client certs

I am in an odd dilema. I need to write an iRule to do the same thing as 'require' setting does for client certs.

Problem exists, because I need to require client certs by regulation, and one of the applications uses Sun's JVM version 1.4.2_xx. It works off of an Oracle 10g IAS server (release 1). The 10g server at this release cannot use the 1.5 version of the JVM. The 1.4.2 version has a bug in it (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4480333)

The bug is it basically can't do client certs. The 1.5 version fixed this bug.

I want to set an iRule that makes the user present a cert at the first entry to the session, then not worry about it if that session is still in existance. If they fail to present a cert, do a HTTP::redirect.

Here's what I'm starting with, am I on the right track?


 when HTTP_REQUEST {
if { [SSL::verify_result] eq "ok" }
{set SSL_cert eq "recvd"
}
else
{ HTTP::redirect "https://someotherpage.com/" }
}

10 Replies

  • Hi,

     

     

    You could probably get a start with this post: Click here

     

     

    Take a look at the wiki pages on SSL::cert (Click here) or search the 9.x forum for 'require client cert' to find related posts.

     

     

    Aaron
  • Thanks, that did get me started. Now I have this:

    when HTTP_REQUEST {
    if {[HTTP::uri] starts_with "/ASITE/" }
    {HTTP::collect [HTTP::header Content-Length]
    SSL::cert mode require
    SSL::renegotiate}
    else
    {SSL::cert mode request
    }
    }

    but it doesn't work.

    Originally I had an HTTP::release after the SSL::cert mode request in the else statement, but I don't know what that's supposed to do.

    On the server side, I've got the Apache set up, that when a call to /ASITE/ comes in, it redirects to the real site URI, so I figured, at that point it would only request the client cert, and not require it.

    Thoughts?

    Tom
  • It appears, evry time I have a SSL::renegotiate, it fails with a Cannot find server or DNS Error

     

    .
  • Ok. Getting there. Now I am wondering if someone can explain why this is working? Can anyone give me a section by section explaination of this?

    Also, I need to have it do an 'OR' in the if statement that looks at the URI, but the editor doesn't like my syntax. How do you do an OR in an IF statement? I need it to do this for /ASITE OR /BSITE.

    when CLIENT_ACCEPTED {  
    set session_flag 0 
    }
    when CLIENTSSL_HANDSHAKE {  
    log LOCAL0.warn "cert count=[SSL::cert count]" 
    if {[SSL::cert count] == 0 }
    { 
    log LOCAL0.warn "when client handshake,ssl cert count is 0,pass"  
    }
    else {log LOCAL0.warn "when clent handshake , two way cert found and the cert count is [SSL::cert count] "    
    HTTP::release}  
    log "Session flag is $session_flag"}
    when HTTP_REQUEST {
    if {[HTTP::uri] starts_with "/ASITE"}
    {log "Requiring certificate...and the request uri is :[HTTP::uri]"
    if {[SSL::cert count] == 0}
    {        
    log local0. "when http request,ssl cert count is 0,now http collect"
    HTTP::collect    
    SSL::authenticate always    
    SSL::authenticate depth 9    
    SSL::cert mode require    
    log local0. "when http request,now renegotiating"    
    set session_flag 1         
    SSL::renegotiate    
    }  
    }
    else
    {        
    log LOCAL0.warn "No cert needed,to server directly.And the uri is [HTTP::uri]"  }  
    log "Session_flag at end of http_request is $session_flag"
    }
  • 
    if { ([HTTP::uri] starts_with "/ASITE") or ([HTTP::uri] starts_with "/BSITE")} {
      ...
    }

    make sure you want to be absolute with your case in the URI, otherwise you may want to add a string tolower command on the URI prior to comparison.

    HTH,

    Jason
  • That explains why my OR didn't work. So I need to add

    
    if { ([HTTP::uri] starts_with "/ASITE") or ([HTTP::uri] starts_with "/BSITE") or ([HTTP::uri] starts_with "/asite") or ([HTTP::uri] starts_with "/bsite")} {
      ...
    }

    Anybody want to tackle an explaination on what the sections are actually doing? I understand the SSL:: parts, and how they change the settings, but what is local0.warn? Why set session_flag to 0? etc?
  • I think citizen_elah was actually suggesting you use string tolower to make the condition simpler:

    
    if { [string tolower [HTTP::uri]] starts_with "/asite" or [string tolower [HTTP::uri]] starts_with "/bsite" }{
       ...
    }

    If you have a lot of comparisons like this to make, you might want to add them to a datagroup and use matchlass or use switch.

    I'll leave the analysis of the rule to the others...

    Aaron
  • I have make the rules your post working. sure, it works, but only for version 9.1.2. 9.2.3 and 9.4.0 beta may have some bug on "Cert Mode", so you can't use them in 9.2.3 or higher now.

     

  • Thanks for the info on the rule. While I don't plan on using this forever, I also don't plan on updating F5 from my current release unless there's a security patch. In the meantime, this iRule is only in plaec until we can start using JVM 1.5, which should be by end of this year.

     

     

    One of the problems I do have, is I don't understand what all the lines are doing, and iRule documentation is light (at best).

     

     

    Thanks.