Hi again Kevin,

On Tue, Jul 25, 2017 at 07:26:07AM +0200, Willy Tarreau wrote:
> > frontend www-https
> >     bind :::443 v4v6 ssl crt /etc/haproxy/certs/default.example.ca.pem crt
> > /etc/haproxy/certs/
> >     use_backend www-backend-https
> > 
> > backend www-backend-https
> >     server app default.example.ca:443 ssl verify required sni ssl_fc_sni
> > ca-file /etc/ssl/certs/ca-certificates.crt check check-ssl
> > 
> > If you visit https://should-be-broken.example.ca you will get the page for
> > default.example.ca, but the browser/visitor will show the
> > should-be-broken.example.ca cert from the haproxy and the page will appear
> > secure, despite the backend apache instance having no access to
> > should-be-broken's virtual host or certificate and serving a certificate for
> > default.example.ca to the haproxy.
> 
> Thanks, I'll retry it. I'm surprized because what you describe here is
> *exactly* what I did and it worked fine for me, I remember getting a 503
> when connecting with the wrong name. But obviously there must be a
> difference so I'll try to find it.

So I tried again to replicate it and cannot confirm your issues. Here's
what I've done :
  - I'm having haproxy serve as the origin because I don't have an apache
    instance running and don't know how to set it up so I'm not going to
    waste my time on it ;

  - this origin server responds on 3 different domain names and thus
    serves 3 different certificates (dom{1,2,3}.example.com).

  - a front gateway responds on a dummy cert, and connects to the server
    passing the front connection's SNI to the server.

  - the client connects to this front gateway with 4 different names, the
    3 supported ones and an unsupported one

What I'm seeing is that the first 3 domains work well and the 4th fails.

Here's the config :

  listen gateway
        mode http
        bind :4430 ssl crt rsa2048.pem
        server app 127.0.0.1:4431 ssl sni ssl_fc_sni verify required ca-file 
ca.pem check check-ssl

  frontend origin
        mode http
        bind :4431 ssl crt dom1.example.com.pem crt dom2.example.com.pem crt 
dom3.example.com.pem
        http-request redirect location /called-with-%[ssl_fc_sni]

Command to start this and output :
  $ ./haproxy -d -f sni-srv-bug.cfg

Test with dom1..dom3 :
  $ printf "GET / HTTP/1.0\r\n\r\n" | openssl s_client -connect 127.0.0.1:4430 
-quiet -servername dom1.example.com

Haproxy's output :
  00000004:origin.accept(0005)=0007 from [127.0.0.1:36664] ALPN=<none>
  00000004:origin.clicls[0007:ffffffff]
  00000004:origin.closed[0007:ffffffff]
  00000005:gateway.accept(0004)=0006 from [127.0.0.1:56942] ALPN=<none>
  00000005:gateway.clireq[0006:ffffffff]: GET / HTTP/1.0
  00000006:origin.accept(0005)=0008 from [127.0.0.1:36668] ALPN=<none>
  00000006:origin.clireq[0008:ffffffff]: GET / HTTP/1.0
  00000006:origin.clicls[0008:ffffffff]
  00000006:origin.closed[0008:ffffffff]
  00000005:gateway.srvrep[0006:0007]: HTTP/1.1 302 Found
  00000005:gateway.srvhdr[0006:0007]: Cache-Control: no-cache
  00000005:gateway.srvhdr[0006:0007]: Content-length: 0
  00000005:gateway.srvhdr[0006:0007]: Location: /called-with-dom1.example.com
  00000005:gateway.srvhdr[0006:0007]: Connection: close
  00000005:gateway.srvcls[0006:0007]
  00000005:gateway.clicls[0006:0007]
  00000005:gateway.closed[0006:0007]
  00000007:origin.accept(0005)=0007 from [127.0.0.1:36670] ALPN=<none>
  00000007:origin.clicls[0007:ffffffff]
  00000007:origin.closed[0007:ffffffff]

OpenSSL output :
  depth=0 C = FR, ST = Some-State, O = test, CN = localhost
  verify error:num=18:self signed certificate
  verify return:1
  depth=0 C = FR, ST = Some-State, O = test, CN = localhost
  verify return:1
  HTTP/1.1 302 Found
  Cache-Control: no-cache
  Content-length: 0
  Location: /called-with-dom1.example.com
  Connection: close
  
Test with dom4:
  $ printf "GET / HTTP/1.0\r\n\r\n" | openssl s_client -connect 127.0.0.1:4430 
-quiet -servername dom4.example.com

Haproxy's output :
  00000000:origin.accept(0005)=0007 from [127.0.0.1:36640] ALPN=<none>
  00000000:origin.clicls[0007:ffffffff]
  00000000:origin.closed[0007:ffffffff]
  00000001:gateway.accept(0004)=0006 from [127.0.0.1:56918] ALPN=<none>
  00000001:gateway.clireq[0006:ffffffff]: GET / HTTP/1.0
  fd[0007] OpenSSL error[0x14090086] ssl3_get_server_certificate: certificate 
verify failed
  fd[0008] OpenSSL error[0x14094438] ssl3_read_bytes: tlsv1 alert internal error
  00000002:origin.accept(0005)=0008 from [127.0.0.1:36646] ALPN=<none>
  00000002:origin.clicls[0008:ffffffff]
  00000002:origin.closed[0008:ffffffff]
  fd[0007] OpenSSL error[0x14090086] ssl3_get_server_certificate: certificate 
verify failed
  fd[0008] OpenSSL error[0x14094438] ssl3_read_bytes: tlsv1 alert internal error
  fd[0007] OpenSSL error[0x14090086] ssl3_get_server_certificate: certificate 
verify failed
  fd[0008] OpenSSL error[0x14094438] ssl3_read_bytes: tlsv1 alert internal error
  00000003:origin.accept(0005)=0008 from [127.0.0.1:36652] ALPN=<none>
  00000003:origin.clicls[0008:ffffffff]
  00000003:origin.closed[0008:ffffffff]
  fd[0007] OpenSSL error[0x14090086] ssl3_get_server_certificate: certificate 
verify failed
  fd[0008] OpenSSL error[0x14094438] ssl3_read_bytes: tlsv1 alert internal error
  00000001:gateway.clicls[0006:adfd]
  00000001:gateway.closed[0006:adfd]

OpenSSL output :
  depth=0 C = FR, ST = Some-State, O = test, CN = localhost
  verify error:num=18:self signed certificate
  verify return:1
  depth=0 C = FR, ST = Some-State, O = test, CN = localhost
  verify return:1
  HTTP/1.0 503 Service Unavailable
  Cache-Control: no-cache
  Connection: close
  Content-Type: text/html
  
  <html><body><h1>503 Service Unavailable</h1>
  No server is available to handle this request.
  </body></html>

So as you can see it works as expected here. I hardly know what else
can be checked. What exact version are you using ? Are you certain it
contains the patch I mentionned ?

Regards,
Willy

Reply via email to