【发布时间】:2018-04-11 19:45:19
【问题描述】:
我正在尝试设置终止 SSL 连接的 Apache 正向代理。我尝试这样做的原因是在返回的代码上运行 Apache 过滤器(特别是 mod_pagespeed)。在处理 mod_pagespeed 之前,我正在通过尝试在响应中插入标头来测试这个 POC(这将证明我可以编辑响应),但是我遇到了 SSL 代理问题(非 SSL 代理工作正常) .
请注意,我不关心任何证书错误或类似问题——这纯粹是为了内部测试。
我已经设置好服务器并在非 SSL 页面上看到 X-MSCProxy 标头:
jshannon-macbookpro:pagespeed_proxy jshannon$ curl -vv --proxy pagespeed_proxy:3ja82ad9@localhost:8080 -D - -o /dev/null http://www.slate.com
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
* Proxy auth using Basic with user 'pagespeed_proxy'
> GET http://www.slate.com/ HTTP/1.1
> Host: www.slate.com
...
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Mon, 30 Oct 2017 18:10:40 GMT
Date: Mon, 30 Oct 2017 18:10:40 GMT
< Server: Apache/2.2.29 (Amazon)
Server: Apache/2.2.29 (Amazon)
...
< Content-Length: 187051
Content-Length: 187051
...
< X-Instart-Request-ID: 8286987369135064135:FWP01-NPPRY22:1509387040:0
X-Instart-Request-ID: 8286987369135064135:FWP01-NPPRY22:1509387040:0
< Via: 1.1 172.17.0.2:8080
Via: 1.1 172.17.0.2:8080
< X-MSCProxy: SansPS
X-MSCProxy: SansPS
但是当我向 Slate 的 SSL 页面发出相同的请求时,我看不到我的代理:
jshannon-macbookpro:pagespeed_proxy jshannon$ curl -vv --proxy pagespeed_proxy:3ja82ad9@localhost:8080 -D - -o /dev/null https://www.slate.com
* Connected to localhost (::1) port 8080 (#0)
* Establish HTTP proxy tunnel to www.slate.com:443
* Proxy auth using Basic with user 'pagespeed_proxy'
> CONNECT www.slate.com:443 HTTP/1.1
> Host: www.slate.com:443
< HTTP/1.0 200 Connection Established
HTTP/1.0 200 Connection Established
< Proxy-agent: Apache/2.4.25 (Debian)
Proxy-agent: Apache/2.4.25 (Debian)
<
* Proxy replied OK to CONNECT request
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: ssl004.insnw.net
* Server certificate: GlobalSign CloudSSL CA - SHA256 - G3
* Server certificate: GlobalSign Root CA
> GET / HTTP/1.1
> Host: www.slate.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< Content-Length: 187044
Content-Length: 187044
< Connection: keep-alive
Connection: keep-alive
< Server: Apache/2.2.29 (Amazon)
Server: Apache/2.2.29 (Amazon)
< X-Instart-Request-ID: 762420041708891440:FWP01-NPPRY21:1509387251:0
X-Instart-Request-ID: 762420041708891440:FWP01-NPPRY21:1509387251:0
我发现很多帖子说通过各种 httpd.conf 建议这是可能的(从技术上讲,应该是),但我尝试过的任何方法都没有奏效。现在我的 httpd.conf 看起来像:
<VirtualHost *:8080>
ProxyRequests On
ProxyVia On
Header set X-MSCProxy SansPS
#SSLEngine On
# suggestion that this allows termination
ProxyPreserveHost On
SSLProxyEngine on
SSLProxyCheckPeerCN Off
SSLProxyCheckPeerExpire Off
SSLProxyCheckPeerName Off
SSLCertificateFile /etc/apache2/ssl/localhost.crt
SSLCertificateKeyFile /etc/apache2/ssl/localhost.key
ModPagespeed Off
</VirtualHost>
FWIW,当我在此代理上启用 SSLEngine(如建议的那样)时,请求根本无法处理来自 Apache 的此错误:
[Mon Oct 30 18:20:20.705047 2017] [ssl:info] [pid 372:tid 140147985901312] [client 172.17.0.1:34012] AH01996: SSL handshake failed: HTTP spoken on HTTPS port; trying to send HTML error page
[Mon Oct 30 18:20:20.705107 2017] [ssl:info] [pid 372:tid 140147985901312] SSL Library Error: error:1407609C:SSL routines:SSL23_GET_CLIENT_HELLO:http request -- speaking HTTP to HTTPS port!?
我认为这是有道理的,因为代理协议不期望直接与代理建立 HTTPS 连接。
【问题讨论】:
-
由于两个原因,任何典型的客户都不可能。 1) 如您所见,https 客户端不会通过 SSL 与转发代理通信。 2)即使您的客户端使用 https 到代理,它仍然会通过已建立的 CONNECT 隧道使用 https,因此代理将无法通过它看到 HTTP 请求/响应以进行操作。对我来说似乎是一个死胡同。
-
好的。感谢您的确认。
-
不使用它作为代理,而是使用主机文件将域指向 apache 服务器,然后代理将请求传递给原始服务器如何?这是有效的,因为您将拥有一个
https (domain IP changed using host file)-> Apache -> https on original site -
@TarunLalwani。唔。您是否建议我编写自己的代理(这可能很简单:
return curl(request_url))。您的方法将利用主机文件,而不必处理重写链接、资产和 XHR 请求(这很有用)。