Caddy反向代理转发TLS Client Hello时触发内部错误求助
问题:Caddy反向代理转发TLS握手失败,接收到Client Hello即报错
环境与配置
/etc/hosts 配置
127.0.0.1 localhost back-server.local proxy-server.local
后端服务器Caddyfile(Caddyfile-back-server)
{ http_port 2015 } back-server.local:2016 respond "Hello, world!"
代理服务器Caddyfile(Caddyfile-proxy-server)
{ http_port 2017 } proxy-server.local:2018 { reverse_proxy https://back-server.local:2016 { header_up Host {upstream_hostport} } }
测试情况
初始正常测试
$ caddy start --config Caddyfile-back-server $ caddy start --config Caddyfile-proxy-server $ curl https://back-server.local:2016 Hello, world! $ curl https://proxy-server.local:2018 Hello, world!
转发TLS握手测试失败
$ curl --connect-to back-server.local:2016:proxy-server.local:2018 https://back-server.local:2016 curl: (35) ... internal error
抓包显示:客户端向proxy-server.local:2018发送的TLS Client Hello中SNI为back-server.local,但代理直接返回TLS server alert: internal error并关闭连接,且未与后端服务器建立通信。
问题原因
当前代理的Caddy配置是HTTPS反向代理模式:Caddy会先作为TLS终止点,使用proxy-server.local的证书与客户端完成TLS握手,再以HTTPS请求转发到后端。
但你用--connect-to的测试方式,是让客户端直接向代理端口发送SNI为back-server.local的TLS Client Hello。而Caddy的proxy-server.local:2018站点仅配置了对应自身域名的证书,无法匹配该SNI请求,因此触发TLS内部错误,根本没进入反向代理的转发逻辑。
解决方法
根据实际需求选择以下两种方案:
方案1:配置TCP透传代理(完全转发TLS握手)
如果需要Caddy不终止TLS,直接将TCP流量透传给后端,让客户端与后端完成TLS握手,修改代理的Caddyfile为:
{ http_port 2017 } :2018 { reverse_proxy back-server.local:2016 { transport tcp } }
此模式下Caddy仅做字节流转发,不处理TLS,后端服务器的证书直接暴露给客户端。
方案2:扩展代理站点的SNI支持
如果仍需Caddy作为TLS终止点,让代理能处理SNI为back-server.local的请求,将代理的Caddyfile修改为:
{ http_port 2017 } proxy-server.local:2018, back-server.local:2018 { reverse_proxy https://back-server.local:2016 { header_up Host {upstream_hostport} } }
修改后Caddy会为两个域名生成证书,当客户端发送SNI为back-server.local的请求到2018端口时,Caddy能匹配到对应证书完成握手,再转发请求到后端。
内容的提问来源于stack exchange,提问作者sof
相关产品推荐
相关产品推荐

