Forum Discussion

Mathew_Loesch's avatar
Mathew_Loesch
Icon for Nimbostratus rankNimbostratus
Feb 01, 2017

Client certificate check. Redirect if none, continue if presented.

I need an iRule that checks for the existence of a Client SSL certificate. If no cert, redirect to request page. If present, continue to default pool. However, my example below always points me to the request page whether I present a certificate or not. I have my client SSL profile set to request for the client certificate.

 

when HTTP_REQUEST { if { [SSL::cert count] < 1 } { HTTP::redirect "" } else { pool } }

 

4 Replies

  • JG's avatar
    JG
    Icon for Cumulonimbus rankCumulonimbus

    In your client SSL profile, change your setting for "Frequency" in the "Client Authentication" to "Always" and see if that makes a difference.

     

  • the problem of your original, next attempt and most recent code is that the $clientCRT variable is not getting initialized, if the user doesn't provide a certificate.

    A fix for your problem would be to initialize the $clientCRT variable with value of 0 during CLIENT_ACCEPTED event and overwrite its value to 1 during CLIENTSSL_CLIENTCERT in the case that the client provides a certificate. In this case you will make sure that the HTTP_REQUEST event can savely query the current value of $clientCRT without raising a TCL exeption...

     

    when CLIENT_ACCEPTED {
        set clientCRT 0
    }
    when CLIENTSSL_CLIENTCERT {
        if { [SSL::cert 0] ne "" } then {
            set clientCRT 1
        }
    }
    when HTTP_REQUEST {
        if { $clientCRT } then {
            pool PoolName
        } else { 
            HTTP::redirect "URL" 
        }
    }
    

     

    Cheers, Kai

  • Hi Mathew,

    just completed the quick repro for the selective client certificate authentication. Below is the iRule I came up with...

     

    when CLIENTSSL_HANDSHAKE {
        if { [SSL::verify_result] == 0 } then {
             Authenticated user
            set clientCRT 1
        } else {
             Anonymous user
            set clientCRT 0
        }
    }
    when HTTP_REQUEST {
        if { $clientCRT } then {
             Authenticated user
            HTTP::respond 200 content "Result_Code = [X509::verify_cert_error_string [SSL::verify_result]] | The user \"[X509::subject [SSL::cert 0]]\"  is authenticated" "Content-Type" "text/html"
        } else {
             Anonymous user
            HTTP::respond 200 content "Result_Code = [X509::verify_cert_error_string [SSL::verify_result]] | Anonymous Request" "Content-Type" "text/html"
        }
    }
    

     

    Note: The Client SSL Profile was set to request the Client Certificate with appropiate "Trusted Certificate Authorities" "Advertised Certificate Authorities" chains in place.

    Note2: The included [HTTP::respond 200] commands are for testing purposes. You need to replace these with your original [pool] selection / [HTTP::redirect] code once you've verified the functionality.

    Cheers, Kai