HAProxy for converting HTTP to HTTPS request with server requiring SNI

Of course. You cannot access “localhost” and expect certificate verification to succeed when really there is names mismatch. Both haproxy and your backend behave exactly as you want.

I am confused. I am not trying to achieve mutual authentication .

The client/localhost is using only non ssl port (80) and the backend config to enable it as https (tls1.2 with sni) to connect to server

Additionally I have set the ssl server verify global parameter as none, to not verify the server certificates.

Wrong, your client side is not non-ssl, it is SSL encrypted on port 443. You setup haproxy on port 80 to redirect to SSL immediately. You are also using https in your curl request. And what the error message is saying is that you your request hostname localhost does not match the certificate, which is *.sdppcf.com

So your browser, curl, haproxy and your backend are doing exactly what you configured them to do.

Oh ok.

Does that mean that, I need to provide client cert (including private key) in the front end which binding at the port :

front end
bind *:443 --ssl crt /etc/ssl/client.pem

Does that certificate need to have server details(test.sdppcf.com) in the alternate name(SAN)?

No, this has nothing to do at all with client certificates.

What you need in your curl command and in your browser, is to point to https://test.sdppcf.com instead of localhost. Configure DNS appropriately.

The URL https://test.sdppcf.com is the server URL, which is configured in the backend.

To test the HAProxy, shouldn’t I be using the domain name which is binded at the frontend?

I have updated the config file as below :
frontend localhost443
mode tcp
bind *:443 ssl crt /etc/haproxy/certs/client.pem
tcp-request inspect-delay 5s
default_backend tebackend

backend outbound
mode tcp
server server1 test.sdppcf.com:443 ssl verify required ca-file /etc/haproxy/certs/ca_chain.pem crt /etc/haproxy/certs/client.pem sni str(test.sdppcf.com) verifyhost test.sdppcf.com

You have a certificate installed on haproxy, which is in /etc/haproxy/certs/client.pem. That certificate is valid for test.sdppcf.com. So, for the browser or haproxy do validate this certificate succesfully, you need to point to test.sdppcf.com. If you write the IP address or localhost in the browser, it will not work, since test.sdppcf.com is not the same string as localhost.

Finally, I have changed the configuration so that , we are passing http request in the front end and enabled ssl in the backend.

frontend localhost80
bind *:80
option tcplog
mode tcp
tcp-request inspect-delay 5s
default_backend sslredirect

backend sslredirect
mode tcp
server server1 test.sdppcf.com:443 ssl verify none sni str(test.sdppcf.com) verifyhost test.sdppcf.com ca-file /etc/haproxy/certs/ca.crt

This configuration is working fine and I get the output.

However, when I modify the “ssl verify” to required in order to verifiy the server certificate, it simply returns “empty response”.

Then the CA file you passed to haproxy does not validate the certificate returned by the server.

Yes.

After I add the force-tlsv12 and updated the ca with the intermediate chain, it started working.

server server1 test.sdp.com:443 ssl verify required force-tlsv12 sni str(test.sdp.com) ca-file /etc/ssl/certs/ca.pem crt /etc/haproxy/certs/client.pem

Thanks a ton for your inputs :slight_smile:

1 Like