Forum Discussion

RiverFish's avatar
RiverFish
Icon for Altostratus rankAltostratus
Jun 04, 2014

Turn off client auth if uri equals

Customers connect to one IP. They connect with an app, not a browser. They use port 5443 to register (obtain a cert we issue) for the service, and port 443 for the actual service.

register: https://5.5.5.5:5443/register (1-way ssl) (get the cert)

service: https://5.5.5.5/service (2-way ssl) (use the cert)

We have a registration VS and a service VS. Both VS's have their own client ssl profile (no server profile). Below are the differences in the ssl profiles:

I am tasked with getting rid of port 5443 and making it so that customers can both register and hit the service on port 443/https. The majority of the traffic comes in on 443 with the occasional new customer registering first on 5443. The VS's point to different pools. We are running BIG-IP 11.3.0 Build 2806.0 Final.

With that being said, I'd like to make the 2-way ssl profile the default and turn off client auth if uri equals "/register". Here is what I have so far...

when HTTP_REQUEST {
     Turn off client auth for registration requests
    if { [HTTP::uri] contains "/register" } {
      SSL::cert mode ignore
      SSL::renegotiate enable
      SSL::renegotiate
      pool registration-pool  
      return
    } elseif { ([SSL::cert count] > 0) && ([HTTP::uri] contains "/service") } {
     scrub header
      HTTP::header remove chain
      HTTP::header remove client
      HTTP::header remove testCert
      HTTP::header remove ClientCert-Subject
      HTTP::header remove SSLClientCertSubject
      HTTP::header remove SSLClientCertThumbprint
       insert cert subject
      HTTP::header insert SSLClientCertSubject [X509::subject [SSL::cert 0]]
    } else {
      drop
    }
}

Concerns:

  • When to use "return" and "SSL::renegotiate"
  • Security (ssl renegotiate vulnerabilities)
  • Do I need to set variables?

Very grateful for any help on this. Thanks.

  • Hi, I need to revive this topic.

    I got request to configure LB to ask for client certificate when client goes to certain path, but NOT to ask in any another case. It means I cannot use "Client certificate - Request", but "Client certificate - Ignore" as default method in ssl profile.

    I tried some iRules when example was taken from here and from the last post in this channel.

    My current iRule is as follows:

    when CLIENTSSL_CLIENTCERT {
        if {[SSL::cert count] > 0} { set cert_count 1 }
        else { set cert_count 0}
        set ssl_status_code [SSL::verify_result]
        set ssl_status_desc [X509::verify_cert_error_string [SSL::verify_result]]
        log local0. "$ssl_status_code $ssl_status_desc, cert_count = $cert_count"
    }
    when HTTP_REQUEST {
       if { [info exists cert_count] } {
          return
       }
       else {
          set cert_count 0
       }
    
        Reject requests to the service if a cert was not presented
       if { [HTTP::host] eq "fqdn.com" and [string tolower [HTTP::path]] starts_with "/secure_path" } {
                if {$cert_count == 0}{
                   log local0. "1 - RENEGOTIATE cert_count = $cert_count, hostname: [HTTP::host][HTTP::uri]"
                   HTTP::collect
                   SSL::session invalidate
                   SSL::authenticate always
                   SSL::authenticate depth 9
                   SSL::cert mode require
                   SSL::renegotiate
    }           elseif {$cert_count == 1 and $ssl_status_code == 0}{
                   log local0. "2 - ACCEPT cert_count = $cert_count, \$ssl_status_code = $ssl_status_code, hostname: [HTTP::host][HTTP::uri]"
                    scrub existing headers  
                   HTTP::header remove chain
                   HTTP::header remove client
                   HTTP::header remove testCert
                   HTTP::header remove ClientCert-Subject
                   HTTP::header remove SSLClientCertSubject
                   HTTP::header remove SSLClientCertThumbprint
                    insert cert subject
                   HTTP::header insert SSLClientCertSubject [X509::subject [SSL::cert 0]]
                }
                else {
                   HTTP::respond 403 "Test page, you are rejected"
                   log local0. "3 - REJECT cert_count = $cert_count, hostname: [HTTP::host][HTTP::uri]"
                }
       }
       else {
          return
       }
    }
    

    It is not working because of variable cert_count. Eventhough it has value 1 in CLIENTSSL_CLIENTCERT part, it looks like it does not exists at all in HTTP_REQUEST part. Anyway, I think main reason is that I use Ignore as value of CLient Certificate in SSL profile, so then it looks it is somehow very hard to make user to renegotiate properly and show the cert.

    I am surprised all solutions comes with default method "Request" in ssl profile, but this way client gets option to select which client certificate to choose, and that is reasn why we cant use it as basic/default value in profile.

  • Hmm, silence :-) Is it even possible to apply client cert auth for specific uri and have SSL profile settings to be "Ignore" the client SSl certificate (so LB is not asking for client cert by default)?

     

  • In my particular scenario the clients didn't use browsers, they used a program similar to SOAP UI so there was no pop up asking the client to select a cert. Other than forcing SSL renegotiation, you could redirect the client to another VIP with say port 444 ( that has SSL mode set to Require in the profile.

     

  • "you could redirect the client to another VIP with say port 444 ( that has SSL mode set to Require in the profile" ---> yes, we decided to use "plan B", it means use completely different domain and VIP for this service and it makes everything easier and straightforward. So one VIP for anonymous traffic and second VIP for authenticated based on client cert and everything is allright.

     

    Thanks anyway ;)

     

  • I'm assuming plan B would work as well with the same domain and VIP but with different ports and different virtual servers?

     

    • Kevin_Stewart's avatar
      Kevin_Stewart
      Icon for Employee rankEmployee

      Yes. You can make a layer 6 (TLS) decision based on layer 3 (IP) or layer 4 (port) data, and without any of the complex iRules.