Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

SNI and Client certificate authentication

Hi

LTM 11.4.0 VE

I want a VS that listens to 443 and terminates TLS 1.0+ https traffic. It should have two Client SSL profiles (with different certificates and hostnames in the certificates for SNI to work of course), one default and the other should use SNI. They should afterwards be proxied to different pools.

So far so good.

The problem is that I want to have Client Certificate Authentication as well. Unfortunetaly the Client SSL profiles above should not accept certificates issued from the same CA-chain. (The client certificates do share the same rootCA though).

The only way I can get F5 to swallow my two Client SSL profiles at the same time in my VS is to put a CA bundle containing both my CA-chains in "Trusted Certificate Authorities" on both Client SSL profiles. Unless I do this I get: 0107157c:3: Selected client SSL profiles do not match security policies for Virtual Server /Common/vs_https_external. Putting the bundle in Trusted Certificate Authorities gives the unwanted effect that clients from one CA-chain can is authenticated sucessfully agains the other Client SSL profile and the opposite. As a side note, both type of client certificates will be checked against a common OCSP server.

This all comes from a shortage of IP adresses.

Do any of you F5 professors have any idea? Do I have to code/copy-paste a custom iRule to solve this?

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

This one is definitely unusual. For all intents and purposes, if the SNI-based profile selection is based on the CLIENTHELLO message, I would think the parts of the individual profiles shouldn't matter and certainly shouldn't have to match. I would also comment that trying to do anything in an iRule under the CLIENTSSL_ commands is too late in the process. For that reason I put together a potential workaround that relies on capturing the CLIENTHELLO server_name data in the (still unencrypted) TCP payload. Here's what it looks like:

when CLIENT_ACCEPTED {
    TCP::collect
}
when CLIENT_DATA {
    if { [info exists selected_profile] } { 
        ## use specified client SSL profile if set
        catch { eval "SSL::profile $selected_profile" } 
    } else {
        ## look for CLIENTHELLO message in the TLS handshake (SSL bypassed)
        binary scan [TCP::payload] cSSc tls_xacttype tls_version tls_recordlen tls_handshake_type
        switch -- $tls_version {
            "769" -
            "770" -
            "771" { 
                if { $tls_handshake_type equals 1 } {
                    ## CLIENTHELLO message
                    binary scan [TCP::payload] H* hexdump
                    if { [class match $hexdump contains my_ssl_profile_dg] } {
                        ## use client SSL profile from data group
                        set selected_profile [class match -value $hexdump contains my_ssl_profile_dg]
                        catch { eval "SSL::profile $selected_profile" }
                    }
                } 
            }
        }
    }
    TCP::release
    TCP::collect
}

Essentially what's happening is that I'm capturing the TCP payload and looking for a CLIENTHELLO message inside a TLS (1.0, 1.1, or 1.2) handshake. I toyed with a few different approaches, but for the sake of simplicity I hex-encoded the server names and added them to a data group with the corresponding client SSL profile name. Example:

6d79736572766572312e646f6d61696e2e636f6d := myserver1.domain.com_clientssl
6d79736572766572322e646f6d61696e2e636f6d := myserver2.domain.com_clientssl

You can get these values with the following code:

when RULE_INIT {
    binary scan "myserver1.mydomain.com" H* tmp
    log local0. $tmp
}

Another option would have been to loop through the literal server name strings in the data group and hex encode them on the fly. Ultimately, instead of trying to binary parse the CLIENTHELLO payload to find the exact server_name value, I'm simply looking for this particular hex string in the hex-encoded payload. Once I find and match the payload value to a data group entry, I extract and use the defined client SSL profile. The SSL::profile command isn't technically supported in the CLIENT_DATA event, so I wrapped in an eval command, and again in a catch command. I also set the profile name to a local variable so that subsequent requests in the same TCP session will use the same profile. You need at least one client SSL profile applied to the VIP, and all non-TLS-capable clients should simply fall through to this default profile.

The one thing it doesn't seem to support is flipping back and forth between the SSL VIPs in a single browser session. I don't imagine that'll happen often and I haven't figured out how to fix that yet. This workaround does seem to work well though. It also supports client SSL profiles with different client cert auth settings.

1
Comments on this Answer
Comment made 11-Oct-2013 by Kevin Stewart
It'd probably also be worth opening a support case.
0
Comment made 18-Nov-2016 by Yolanda 2

I have a similar issue as explained here. because I am new to irules, I am unsure if the above iRule will fix my issue. Please help!

Here is my scenario

  1. Large number of Websites using same VIP. These URLs all use the same domain *.example.com
  2. Each of these sites requires client authentication. All sites use a different certificate chain, these certs should all be managed individually

I created a single VS to handle for all these websites. I created a default SNI profile as recommended by F5, I applied the fallback profile to the virtual server, then proceeded to create a single Client SSL profile per URL.

When I attached the client SSL profile to the VS, it errors with the following:

0107157c:3: Selected client SSL profiles do not match security policies for Virtual Server /Common/

So I guess I need an irule that can match each SSL client profile with its hostname (URL), in order for the client authentication to be successful, each client SSL profile would be configured with the certificate chain to be used during CA.

Will the above irule work for me?

Thanks in advance for any assistance you can provide!

0
Comment made 20-Nov-2016 by boneyard 5637

Yolanda, please try Kevin's first suggestion first, open a support ticket. i also see no reason why this shouldn't work. that might safe you extra unneeded config.

do please report back with their (support) answer.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

A bit more investigation. Without any authentication profile enabled and just a default SNI ssl client profile and another ssl client profile that uses SNI and a simple irule:

when CLIENTSSL_HANDSHAKE { log local0.debug "My selected sslprofile [PROFILE::clientssl name]" }

I always get the sslprofile name of the profile that is on top in the list in my VS->SSL Profile (Client) even though I send in SNI in my handskake and I get the correct server certificate back.

I would have expected to get the profile name in the log that is corresponding to my SNI clientssl profile...

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

I've no doubt where the iRule is concerned it's simply a matter (as used to be the case with HTTP::uri and others) that what's logged doesn't actually reflect changes that have occurred during LTM (and iRule) processing. Perhaps change the event to a serverside one (but specify clientside operation) to get the real picture. Of course, logically, this may just be how things work for now.

Regarding the ClientSSL issue, I assume you've specified different CA's in each profile?

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Thanks for the excellent reply Kevin!

In my case I ended up with two SSL profiles and one OCSP authentication profile and an iRule that send traffic to the correct pool for the type of client as determined by the iRule looking at the certificate in CLIENTSSL_CLIENTCERT.

It seems to work reasonably well. I think we can live with not being able to set different cipher suites on the two SSL profiles.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hi all,

it seems I'm running into the same issue, but I'm not sure if I really understand the above answers correctly.

We also have a VS with currently seven different clientSSL-profiles (and might be more in the future). One of it should be configured with Client Authentication, but if I try to enable it I get the following error message.

0107157c:3: Selected client SSL profiles do not match security policies for Virtual Server /Common/<vs_name>.

The default SSL profile contains a self-signed wildcard certificate and all other six profiles just have its cert-key-chain configured and the appropriate "Server Name". The chain is equal for all six "real" certificates and I also tried to include it for the default wildcard profile, but the error message is still the same.

Right now I don't see the reason for this error message and therefor don't know where to search for. And I also don't really understand if the answer from Kevin is the solution/workaround for my setup as well.

We have another VS with just one clientSSL-profile active and there Client Authentication can be enable without any issues.

By the way we are using 11.5.3

Thank you for your help or further ideas!

Ciao Stefan :)

0