Hi again,

This is definitively not possible with HAProxy, unless I missed something!
Better use 2 different domain names pointing to 2 IPs hosted by 2
frontends, one asking for a client cert, the other one not.

Baptiste

On Wed, Jan 8, 2014 at 9:04 PM, Remy van Elst <[email protected]> wrote:
> Lukas Tribus schreef op 08/01/14 19:37:
>
>> Hi,
>>
>>> Thank you. I've read the blog post. However, with the verify optional
>>> bind line, if the client has a certificate in their browser, they will
>>> get asked every time they visit the website. I only want them to be
>>> asked for a certificate on a specific path. Possibly something like:
>>>
>>> if { path_beg /admin }ca-file ./ca.crt verify required
>>
>> (the proposal from Baptiste is basically the same as mine, we just
>> overlapped in time)
>>
>> I'm afraid this is not possible at all (not even with Apache). Its for
>> the same reason you cannot use the "Host:" header to select the correct
>> server certificate (and need SNI instead):
>> You are relying on a information available only after the SSL/TLS
>> handshake
>> to influence the actual handshake. This information about the URI is not
>> known when you are doing the SSL/TLS handshake.
>>
>> This is how it looks like when I connect to a server which ask me (the
>> client) for a certificate:
>>   openssl s_client -state -quiet -connect 10.0.0.55:443
>> SSL_connect:before/connect initialization
>> SSL_connect:unknown state
>> SSL_connect:SSLv3 read server hello A
>> depth=0 C = IT, ST = bogus ST, L = Sin City, O = sin-org, CN =
>> ubuntuvm.sin-org
>> verify error:num=18:self signed certificate
>> verify return:1
>> depth=0 C = IT, ST = bogus ST, L = Sin City, O = sin-org, CN =
>> ubuntuvm.sin-org
>> verify return:1
>> SSL_connect:SSLv3 read server certificate A
>> SSL_connect:SSLv3 read server key exchange A
>> SSL_connect:SSLv3 read server certificate request A    <-- [1]
>> SSL_connect:SSLv3 read server done A
>> SSL_connect:SSLv3 write client certificate A
>> SSL_connect:SSLv3 write client key exchange A
>> SSL_connect:SSLv3 write change cipher spec A
>> SSL_connect:SSLv3 write finished A
>> SSL_connect:SSLv3 flush data
>> SSL_connect:SSLv3 read server session ticket A
>> SSL_connect:SSLv3 read finished A
>> GET / HTTP/1.0    <-- [2]
>>
>> HTTP/1.1 200 OK
>> Date: Wed, 08 Jan 2014 18:13:35 GMT
>> [...]
>>
>>
>> As you can see, the certificate request [1] happens before the HTTP
>> request
>> [2], so what you are saying is not possible.
>>
>> In case Apache really does the certificate request after the server done
>> message, then I believe its a violation of the SSL/TLS specs [3].
>>
>>
>> Can you run
>>   openssl s_client -state -quiet -connect <hostname>:443
>>
>> against your working apache server and paste:
>> GET /admin/ HTTP/1.0
>>
>> (with 2 newlines/enters after HTTP/1.0)
>>
>> so we can see the behavior of your working apache setup?
>>
>>
>>
>> Regards,
>>
>> Lukas
>>
>>
>> [3] http://tools.ietf.org/html/rfc5746
>
>
>
> Thank you all for the great and clear explanations. I'll explain the
> situation a bit more.
> The web app currently runs on 2 Apache servers set up by a former admin.
> I've had to bolt on cluster functionality, now using Pacemaker and Corosync
> HA. However, they're migrating all the apps from off a Big IP F5
> loadbalancer (which does not do SSL offloading) to a haproxy setup (SSL
> offloading on haproxy, again, with pacemaker/corosync clustering).
>
> In the testing phase (now), some clients have issues with the app (because
> they have a certificate in their browser). On Apache/F5 they are not asked
> for a certificate in using the app, only admins are.
>
> The current haproxy setup does ask for a certificate to "regular users",
> whereas the previous setup did not. Therefore, my understanding was that it
> was a valid setup, however now it appears to be a "violation of the SSL/TLS
> specs".
>
> Here is the requested data, both for a non-admin url and for the admin url.
>
>
> The client side certificate requesting URL:
>
>     $ openssl s_client -state -quiet -connect xx.xx.xx.xx:443
>
>     SSL_connect:before/connect initialization
>     SSL_connect:SSLv2/v3 write client hello A
>     SSL_connect:SSLv3 read server hello A
>     depth=4 /C=NL/O=xxx/CN=xxx
>     verify error:num=19:self signed certificate in certificate chain
>     verify return:0
>
>     SSL_connect:SSLv3 read server certificate A
>     SSL_connect:SSLv3 read server key exchange A
>     SSL_connect:SSLv3 read server done A
>     SSL_connect:SSLv3 write client key exchange A
>     SSL_connect:SSLv3 write change cipher spec A
>     SSL_connect:SSLv3 write finished A
>     SSL_connect:SSLv3 flush data
>     SSL_connect:SSLv3 read finished A
>     GET /admin/ HTTP/1.0
>
>     SSL_connect:SSL renegotiate ciphers
>     SSL_connect:SSLv3 write client hello A
>     SSL_connect:SSLv3 read server hello A
>     depth=4 /C=NL/O=xxx/CN=xxx
>     verify error:num=19:self signed certificate in certificate chain
>     verify return:0
>
>     SSL_connect:SSLv3 read server certificate A
>     SSL_connect:SSLv3 read server key exchange A
>     SSL_connect:SSLv3 read server certificate request A
>     SSL_connect:SSLv3 read server done A
>     SSL_connect:SSLv3 write client certificate A
>     SSL_connect:SSLv3 write client key exchange A
>     SSL_connect:SSLv3 write change cipher spec A
>     SSL_connect:SSLv3 write finished A
>     SSL_connect:SSLv3 flush data
>     SSL3 alert read:fatal:handshake failure
>     SSL_connect:failed in SSLv3 read finished A
>     38843:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake
> failure:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s3_pkt.c:1106:SSL
> alert number 40
>     38843:error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake
> failure:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s3_pkt.c:1010:
>
> The non client side certificate response:
>
>     $ openssl s_client -state -quiet -connect xx.xx.xx.xx:443
>
>     SSL_connect:before/connect initialization
>     SSL_connect:SSLv2/v3 write client hello A
>     SSL_connect:SSLv3 read server hello A
>     depth=4 /C=NL/O=xxx/CN=xxx
>     verify error:num=19:self signed certificate in certificate chain
>     verify return:0
>
>     SSL_connect:SSLv3 read server certificate A
>     SSL_connect:SSLv3 read server key exchange A
>     SSL_connect:SSLv3 read server done A
>     SSL_connect:SSLv3 write client key exchange A
>     SSL_connect:SSLv3 write change cipher spec A
>     SSL_connect:SSLv3 write finished A
>     SSL_connect:SSLv3 flush data
>     SSL_connect:SSLv3 read finished A
>     GET / HTTP/1.0
>
>     HTTP/1.1 200 OK
>     Date: Wed, 08 Jan 2014 19:53:33 GMT
>     Server: Apache
>     X-Frame-Options: SAMEORIGIN
>     X-XSS-Protection: 1; mode=block
>     X-Content-Type-Options: nosniff
>     X-UA-Compatible: chrome=1
>     Cache-Control: no-cache
>     X-Request-Id: 0978a920-5722-4acd-9a19-8bca6b49f8c3
>     X-Runtime: 0.009102
>     Set-Cookie: request_method=GET; path=/
>     Status: 200
>     Content-Length: 95
>     Connection: close
>     Content-Type: text/html; charset=utf-8
>     Strict-Transport-Security: max-age=31536000; includeSubDomains
>
>     SSL3 alert read:warning:close notify
>     SSL3 alert write:warning:close notify
>
>
> If it is not possible to do this with haproxy (because it is invalid
> according to the spec) then I'll probably suggest they move the admin
> interface out of the user-facing part of the app.
>

Reply via email to