apache - CONNECT 请求通过 SSL 连接转发 HTTP 代理?

标签 apache http ssl proxy

我正在编写一个 HTTP 代理,但我无法理解通过 TLS 发出 CONNECT 请求的一些细节。为了获得更好的画面,我正在试验 Apache 以观察它如何与客户端交互。这是来 self 的默认虚拟主机。

NameVirtualHost *:443
<VirtualHost>
  ServerName example.com
  DocumentRoot htdocs/example.com  
  ProxyRequests On
  AllowConnect 22
  SSLEngine on
  SSLCertificateFile /root/ssl/example.com-startssl.pem
  SSLCertificateKeyFile /root/ssl/example.com-startssl.key
  SSLCertificateChainFile /root/ssl/sub.class1.server.ca.pem
  SSLStrictSNIVHostCheck off
</VirtualHost>

Apache 和我的客户之间的对话是这样的。

一个。客户端连接到 example.com:443 并在 TLS 握手中发送 example.com

客户端发送 HTTP 请求。

CONNECT 192.168.1.1:22 HTTP/1.1
Host: example.com
Proxy-Connection: Keep-Alive

Apache 显示 HTTP/1.1 400 Bad Request。 Apache 错误日志说

Hostname example.com provided via SNI and hostname 192.168.1.1
provided via HTTP are different. 

似乎 Apache 不会查看 Host header ,只是查看它是否存在,因为 HTTP/1.1 需要它。如果客户端发送 Host: foo,我会得到相同的失败行为。如果我在没有 TLS 的情况下向 example.com:80 发出 HTTP 请求,那么 Apache 会将我连接到 192.168.1.1:22。

我不完全理解这种行为。 CONNECT 请求有问题吗?我似乎无法找到解释所有这些的 RFC 的相关部分。

最佳答案

不清楚您是否正在尝试使用 Apache Httpd 作为代理服务器,这可以解释您收到的 400 状态代码。 CONNECT 由客户端使用,并发送到代理服务器(可能是 Apache Httpd,但通常不是),而不是目标 Web 服务器。

CONNECT 在客户端和终端服务器之间建立 TLS 连接之前在客户端和代理服务器之间使用。客户端 (C) 连接到代理 (P) proxy.example.com 并发送此请求(包括空行):

C->P: CONNECT www.example.com:443 HTTP/1.1
C->P: Host: www.example.com:443
C->P:

代理打开到 www.example.com:443 的 TCP 连接(P-S)并用 200 状态码响应客户端,接受请求:

P->C: 200 OK
P->C: 

在此之后,客户端和代理(C-P)之间的连接保持打开状态。代理服务器将 C-P 连接上的所有内容中继到 P-S 或从 P-S 接收。客户端通过在该 channel 上启动 TLS 握手,将其事件 (P-S) 连接升级为 SSL/TLS 连接。由于现在一切都已中继到服务器,就好像 TLS 交换是直接使用 www.example.com:443 完成的。

代理在握手过程中没有任何作用(因此对于 SNI)。 TLS 握手实际上直接发生在客户端和终端服务器之间。

如果您正在编写代理服务器,则在 CONNECT 请求中读取允许您的客户端连接到 HTTPS 服务器所需要做的所有事情,建立从代理到终端服务器的连接(在 CONNECT 请求中给出),向客户端发送一个 200 OK 回复,然后将您从客户端读取的所有内容转发到服务器,反之亦然。

RFC 2616CONNECT 视为建立简单隧道的一种方式(它确实如此)。在 RFC 2817 中有更多相关信息,尽管很少使用 RFC 2817 的其余部分(在非代理 HTTP 连接中升级到 TLS)。

看起来您正在尝试做的是通过 TLS 在客户端 (C) 和代理 (P) 之间建立连接。这很好,但客户端不会使用 CONNECT 连接到外部 Web 服务器(除非它也是到 HTTPS 服务器的连接)。

关于apache - CONNECT 请求通过 SSL 连接转发 HTTP 代理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6594604/

相关文章:

http - 高响应时间与排队

php - 在 PHP 中进行 SOAP 调用并设置 SSL 版本

php - 检测到路径错误的 Apache 服务

apache - 如何使用 modheader 删除 session cookie 安全标志?

php - 修改数据卷中的文件后添加了非法 token

Apache 多个 Access-Control-Allow-Origin 设置

c# - 创建用于测试目的的 Http 请求

http - 服务器启动时记录

ssl - 如何让虹吸识别 SSL 证书包

asp.net-mvc - RequireSSL 在带有 Querystring 的 Url 上失败