6

Excuse me if I posted this here wrongly, I know the question is partly about haproxy itself.

I am setting up haproxy as an SSL terminator/load balancer in front of an API that we need to expose over the internet to a customer.

The plan was to use mutual (2-way) SSL/HTTPS to verify that both parties are who they are since there is no further authentication on the API itself. On top of this we will also utilize an IP whitelist.

Now the customer has given us a certificate that both parties use for both server and client certificates, this certificate is signed by a 'common' CA (DigiCert). While I understand this is good from a client perspective, as the certificate is also compared to the hostname of the server it's accessing, however the other way around doesn't seem to be that safe (at least not with haproxy)

The way I understand it currently, I have to tell HAProxy to trust certificates signed by Digicert by using the 'ca-file' directive, however, there is no way to tell it that on top of that it also needs to be a specific client certificate, because I don't want to trust all client certificates signed by DigiCert.

Is there a way to do this with HAProxy? If not, I guess the only way forward would be to make self-signed client certificates for both sides and exchange them (or rather, certificate signing requests, and have the other party sign them).

Or is my understanding of the whole client certificate concept just wrong?

Sartsj
  • 101
  • 1
  • 5

3 Answers3

4

Building on StackzOfZtuff's answer, I figured out its actually possible to have haproxy do this itself by using an acl.

With the following 2 lines I can just check the CN in the client cert. And deny requests that don't have a matching CN.

acl validcert ssl_c_s_dn(cn) -m str VALID\ CERT\ CN
http-request deny if !validcert
Sartsj
  • 101
  • 1
  • 5
2

You can read out the certificate's "Common Name" field and then pass it to the back end like so:

http-request set-header X-SSL-Client-CN %{+Q}[ssl_c_s_dn(cn)]

And if you then combine this with the a CA of your own issuing the certificates, then you can put a username in that field. And then read it out with HAProxy.

Described here: http://blog.haproxy.com/2013/06/13/ssl-client-certificate-information-in-http-headers-and-logs/

StackzOfZtuff
  • 17,783
  • 1
  • 50
  • 86
0

I'm not familiar with HAProxy, but I don't think it could be configured to do your authentication logic, meaning accepting just some of certificates with same CA, during certification verification process.

Is there a way to do this with HAProxy? If not, I guess the only way forward would be to make self-signed client certificates for both sides and exchange them (or rather, certificate signing requests, and have the other party sign them).

You can build you CA on top of openssl with not much work. You probably need to authorize clients too, so you can provide some information in clients' certificate subject and check them in application layer.

reith
  • 203
  • 2
  • 7