使用代理的 Web 请求是否总是需要新连接?

Does a web request with proxy always require a new connection?

这是一个关于代理应该如何处理 HTTPS 请求的问题。如果代理后面有 2 个用户并且都一个接一个地转到 https://example.com,代理是否可以为用户 1.

重用之前使用 example.com 创建的现有 TCP 连接?

TCP 和 HTTPS 都是不同的协议,所以它似乎不会影响任何东西,实际上也不会。

现有的 TLS 实现中是否有某些东西可能不喜欢这种在同一连接上有两个不同会话的行为?从安全的角度来看,为不同的用户使用相同的 TCP 连接是不是一个坏主意?

您的意思是,如果两个 HTTP 客户端向反向 HTTP 代理发出请求,该代理是否可以重用与 HTTP 服务器的 TCP 连接?

是的,绝对是。这称为连接池,在实践中很常见。代理打开一个与每个后端端点的持久连接池。然后,代理对请求进行排队,每个请求都通过可用的 TCP 连接发送。

从 TLS 的角度来看,如果代理是 HTTP 代理 (L7),客户端将与代理而不是后端 Web 服务器执行 TLS 握手,因此没有问题。但是,如果代理在 L4 运行,则 TLS 终止必须发生在下游(TLS 传递),这会带来复杂性。

我目前的理解是 L4 代理与后端保持 1:1 连接。这意味着,每个传入连接都有一个对应的到后端的传出连接,这消除了我们重用连接和利用连接池的能力。

例如,NGINX 这样做:

NGINX maintains a “cache” of keepalive connections – a set of idle keepalive connections to the upstream servers – and when it needs to forward a request to an upstream, it uses an already established keepalive connection from the cache rather than creating a new TCP connection.

Load Balancing with NGINX and NGINX Plus, Part 2


有用的资源

我认为 https 不可能。

使用 http 代理代理 https 需要客户端使用 http CONNECT 方法,该方法提供原始 TCP 连接和重用上游连接的结果是每个后续客户端都必须接收具有历史记录的连接。这在网络流量的情况下可能不是问题,但会违反其他连接感知协议(例如 SSH 或 SMTP),例如期望邀请横幅。因为代理不知道将要使用的更高层协议,所以它不能假设重用 TCP 连接会起作用。

对于代理纯 HTTP 流量(不使用 http CONNECT 方法)这应该不是问题,只要客户端不发送带有 header 的 http 请求:

Connection: close

因此,虽然它是在具有反向代理的控制良好的环境中的常见解决方案,但我不知道是否有任何正向代理能够重用与上游服务器的 TCP 连接,这些服务器不限于代理配置中定义的某些服务器池。