HAProxy version: 3.4.4 (also reproduced earlier on 3.2.23 before upgrading)
OS: Ubuntu 24.04/26.04, installed via vbernat’s PPA
Setup: TCP-mode frontend doing SNI-based passthrough routing to a mail server (SmarterMail), with an HTTP-mode local-termination fallback for everything else.
Relevant config:
frontend fe_tcp_443
mode tcp
option tcplog
bind *:443
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 } { req.ssl_sni -m found }
acl sni_mail req.ssl_sni -i mail.example.com autodiscover.example.com webmail.example.com
[... ~20 more domain lines ...]
use_backend be_mail_passthrough if sni_mail
default_backend be_local_terminate
backend be_mail_passthrough
mode tcp
server sm1 <mail-server-ip>:443
backend be_local_terminate
mode tcp
server local_ssl 127.0.0.1:8443
Symptom: Clients (mail apps on mobile) very occasionally get a TLS identity warning when connecting to one of the SNI-routed mail domains — the certificate presented is for a different, unrelated domain served via be_local_terminate’s cert store (i.e. traffic appears to fall through to default_backend instead of matching sni_mail). Rare and intermittent; users report it correlates with their phone waking from idle/sleep and the mail app reconnecting.
What we’ve tried:
-
Added
{ req.ssl_sni -m found }to thetcp-request content acceptcondition, on the theory HAProxy was sometimes committing to a backend before the SNI extension had fully arrived in a fragmented/delayed ClientHello. -
Increased
tcp-request inspect-delayfrom 5s to 10s on one instance. -
Upgraded 2.8 → 3.2 → 3.4.4. Checked the 3.4.4 changelog directly and confirmed it already includes:
BUG/MEDIUM: ssl: Fix unprotected 'ssl_sock_choose_sni_ctx' callsBUG/MEDIUM: ssl: isolate TLS session resumption per X509 server certificateBUG/MINOR: ssl: isolate TLS session resumption per crt-list filterBUG/MEDIUM: ssl: isolate TLS session resumption per authentication policy
These looked like exactly our issue (cert-selection race + resumption reusing the wrong cert context), but the symptom has still recurred on 3.4.4.
Diagnostics: Ran a continuous full-packet tcpdump/tshark capture (systemd service, ring-buffered) watching for TLS ClientHellos on port 443 matching our mail domains, to catch a live occurrence. In every capture window checked so far (multiple hours, hundreds of real client connections across several domains), every single ClientHello with a matching SNI was correctly relayed to the mail backend within milliseconds — no missing SNI, no mismatched SNI, no unrelayed connections. We have not caught a genuine anomaly in the wire traffic corresponding to a reported failure.
Questions:
- Given the relevant SNI-ctx/session-resumption fixes are already in 3.4.4, is there a different known issue in this version range that could still cause TCP-mode
req.ssl_sniACL matching to intermittently miss despite a well-formed, correctly-timed ClientHello? - Given our packet captures show clean traffic every time we’ve checked, is it plausible this is actually a client-side (iOS Mail) stale/cached TLS-error notification being resurfaced on app-foreground, rather than a live HAProxy routing failure? Are there known client behaviors that would produce this without any corresponding bad packet on the wire?
- Is there a more definitive way to log, per-connection, which backend HAProxy actually selected and why (beyond raw tcpdump), to correlate with client reports after the fact?
Any insight — especially from anyone who’s seen this exact “clean captures, fixes already included, still occasional wrong cert” pattern — would be appreciated.