HAProxy 1.6, Backend SNI not working in my implementation


#1

Hi,
So this is my first major solo HAProxy implementation, I was running HAProxy 1.5 on Red Hat 7 until one of our clients came forward with a requirement to use SNI on one of our backend resources.
I’ve deployed 1.6 and an SNI backend resource and can’t seem to get a successful TLS exchange working, I’ve been watching the exchange with tcpdump and my client hello requests don’t seem to include a server name indicator field.
The rest of the TLS exchange appears normal.

I’ve tested the same connection/certs with an openssl test and find them successful and can verify the SNI field being submitted

At this point I’m willing to try anything, I’ve spend about 48 hours working on this issue, and the large company I work for will be glaring at me pretty soon.
Any suggestions, pointers will be greatly appreciated.

Thanks,

Liam

This file managed by Puppet

global
chroot /var/lib/haproxy
daemon
group haproxy
log 127.0.0.1 local0
maxconn 4000
pidfile /var/run/haproxy.pid
stats socket /var/lib/haproxy/stats
user haproxy

defaults
log global
maxconn 3000
mode http
option httplog
option forwardfor
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s

frontend client_farm-frontend
bind 0.0.0.0:443 ssl crt /etc/ssl/certs/haproxy/server.crt
mode http
default_backend client_farm-backend
option tcplog

backend client_farm-backend
balance roundrobin
mode http
cookie JSESSIONID prefix nocache
server client_farm01 client.com:443 cookie client_farm01 check ssl sni str(client.com) verify none crt /etc/ssl/certs/haproxy/client.crt

Build Options:

[root@int-prd-prx01-wm haproxy]# haproxy -vv
HA-Proxy version 1.6.5 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 -Wdeclaration-after-statement -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 = 1024, maxpollevents = 200

Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.7
Compression algorithms supported : identity(“identity”), deflate(“deflate”), raw-deflate(“deflate”), gzip(“gzip”)
Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
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 without Lua support
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.


#2

The health check is the problem. The health check does not send the SNI header, while regular traffic would correctly handle it (disable health checking or revert to layer 4 health check would work around this problem).

Also see:


https://www.mail-archive.com/haproxy@formilux.org/msg22938.html


#3

Awesome, I did read that thread however it didn’t quite seem to click, my bad.
Tested with my browser hitting my HAProxy frontend and I can see server name indicator fields in my TLS client hello generated by HAProxy now which is awesome.
I’ll be following the release notes and that linked article for the HTTP health check, I might have to come up with a script workaround for a HTTP check that forwards SNI.

In the interim though will a layer 4 health check trigger a new DNS lookup? I imagine it would have to once I’ve configured a DNS resolver.

Thanks for your assistance.