You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haproxy基于SNI的TLS透传与终止配置问题求助

HAProxy TLS Termination Issue for Subdomain a.mydomain.com

Let's break down what's causing your handshake error and fix it step by step:

Root Cause

The error SSL peer handshake failed, the server most likely requires a client certificate to connect is directly tied to this line in your frontend a configuration:

verify required

This option forces HAProxy to demand a valid client certificate from the connecting client during TLS handshake. Since your regular clients (browsers, API callers) don't send client certificates by default, the handshake fails immediately.

Additionally, your SNI capture showing - is likely due to missing SNI capture configuration in the main TCP frontend, though your routing rules work because the ACLs are correctly inspecting the SNI during the TLS hello.

Fix Steps

1. Remove Client Certificate Requirement (Critical Fix)

Update your frontend a to remove the client certificate verification rules—you only need to terminate TLS for the subdomain, not enforce client auth:

frontend a
bind *:9666 ssl crt server.pem accept-proxy
mode http
default_backend proxy_a

We removed ca-file ca.pem and verify required because these are only needed for mutual TLS (mTLS) authentication, which isn't part of your stated requirement.

2. Fix SNI Logging (Optional but Useful)

To properly capture SNI in your logs (so you don't see - for capture0), add SNI capture logic to your main frontend and update the log format:

First, modify the frontend main to capture SNI:

frontend main
bind *:443
mode tcp
option tcplog
log global
# Capture SNI from TLS hello for logging
tcp-request content capture req_ssl_sni len 64
tcp-request inspect-delay 5s
acl is_main req_ssl_sni -i "${pDomainName}"
acl is_a req_ssl_sni -m beg "a"
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend main if is_main
use_backend a if is_a

Then update your global section to include the captured SNI in logs:

global
    log /dev/log local0
    # Add sni=%{+Q}[capture.req.hdr(0)] to your log format
    log-format %ci:%cp [%tr] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq sni=%{+Q}[capture.req.hdr(0)]

3. Validate the Flow

With these changes, your traffic path for a.mydomain.com will work as intended:

  • Client sends TLS hello to NLB:443 with SNI a.mydomain.com
  • HAProxy main frontend matches the SNI ACL and forwards the TCP stream to 127.0.0.1:9666 with proxy protocol headers
  • frontend a terminates the TLS connection using server.pem, then forwards the HTTP request to your proxy_a backend

Why Your Test with a Different HTTP Port Worked

When you switched frontend a to a different port using HTTP mode, there was no TLS handshake involved—so the client certificate requirement (which only applies to SSL/TLS connections) wasn't triggered, hence no error.

内容的提问来源于stack exchange,提问作者CrusaderX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:52:54