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.

Attachment: smime.p7s
Description: S/MIME-cryptografische ondertekening

Reply via email to