Forum Discussion

augustusk's avatar
augustusk
Icon for Nimbostratus rankNimbostratus
Dec 02, 2015

APM iRule Event

I need some assistance on why I get no value for the client certificate CN when running below iRule. The variable $user gets a value but $cn does not :-(. I have looked in /var/log/ltm and nothing. The end goal is to ensure the username for my APM login page matches the client certificate subject received from client. I need to fill the $cn value to do a comparison and then deny or allow accordingly.

 

when ACCESS_POLICY_AGENT_EVENT { set user [ACCESS::session data get "session.logon.last.username"] log local0. "User Login Name: $user" }

 

when CLIENTSSL_CLIENTCERT { set cn [X509::subject [SSL::cert 0]] log local0. "Common Name: $cn"

 

}

 

8 Replies

  • Lucas_Thompson_'s avatar
    Lucas_Thompson_
    Historic F5 Account

    Also, set the clientssl profile certificate to request. APM has two different ways to do client certs: You can set the clientssl profile to request them, OR you can set the clientssl profile to not request them and use On-Demand cert authentication.

     

    If you use on-demand, the certificate is requested via SSL renegotiation during Access Policy execution and the cert's properties are available as session variables automatically. This means that you don't really have to use irules at all (which is preferred for simplicity's sake), you can use branch rules in the VPE and send the user to a remediation page or whatever user-friendly error you want at the end of the Access Policy.

     

  • Thanks and will try your recommendation. Update once tested

     

  • I ensured that the client side ssl profile did "ignore" requests for client certificates. I then ensured the on-demand cert auth requested a client certificate which works (I see my machine presenting certificate). I then created another on-demand cert auth with a require option for client certificate. I then created the branch rules below on the second on-demand cert auth. The first works as expected but when trying to acquire subject, common name, issue, etc...this fails. I am stomped. Thanks Kris

     

    expr { [mcget {session.ssl.cert.cn} ] contains "myName" }

     

    this fails. Not finding common name and ensured case matched. I also tried ensuring lower case with [string tolower [mcget {session.ssl.cert.name}]]

    expr { [mcget {session.ssl.cert.exist} ] == "0" }

     

    this passes and allows access. Client cert exists
  • John_Alam_45640's avatar
    John_Alam_45640
    Historic F5 Account

    Kris, do you see the CN in the session variables under "reports/active sessions/session variables"?

     

  • Lucas_Thompson_'s avatar
    Lucas_Thompson_
    Historic F5 Account

    The way that client cert works (and the session variables available) is different between "on-demand" and setting the clientssl profile to Request or Require. You should try using it in both modes.

     

    Logging will help you here. Set the Access log level to Informational and check /var/log/apm.

     

  • Below is the iRule I have that should be setting a variable called session.custom.query_result. According to the value, the user will not be allowed access. I am trying to match the client certificate name to the logonname. Any help is appreciated. Best, Kris

     

    when ACCESS_POLICY_AGENT_EVENT { if { [ACCESS::session data get session.ssl.cert.x509extension] contains "othername:UPN<" } { set uname [ACCESS::session data get [lindex [split [findstr [ACCESS::session data get session.ssl.cert.x509extension] "othername:UPN<" 14 ">"] "@"] 0]] set login [ACCESS::session data get "session.logon.last.username"] } if { $uname contains $login} { ACCESS::session data set session.custom.query_result 0 } else { ACCESS::session data set session.custom.query_result 1 }

     

    }

     

  • Hi,

    you can evaluate tcl in variable assign instead of irule event. most of tcl commands are implemented in variable assign but some tcl command are not yet. add a ; at the end of every commands as APM remove new lines.

    to extract UPN from certificate, create a variable assign with expression:

    session.logon.last.certupn = 
    set extension [string tolower [mcget {session.ssl.cert.x509extension}]];
    return [string range $extension [expr {[string first "othername:UPN<" $extension] +14}] [expr {[string last ">" $extension] -1}] ];
    

    if you want to create a variable which compare both strings:

    session.custom.query_result = 
    if { [mcget {session.logon.last.certupn}] contains [string tolower [mcget {session.logon.last.username}]]} { return 0 } else { return 1}
    

    or create a branch with expression:

    expr { [mcget {session.logon.last.certupn}] contains [string tolower [mcget {session.logon.last.username}]] }