I'm trying to pull an attribute from a client certificate in a mutual authentication scenario and set it as a HTTP header in the request to backend. See fig 1 below.

  [user with correct certificate]
                 | 1. presents cert with normal v1 attributes
                 | has additional "extension" attributes
                 | incl. "Subject Alt Name" which contains
                 | "User Principal Name" ( UPN looks like an email addr) 
     [example.com:443 haproxy] --app1 / app2 CNAMEd to example.com 
                 | 2. read Subject Alternative Name
                 | 3. regex or parse out UPN
                 | 4. set REMOTE_USER header to be UPN
                 | 5. pass to backend(s)
       |                  |   
       |                  |   
       |                  |   
       |                  |   
       V                  V                 
 [app1svr:80]       [app2svr:80]    

Normally, it's easy, you would just pull the attribute you want using the built in functionality like so:

frontend https
 bind *:443 name https ssl crt ./server.pem ca-file ./ca.crt verify required

 http-request set-header X-SSL-Client-DN        %{+Q}[ssl_c_s_dn]
 http-request set-header X-SSL-Client-CN        %{+Q}[ssl_c_s_dn(cn)]
 http-request set-header X-SSL-Issuer           %{+Q}[ssl_c_i_dn]
 http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore]
 http-request set-header X-SSL-Client-NotAfter  %{+Q}[ssl_c_notafter]

 default_backend app1svr

backend app1svr
 server app1 app1svr.example.com:80

backend app2svr
 server app2 app2svr.example.com:80

List of attributes here: https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#7.3.4

Unfortunately, missing from the list of attributes are any of the COMMON extension attributes such as:

  • Subject alternative name
    • RFC822 Name
    • Other Name
      • Principal Name
  • CRL Distribution Points

I can't seem to figure out the right way to access these attributes. Looking at the code (below line 5815) https://github.com/haproxy/haproxy/blob/master/src/ssl_sock.c it doesn't seem to be just a documentation issue.

Any thoughts here? (possibly related issue): https://stackoverflow.com/questions/22966461/reading-an-othername-value-from-a-subjectaltname-certificate-extension

  • 1
    I don't see it, either. If you don't get a helpful answer here, I'd suggest taking this to the project mailing list as a question, followed by a feature request. It seems reasonable enough to me, but I'm not the one who has to write it, so that's easy enough to say. :) Jun 14, 2016 at 20:17
  • Not looking good for the mailing list, no messages archived for all of 2016 http://marc.info/?l=haproxy...will try it tomorrow if no one has any ideas. Community site has very light traffic http://discourse.haproxy.org/, may have to take it to github
    – MattPark
    Jun 15, 2016 at 3:32
  • 1
    The archive is third-party, and broken. The mailing list itself is very much alive. I've found a couple of bugs in 1.6 and 1.7 and they have been resolved promptly, on the list. It's used developer communications, patch review, bug tracking, help-I'm-stuck, and feature requests. Jun 15, 2016 at 3:59
  • OK submitted, bad timing, but it's out there. We'll see if the mailing list kicks it back since there are a couple links in it.
    – MattPark
    Jun 17, 2016 at 21:21
  • No one seems to care about smart card / PIV. Ended up just using Apache 2.4-20 -- Works fine, would rather have used ha-proxy.
    – MattPark
    Sep 30, 2016 at 1:21

1 Answer 1


As HAProxy version 1.5.14 (see http://www.haproxy.org/news.html) HAProxy send the whole certificate in the ssl_c_der attribute.

So, if you put the following lines in haproxy configuration file

http-request set-header X-SSL-ClientCert-Base64          %{+Q}[ssl_c_der,base64]

then you could read the whole client certificate by reading the X-SSL-ClientCert-Base64 header.

  • Yeah, that is fairly well documented. Not quite what I need because I can't edit how authorization is done on the remote server.
    – MattPark
    Sep 30, 2016 at 1:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.