haproxy + stunnel + 保持活动?

haproxy + stunnel + 保持活动?

我想将 stunnel 放在 haproxy 1.4 前面来处理 HTTPS 流量。我还需要 stunnel 来添加X-转发标头。这可以通过“stunnel-4.xx-xforwarded-for.diff”实现补丁 来自 haproxy 网站。

然而,描述中提到:

请注意,此补丁不适用于 keep-alive,...

我的问题是:这对我来说意味着什么?我不确定,

  1. 如果这是关于
    • 客户端和隧道
    • stunnel 和 haproxy
    • 或 haproxy 和后端服务器?
  2. 这对性能意味着什么:如果我的网页上有 100 个图标,浏览器是否必须协商 100 个完整的 SSL 连接,或者它是否可以重新使用 SSL 连接,而只需创建新的 TCP 连接?

答案1

这是关于 HTTP 保持活动状态的,它允许多个资源请求通过单个 TCP 会话(对于 SSL,则为单个 SSL 会话)进行。这对于 SSL 站点的性能非常重要,因为如果没有保持活动状态,则每个请求的资源都需要 SSL 握手。

因此,这里需要关注的是从客户端一直到后端服务器的一个大型保持活动会话。这对于性能来说很重要,并且对于现代 HTTP 服务器来说理所当然,但此补丁表示它不支持它。让我们来看看为什么……


保持活动会话只是一个接一个的请求——一旦服务器完成对一个请求的响应,服务器就不会发送数据FIN包来结束 TCP 会话;客户端可以简单地发送另一批标头。

为了理解该补丁的作用,下面是一个保持活动对话的示例:

客户:

GET / HTTP/1.1
Connection: keep-alive
Host: domain.com
...

服务器:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: Apache
Content-Length: 34
.... (other headers)
<html><head>content!</head></html>

这里是非保持连接停止的地方。但是,保持连接允许客户端启动另一个连接:

GET /images/some/image.on.the.page.jpg HTTP/1.1
Connection: keep-alive
Host: domain.com
...

对于代理中的客户端 ID,一些反向代理可以在每个客户端请求中添加X-Forwarded-For标头。这告诉上游服务器请求来自哪里(而不是每个请求都从反向代理的 IP 发起),以确保日志记录和其他应用程序需求的完整性。

需要将标X-Forwarded-For头注入通过保持活动连接发送的每个客户端资源请求中,因为每次都会发送完整的标头;标X-Forwarded-For头的处理和将其转换为“真实”请求 IP 是基于每个请求而不是每个 TCP 保持活动会话进行的。嘿,也许有一些很棒的反向代理软件,它们使用单​​个保持活动会话来处理来自多个客户端的请求。

这就是这个补丁失败的地方。


该站点的补丁会监视 TCP 会话的缓冲区,以查找流中第一组 HTTP 标头的结尾,并在第一组标头结束后将新标头注入流中。完成此操作后,它会认为工作已X-Forwarded-For完成,并停止扫描新标头集的结尾。此方法无法感知通过后续请求传入的所有未来标头。

其实不能责怪他们;stunnel 并不是真正为处理和翻译其流的内容而构建的。

这会对你的系统产生的影响是第一的保持活动流的请求将会X-Forwarded-For正确注入标头,并且所有后续请求都将正常工作 - 但它们不会有标头。

除非有另一个标头注入补丁可以处理每个连接多个客户端请求(或者在 Stack Overflow 上我们的朋友的帮助下对此进行调整),否则您可能需要考虑 SSL 终止的其他选项。

答案2

STunnel 4.45 使用 HAProxy 1.15 的一些新功能(代理协议)正确解决了这个问题

它还修复了以前的补丁和 Keep Alive 的问题

答案3

与我在另一个帖子中发布的内容类似,自 1.5-dev12 以来,HAProxy 确实支持两端的本机 SSL。因此,拥有 X-Forwarded-For、HTTP keep-alive 以及告诉服务器连接是通过 SSL 建立的标头非常简单,如下所示:

listen front
    bind :80
    bind :443 ssl crt /etc/haproxy/haproxy.pem
    mode http
    option http-server-close
    option forwardfor
    reqadd X-Forwarded-Proto:\ https if { is_ssl }
    server srv1 1.1.1.1:80 check ...
    ...

这比修补 stunnel 要容易得多,而且比放弃 keep-alive 要好得多。

答案4

扩展 Shane 的出色回答,您可以在 HAproxy 前面使用 Nginx 作为 SSL 终止器。它正确处理客户端和 nginx 之间的保持活动,这是对延迟最敏感的一侧,并为每个客户端请求建立到后端的新连接,并在每个请求中发送 X-FORWARDED-FOR。

相关内容