Haproxy with Nginx can't use client certificate authentication

Hi, all

I have one IP Adress and one port 443
At the end I have four web applications
I use two domain name (www.domainsample1.com, www.domainsample2.com) and two context root (context_root_1, context_root_2) to backend mapping
I have path: request https -> nginx -> haproxy -> http application
It works until I try to use client certificate authentication
When I add client certificate authentication I get error “1: SSL handshake failure” and client browser do not even try to ask questions about the use of the certificate.
When I test it without nginx (https -> haproxy -> http application ) I can authenticate with a client certificate but I get a 400 error when displaying the application page.
Any help or suggestions are appreciated.
Thanks! :slight_smile:

config haproxy:

global
# log 127.0.0.1 local1 notice
log localhost:514 local0
stats timeout 30s
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
stats socket /var/run/haproxy.sock mode 666 level admin
stats timeout 2m
stats bind-process 1
nbproc 2
cpu-map 1 0
cpu-map 2 1

defaults
log global
option dontlognull
option httplog
balance leastconn
timeout client 60000
timeout server 60000
timeout connect 5000
retries 3
option redispatch

frontend demo
mode http
acl context_root_1 path_beg /context_root_1
acl context_root_2 path_beg /context_root_2
acl domainsample1 hdr(Host) www.domainsample1.com
acl domainsample2 hdr(Host) wwww.domainsample2.com
bind 172.16.10.1:443 ssl crt /etc/pki/tls/certs/domainsample1.pem crt /etc/pki/tls/certs/domainsample2.pem ca-file /etc/pki/tls/certs/CA.cer verify required
http-request set-header X-SSL %[ssl_fc]
http-request set-header X-SSL-Client-Cert %[ssl_fc_has_crt]
http-request set-header X-SSL-Client-Verify %[ssl_c_verify]
http-request set-header X-SSL-Client-SHA1 %{+Q}[ssl_c_sha1]
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-Not-Before %{+Q}[ssl_c_notbefore]
http-request set-header X-SSL-Client-Not-After %{+Q}[ssl_c_notafter]
use_backend bk_context_root_1_demo_domainsample1 if domainsample1 context_root_1
use_backend bk_context_root_1_demo_domainsample2 if domainsample2 context_root_1
use_backend bk_context_root_2_demo_domainsample1 if domainsample1 context_root_2
use_backend bk_context_root_2_demo_domainsample2 if domainsample2 context_root_2

backend bk_context_root_1_demo_domainsample1
mode http
server server1 172.16.10.2:5071 check
reqirep ^([^\ :])\ /context_root_1/(.) \1\ /\2

backend bk_context_root_1_demo_domainsample2
mode http
server server2 172.16.10.3:5071 check
reqirep ^([^\ :])\ /context_root_1/(.) \1\ /\2

backend bk_context_root_2_demo_domainsample1
mode http
server server1 172.16.10.2:5070 check
reqirep ^([^\ :])\ /context_root_2/(.) \1\ /\2

backend bk_context_root_2_demo_domainsample2
mode http
server server2 172.16.10.3:5070 check
reqirep ^([^\ :])\ /context_root_2/(.) \1\ /\2

haproxy -vv

HA-Proxy version 1.5.18 2016/05/10
Copyright 2000-2016 Willy Tarreau willy@haproxy.org

Build options :
TARGET = linux2628
CPU = generic
CC = gcc
CFLAGS = -O2 -g -fno-strict-aliasing -DTCP_USER_TIMEOUT=18
OPTIONS = USE_LINUX_TPROXY=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_PCRE=1

Default settings :
maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200

Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.7
Compression algorithms supported : identity, deflate, gzip
Built with OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.32 2012-11-30
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND

Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.

On nginx I getting error:
2019/03/14 17:39:39 [error] 1090#0: *6254 SSL_do_handshake() failed (SSL: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3
alert handshake failure:SSL alert number 40) while SSL handshaking to upstream,

So what are you trying to solve? The 400 error without nginx or the SSL issue with nginx? How is nginx configured exactly and where those SSL termination/authentication occur exactly?