【问题标题】:How to pass the custom SNI with haproxy in TCP mode如何在 TCP 模式下使用 haproxy 传递自定义 SNI
【发布时间】:2021-07-01 15:25:27
【问题描述】:

我有一个公共 ssl 端点 something.example.com,它需要使用 SNI 扩展。我不能直接访问它,所以我想通过 haproxy 传递它(它设置在可以访问互联网的服务器中)

这不起作用: openssl s_client -connect something.example.com:443

这工作正常: openssl s_client -connect something.example.com:443 -servername something.example.com

我的 haproxy 配置(版本 1.8.24):

frontend my_frontend
    bind *:443
    mode tcp
    log global
    option tcplog
    tcp-request inspect-delay 5s
    tcp-request content accept if { req_ssl_hello_type 1 }
    use_backend my_backend

backend my_backend
    mode         tcp
    server       my-server something.example.com:443 sni str(something.example.com)

当我登录 haproxy 服务器时,我可以这样做:

curl -v https://something.example.com/ 可以看到 SSL 连接已经建立

但是在做curl -v https://127.0.0.1/我面对的时候:

curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL 连接到 127.0.0.1:443

怎么了?我已经尝试终止 ssl,替换主机头但没有运气。我的理解是 SNI 本身与加密请求是分开的,通过上述配置,我应该能够连接到后端。

附言。后端服务器不是我管理的。


编辑:如 cmets 中所述,无法在 TCP 模式配置中传递自定义 SNI。可以为 http 模式执行以下操作,使用 TLS 终止,以下工作正常:

frontend log_frontend
    bind *:443 ssl crt /etc/pki/tls/private/mycert.pem
    mode http
    log global
    option httplog
    option forwardfor
    use_backend log_backend

backend log_backend
    mode         http
    server       my-server something.example.com:443 ssl verify none sni str(something.example.com)

【问题讨论】:

    标签: ssl haproxy sni


    【解决方案1】:

    我的理解是 SNI 本身与加密请求是分开的......

    SNI 是 SSL/TLS 握手的一部分,特别是客户端在握手开始时发送的 ClientHello。 无法替换 TLS 握手的任何部分,包括 SNI。相反,需要终止 TLS(这意味着需要适当的证书等),然后必须使用预期的 SNI 集创建一个新的 TLS 会话。

    【讨论】:

    • 嘿,Steffen,你可能是对的,但是我知道 TCP 模式下的 haproxy 仍然可以破译 SNI 本身,例如基于此的路由。由于它的 TCP 模式,它无法处理任何标头等。你确定 SNI 是不可触及的吗?查看官方文档:“'sni' 参数评估示例提取表达式,将其转换为字符串并将结果用作在 SNI TLS 扩展中发送到服务器的主机名”。 --> IMO "sni str()" 应该完全符合我的需要。
    • 您能帮我配置 TLS 终止并放置正确的 SNI 吗?这就是我现在所拥有的,在这里找不到如何启用 SNI。尝试替换标题或将其设置在后端部分,但没有运气。我已经为 haproxy 服务器申请了证书,并且可以看到 TLS 连接正在建立,但它不会去后端。
    • 我在主帖中添加了配置。由于我不管理后端,我应该离开这里ssl verify none吗?
    • @borubar:就像我说的,在 TCP 模式下无法更改 SNI。它可以被阅读,因此可以根据它做出决定。但是更改 SNI 会破坏 TLS 握手的完整性,并且握手会失败。
    • 知道了,顺其自然吧。你能评论一下http模式的配置吗?它不起作用,我只能连接到 haproxy 前端,但从后端获取 503。 * TLSv1.2 (IN), TLS alert, close notify (256): * Closing connection 0 * TLSv1.2 (OUT), TLS alert, close notify (256): Verify return code: 21 (unable to verify the first certificate)
    【解决方案2】:

    好吧,我假设您还会在调用 curl -v https://127.0.0.1/ 时收到类似“证书与主机名不匹配”的信息。

    我强烈建议告诉 curl 如何解决 something.example.com

    curl -v --resolve something.example.com:443:127.0.0.1 https://something.example.com/
    

    更详细的解释在这篇博文中 https://daniel.haxx.se/blog/2018/04/05/curl-another-host/

    顺便说一句:我强烈建议更新到最新的 LTS 版本的 haproxy 2.4

    【讨论】:

    • 感谢 Aleksandar 的输入。你是对的,但是当我指定服务器名称时,我已经确保我的配置工作正常。我需要做的是让它在没有这个的情况下工作,这样 haproxy 将负责发送到后端服务器的内容。关于 haproxy 版本 - 完全同意,但是我在非常安全的环境中工作,基于 RHEL,所以通常只有 1.5.18 可用 - 我被允许使用软件集合中的 1.8.24 仍然是一个惊喜。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 2019-05-07
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多