Search code examples
haproxyx509client-certificatesmutual-authentication

HAProxy: unable to forward client-certificate in a header without validation


I have a mutual-TLS setup with HAProxy terminating incoming SSL connections. I need to perform client certificates validation on the backend, not on haproxy side since we have a dynamic truststore and I cannot just set a single ca-file and delegate all the validation logic to haproxy. Regular setup works fine (where haproxy validates a client cert against CA cert):

bind *:443 ssl crt /etc/certs/haproxy.pem verify required ca-file /etc/certs/ca.crt
http-request redirect scheme https unless { ssl_fc }
http-request set-header X-SSL-ClientCert          %{+Q}[ssl_c_der,base64]

Backend receives X-SSL-ClientCert correctly, but this is not enough. If verify required ca-file /etc/certs/ca.crt is removed to skip validation on haproxy, X-SSL-ClientCert is empty when read on the backend, that is, HAProxy does not set the header with the client certificate anymore. Any ideas on how to fix this?


Solution

  • Okay, after some tinkering I stumbled upon the following:

    HAProxy documentation https://cbonte.github.io/haproxy-dconv/2.3/configuration.html#5.2-verify states two options for verify: [none|required], but it seems there is an undocumented option, namely, optional which seems to do the trick:

    bind *:443 ssl crt /etc/certs/haproxy.pem verify optional ca-file /etc/certs/ca.crt
    http-request set-header X-SSL-Client-Cert          %{+Q}[ssl_c_der,base64]
    http-request set-header X-SSL-Client-CN            %{+Q}[ssl_c_s_dn(cn)]
    http-request set-header X-SSL-Client-Verify        %[ssl_c_verify]