Forum Discussion

KimiLi_147173's avatar
KimiLi_147173
Icon for Nimbostratus rankNimbostratus
Apr 04, 2019

Require client authentication once based on specific FQDN

Hi all,

 

I got a vs on LTM with SSL offload, which accepts client requests with multiple FQDN in http header.

 

Is that possible I'd have an irule which requires client SSL certificate authentication when specific FQDN in client request? Require frequency shall be one time that high loads of F5 need to be avoided.

 

Any suggestion will be helpful, thanks.

 

4 Replies

  • Do you want to trigger SSL certificate authentication for the given hostname or do you want to make use of APM authentication?

     

    Cheers, Kai

     

  • Hi Kai,

     

    Just Client SSL certificate authentication rather than APM authentication, thanks.

     

  • Hi,

    First of configure you ssl client with the following parameters:

    • authenticate always
    • authenticate depth 9
    • cert mode request
    • renegotiate

    don't forget to set "Trusted Certificate Authorities" and "Advertised Certificate Authorities" with right CA...

    Simple Irule for begin:

    when CLIENTSSL_CLIENTCERT {
    
    set auth 0
     Check if client provided a cert
    if {[SSL::cert 0] eq ""}{
         Reset the connection
        set auth 0
    } else {
        Example Subject DN:  /C=AU/ST=NSW/L=Syd/O=Your Organisation/OU=Your OU/CN=John Smith
        set subject_dn [X509::subject [SSL::cert 0]]
        log "Client Certificate Received: $subject_dn"
        set cert [b64encode [SSL::cert 0]]
        set auth 1
       }
    }
    
    
    
    when HTTP_REQUEST {
    
    switch -glob [string tolower [HTTP::host]] {
        "app.mydomain.com" {
            if {$auth == 0} {
                HTTP::respond 403 content "Forbidden" "Content-Type" "text/html" "Connection" "Close"
            }
        }
        "app.mydomain.com" {
            if {$auth == 0} {
                HTTP::respond 403 content "Forbidden" "Content-Type" "text/html" "Connection" "Close"
            }
        }
        default {
             don nothing
        }
    }
    }
    

    You have also this interesting post:

    https://devcentral.f5.com/articles/selective-client-cert-authentication

    You just have to change URI by Hostname...

    regards,

  • Hi KimiLi,

    you may take a look to the iRule below. The iRule utilizes a minimalistic but very effective TCP session state to determine, if a given TCP session needs to become SSL authenticated before granting access to specific HOST or URI value.

    If a HTTP request to a protected ressource is received by the

    HTTP_REQUEST
    event, the iRule will put the ongoing HTTP request on hold, change the Client SSL settings (aka. Client Authentication = Require) of the underlying TCP session and triggers a on-the-fly SSL renegotiation with the changed Client SSL settings. Once the SSL renegotiation is complete, it will relase the ongoing HTTP request from hold and mark the underlying TCP as Client Certificate authenticated.

    when CLIENT_ACCEPTED {
         Initialize TCP session state as unauthenticated.
        set tcp_session_state 0
    }
    when CLIENTSSL_HANDSHAKE {
         Check if TCP session is marked for HTTP request on hold.
        if { $tcp_session_state == 1 } then {
             Releasing the ongoing HTTP request
            HTTP::release
             Set TCP session state to authenticated.
            set tcp_session_state 2 
        }
    }
    when HTTP_REQUEST {
         Parse the HOST header value...
        switch -exact -- [string tolower [HTTP::host]] {
            "secure.domain.de" {
                 Check if the TCP session is marked as unauthenticated.
                if { $tcp_session_state == 0 } then {
                     Temporary hold the ongoing HTTP request.
                    HTTP::collect
                     Set TCP session state to HTTP request on hold.
                    set tcp_session_state 1 
                     Changing parameters of the underlying TCP connection to SSL client cert = require.
                    SSL::cert mode require
                     Forcing renegotiating of the underlying SSL session (/w changed parameters for this TCP connection).
                    SSL::renegotiate
                }
                 Select the backend pool
                pool my_secure_pool
            }
            "non-secure.domain.de" {
                 Select the backend pool
                pool my_non_secure_pool
            }
            default {
                 Select the backend pool
                pool my_default_pool
            }
        }
    }
    

    The Client SSL Profile of your Virtual Server, needs to be setup for Client Authentication with the parameter which are best suited for you:

    Client Certificate = Ignore (Ignore is important. The iRule will flip this setting as needed to selectively require Client Certificate authentication)
    Frequency = Once | Always as you like
    Retain Certificate = Enabled | Disabled as you like
    Chain Depth = A deep of your choice
    Trusted CA = A bundle of trusted CAs
    Advertised CA = Most likely the same bundle as above
    CRL = Select one as you like
    

    With those settings, the SSL Profile is fully prepared to ask for a SSL Client Certificate Authentication. But it wont ask for a Client certificate until the iRule instructs the individual TCP session to flip the "Client Certificate" setting to "Require".

    Cheers, Kai