强制 cURL 在 HTTP 请求的代理上使用 GET
Force cURL to use GET on proxy for HTTPs requests
我正在尝试在我的本地计算机上使用转发代理服务器(Apache Traffic Server 或 Squid)作为我的 cURL 调用的本地 HTTP 缓存。
我使用以下方法设置了代理:
curl_setopt($ch, CURLOPT_PROXY, 'http://localhost:8080');
当我查询 HTTP 网站时,cURL 执行标准的 HTTP GET
代理请求,可以正确缓存:
GET http://example.com/ HTTP/1.1
但是,当查询 HTTPs 网站时,cURL 执行 CONNECT
,有效地将代理用作 TCP 隧道,并阻止它缓存响应:
CONNECT example.com:80 HTTP/1.1
有没有办法强制 cURL 执行 GET
请求,即使对于 HTTPs 网站也是如此?
为了安全起见,我可以理解为通过 HTTP 代理的 HTTP 请求使用 TCP 隧道背后的基本原理,但是因为我的代理服务器在本地主机上,所以我不关心使用不安全的 HTTP 连接到代理,并且会像 cURL 一样执行 GET
请求:
GET https://example.com/ HTTP/1.1
我尝试使用:
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false);
但这并没有改变任何东西。
我不相信这可以在客户端使用一些常见的配置设置来完成,因为它会否认 HTTPS 的全部目的(没有人可以窃听你的 HTTPS交通)。
因此,您唯一的选择是配置您的代理以基本上创建一个 man-in-the-middle attack to decrypt the HTTPS traffic going through it. Squid proxy should support this using their "SSL bump" feature. There is a nice intro for it on this wiki and more setup docs here。
squid 在这种情况下所做的是,它从客户端的 CONNECT
请求中获取远程服务器的地址,而不是仅创建到服务器的盲隧道,它 启动一个新的直接 HTTPS 请求 自己到服务器并保存回复。因此 Squid 可以访问所有流量并可以缓存它或做任何 Squid 可以用它做的事情。
当向客户端发送回复时,它本身需要提供一个 HTTPS 证书(客户端需要 HTTPS 流量),因此在 Squid 中有一个 automatically generate certificates 用于所有代理域的功能。要配置它,您基本上必须创建一个本地证书颁发机构。请注意,这些自动生成的证书将是简单的自签名证书,因此在客户端,这将看起来像 不受信任的证书,您需要关闭对等验证(CURLOPT_SSL_VERIFYPEER = false
).
我在 Apache 流量服务器中找不到任何类似的功能。他们似乎只支持反向代理模式中的SSL termination。
最后一点:请记住,这仍然是一种破解,解密 HTTPS 可能会带来法律或道德问题。未经客户同意,切勿这样做!
我不认为这里的其他答案理解你想做什么。但这是可能的。
您想发出一个 https 请求并像这样完成它:
client <--http--> cache <--https--> remote server
因此,您通过本地网络上的 http 不安全地将 https 请求发送到本地缓存,然后让缓存在开放的互联网上以 https 的形式安全地获取它。
为此,您只需破解第一跳。您的客户端程序向缓存发出一个普通的 http 请求,但添加了一个 header 表示在下一跃点转换为 https,例如:
x-use-protocol: https
随心所欲地发明header。为此,客户端和缓存都必须理解此 header 才能进行转换。这不适合一般的网页浏览 - 或者您无法控制客户端的任何时间。但如果您同时编写客户端和缓存,这是一个很好的答案。
我正在尝试在我的本地计算机上使用转发代理服务器(Apache Traffic Server 或 Squid)作为我的 cURL 调用的本地 HTTP 缓存。
我使用以下方法设置了代理:
curl_setopt($ch, CURLOPT_PROXY, 'http://localhost:8080');
当我查询 HTTP 网站时,cURL 执行标准的 HTTP GET
代理请求,可以正确缓存:
GET http://example.com/ HTTP/1.1
但是,当查询 HTTPs 网站时,cURL 执行 CONNECT
,有效地将代理用作 TCP 隧道,并阻止它缓存响应:
CONNECT example.com:80 HTTP/1.1
有没有办法强制 cURL 执行 GET
请求,即使对于 HTTPs 网站也是如此?
为了安全起见,我可以理解为通过 HTTP 代理的 HTTP 请求使用 TCP 隧道背后的基本原理,但是因为我的代理服务器在本地主机上,所以我不关心使用不安全的 HTTP 连接到代理,并且会像 cURL 一样执行 GET
请求:
GET https://example.com/ HTTP/1.1
我尝试使用:
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false);
但这并没有改变任何东西。
我不相信这可以在客户端使用一些常见的配置设置来完成,因为它会否认 HTTPS 的全部目的(没有人可以窃听你的 HTTPS交通)。
因此,您唯一的选择是配置您的代理以基本上创建一个 man-in-the-middle attack to decrypt the HTTPS traffic going through it. Squid proxy should support this using their "SSL bump" feature. There is a nice intro for it on this wiki and more setup docs here。
squid 在这种情况下所做的是,它从客户端的 CONNECT
请求中获取远程服务器的地址,而不是仅创建到服务器的盲隧道,它 启动一个新的直接 HTTPS 请求 自己到服务器并保存回复。因此 Squid 可以访问所有流量并可以缓存它或做任何 Squid 可以用它做的事情。
当向客户端发送回复时,它本身需要提供一个 HTTPS 证书(客户端需要 HTTPS 流量),因此在 Squid 中有一个 automatically generate certificates 用于所有代理域的功能。要配置它,您基本上必须创建一个本地证书颁发机构。请注意,这些自动生成的证书将是简单的自签名证书,因此在客户端,这将看起来像 不受信任的证书,您需要关闭对等验证(CURLOPT_SSL_VERIFYPEER = false
).
我在 Apache 流量服务器中找不到任何类似的功能。他们似乎只支持反向代理模式中的SSL termination。
最后一点:请记住,这仍然是一种破解,解密 HTTPS 可能会带来法律或道德问题。未经客户同意,切勿这样做!
我不认为这里的其他答案理解你想做什么。但这是可能的。
您想发出一个 https 请求并像这样完成它:
client <--http--> cache <--https--> remote server
因此,您通过本地网络上的 http 不安全地将 https 请求发送到本地缓存,然后让缓存在开放的互联网上以 https 的形式安全地获取它。
为此,您只需破解第一跳。您的客户端程序向缓存发出一个普通的 http 请求,但添加了一个 header 表示在下一跃点转换为 https,例如:
x-use-protocol: https
随心所欲地发明header。为此,客户端和缓存都必须理解此 header 才能进行转换。这不适合一般的网页浏览 - 或者您无法控制客户端的任何时间。但如果您同时编写客户端和缓存,这是一个很好的答案。