我想通过在 VPS 上运行的代理强制 HTTP(S) 流量从我的家庭网络传输到某些网站。
我tinyproxy
在 VPS 上安装,在端口上运行8080
。在我的计算机上,我正在运行
sudo ssh -i /home/user/.ssh/id_rsa -nNT -L 80:localhost:8080 -L 443:localhost:8080 remoteuser@vps
在本地访问代理。当我localhost:80
在 Firefox 设置中配置代理时,一切正常(HTTP 和 HTTPS)。
但由于我不希望所有流量都通过该代理,因此我将其添加到我的电脑中/etc/hosts
:
127.0.0.1 server.example
server.example
是为 HTTP 和 HTTPS 配置的 Web 服务器的名称。
访问http://server.example
正常,但https://server.example
在 Firefox 中打开时失败并显示错误
SSL_ERROR_RX_RECORD_TOO_LONG
curl
通过 HTTPS 访问页面也失败:
curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
据我了解,该问题是由于 tinyproxy 使用纯 HTTP 响应 HTTPS 请求引起的。
首先,理论上是否可以实现我想要的?那些所谓的“智能DNS”服务似乎正是这样做的。
这个问题是由我的设置引起的,还是 tinyproxy 根本无法做到这一点?是否有其他能够做到这一点的代理服务器?
编辑:目前我在我的电脑上运行 SSH 隧道并且 DNS 修改也是本地的,但我想稍后在我的路由器上部署它,以便来自我网络的任何设备的流量都会通过这个代理。
EDIT2:正如@SteffenUllrich 在评论中所写,当 HTTPS 通过 HTTP 代理路由时,客户端首先在握手发生之前发送未加密的 CONNECT 请求。请参见此处(到 VPS 的 SSH 隧道正在运行10.0.5.4
):
这是必要的,因为否则代理将无法确定应该将请求转发到哪个服务器。
但这些“智能 DNS”代理服务器究竟是如何工作的呢?(有关一般信息,请参阅这里)
因为它们不需要 CONNECT 请求,所以它们似乎没有 CONNECT 请求也能正常工作。但它们如何确定应将请求转发到哪个服务器?以下是使用此类“智能 DNS”代理(IP 为 37.xxx)的 HTTPS 连接转储。(DNS 被操纵以指向该代理):
那么,这是如何工作的?此外,有没有办法在我的 VPS 上实现这一点(也许不是用 Tinyproxy,而是用其他软件)?
答案1
看起来tinyproxy
不会真正透明地代理 HTTPS 连接,客户端必须使用该CONNECT
方法,这意味着必须设置它才能使用代理。
无论如何,如果不安装 MITM 证书,您就无法透明地代理 HTTPS,否则每次访问都会出现证书错误或由于该原因而失败。
您可能需要更复杂的东西,例如squid
。
答案2
但是这些“智能 DNS”代理服务器究竟是如何工作的呢?它们不需要 CONNECT 请求,它们似乎不需要 CONNECT 请求就可以工作。
我认为这些智能 DNS 代理通过从纯 HTTP 的 HTTP 请求中提取目标域来工作。对于 HTTPS,它们可能从 TLS 握手开始时的 ClientHello 消息中的 SNI TLS 扩展中提取域。
例如,可以使用以下方式构建类似的设置:鱿鱼代理。此代理可配置为在中央路由器上用作透明代理。由于所有客户端都使用此路由器作为互联网网关,因此可以使用数据包过滤规则将相关端口(http 和 https 的 80、443)上的流量重定向到代理,即无需特殊 DNS 设置。
然后,代理可以从 HTTP 标头(纯 HTTP)或 ClientHello(HTTPS)中提取真实目标,而无需破坏 SSL 加密 - 请参阅squid:SSL 窥视和拼接了解详情。squid 代理还可以根据目标配置为具有不同的上游代理(如您的 VPS)或直接连接。