Forum Discussion

MiguelArias_108's avatar
MiguelArias_108
Icon for Nimbostratus rankNimbostratus
Oct 30, 2018

Client Authentication by uri and Client Certificate

Hi, i'm trying deploy iRule similar this Apache's configuration

 Authentication optional
SSLVerifyClient optional
SSLVerifyDepth  5
SSLOptions +StdEnvVars
SSLRequireSSL

 Authentication for URIs
RewriteCond %{REQUEST_URI} ^/Pruebas/cliente1
RewriteCond %{SSL:SSL_CLIENT_S_DN} !^CN=cliente1$
RewriteRule .* - [F]

RewriteCond %{REQUEST_URI} ^/Pruebas/cliente2
RewriteCond %{SSL:SSL_CLIENT_S_DN} !^CN=cliente2$
RewriteRule .* - [F]

Is it posible to do similar configuration in a iRule?

Thanks

  • Okay, so I'll start by trying to decipher the Apache configuration:

    This says that a client certificate is optional:

    SSLVerifyClient optional
    SSLVerifyDepth  5
    SSLOptions +StdEnvVars
    

    This says, if the URI is "/Pruebas/cliente1" and the certificate subject DN is not "CN=cliente1", return a 403 Forbidden.

    RewriteCond %{REQUEST_URI} ^/Pruebas/cliente1
    RewriteCond %{SSL:SSL_CLIENT_S_DN} !^CN=cliente1$
    RewriteRule .* - [F]
    

    This says, if the URI is "/Pruebas/cliente2" and the certificate subject DN is not "CN=cliente2", return a 403 Forbidden.

    RewriteCond %{REQUEST_URI} ^/Pruebas/cliente2
    RewriteCond %{SSL:SSL_CLIENT_S_DN} !^CN=cliente2$
    RewriteRule .* - [F]
    

    So then, if you wanted to represent this in iRules:

    1. Configure the client SSL profile to request (vs. require) the client certificate. This is the same as the "SSLVerifyClient optional" command.
    2. Use an iRule similar to this:

      when HTTP_REQUEST {
           set a flag
          set result 0
          if { [string tolower [HTTP::uri]] starts_with "/pruebas/cliente1" } {
               if there's a client cert (client SSL says it's optional)
              if { [SSL::cert count] > 0 } {
                   find the CN= string in the subject
                  set certcn [findstr [X509::subject [SSL::cert 0]] "CN=" 0]
                  if { $cert ne "CN=cliente1" } {
                       if the CN= doesn't match
                      set result 1
                  }
              } else {
                   no client cert exists
                  set result 1
              }
          }
          if { [string tolower [HTTP::uri]] starts_with "/pruebas/cliente2" } {
              if { [SSL::cert count] > 0 } {
                  set certcn [findstr [X509::subject [SSL::cert 0]] "CN=" 0]
                  if { $cert ne "CN=cliente2" } {
                      set result 1
                  }
              } else {
                  set result 1
              }
          }
          if { ${result} } {
               if URI/CN don't match, send a 403
              HTTP::respond 403 content "Forbidden" "Content-Type" "text/html" "Connection" "Close"
          }
      }