HAproxy配置REQ_SSL_SNI与SSL终止遇NOSRV日志报错求指导
我来帮你拆解下这个问题——你看到的NOSRV日志条目,本质是HAProxy找不到匹配的后端服务器来处理当前请求。结合你在配置SNI+SSL终止的场景,再考虑HAProxy 1.6.3这个特定版本的特性,我梳理了几个最可能遗漏的配置环节,你可以逐一排查:
1. SSL终止的基础配置是否完整
首先得确保SSL终止的核心配置没缺项:
- 你的HTTPS frontend必须用
bind *:443 ssl crt <证书路径>开启SSL,证书得是PEM格式(要把域名证书和对应私钥合并到同一个文件里)。如果有多个域名,HAProxy 1.6.3支持直接指定证书目录,比如crt /etc/haproxy/certs/,它会自动根据SNI匹配对应证书。 - 别忘了设置
mode http,因为你做了SSL终止后要把请求转成HTTP发给后端,这也是req.ssl_sni变量能被正确填充的前提。
2. SNI路由的ACL规则是否配置正确
要让HAProxy根据SNI值路由到对应后端,必须配置匹配规则:
- 先通过
acl匹配请求的SNI字段,比如:
这里acl sni_example_com req.ssl_sni -i example.com acl sni_test_com req.ssl_sni -i test.com-i表示忽略大小写,适配不同客户端的请求格式。 - 再把匹配到的ACL绑定到对应后端:
注意HAProxy 1.6.3里use_backend example_backend if sni_example_com use_backend test_backend if sni_test_comreq.ssl_sni变量是可用的,但必须确保frontend开启了SSL且是mode http,否则这个变量不会被填充。
3. 是否配置了默认后端
如果请求的SNI没有匹配到任何ACL规则,HAProxy会尝试使用默认后端;如果没设置默认后端,就会出现NOSRV错误。你可以:
- 要么给所有可能的SNI都配置对应的ACL和后端,要么设置一个
default_backend,哪怕是用来返回404/403的兜底后端也行,比如:default_backend fallback_backend backend fallback_backend http-request deny deny_status 403
4. 证书文件的权限和格式是否合规
- HAProxy的运行用户(通常是
haproxy)必须有证书文件的读取权限,建议设置权限为chmod 640 /etc/haproxy/certs/*.pem,并把haproxy用户加入证书所在组。 - 证书必须是合并了公钥和私钥的PEM文件,你可以用以下命令合并:
cat example.com.crt example.com.key > /etc/haproxy/certs/example.com.pem
5. 优化日志格式辅助排查
你当前的日志信息不够详细,可以调整HAProxy的日志格式,加入%[req.ssl_sni]字段,这样能直接看到请求的SNI值,方便判断是不是ACL匹配的问题:
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r %[req.ssl_sni]"
参考配置示例
给你一个简化的完整配置模板,你可以对照调整:
# 把HTTP请求重定向到HTTPS frontend http-in bind *:80 redirect scheme ssl code 301 if !{ ssl_fc } # HTTPS前端,处理SSL终止和SNI路由 frontend https-in bind *:443 ssl crt /etc/haproxy/certs/ mode http # SNI匹配规则 acl sni_example req.ssl_sni -i example.com acl sni_example_www req.ssl_sni -i www.example.com acl sni_test req.ssl_sni -i test.com # 路由到对应后端 use_backend example_backend if sni_example sni_example_www use_backend test_backend if sni_test # 兜底默认后端 default_backend fallback_backend # 业务后端示例 backend example_backend server example1 192.168.1.10:80 check backend test_backend server test1 192.168.1.11:80 check # 兜底后端 backend fallback_backend http-request deny deny_status 403
内容的提问来源于stack exchange,提问作者E1ts
相关产品推荐
相关产品推荐

