设置透明的SSL代理


14

我有一个装有2个网卡的linux盒,用于检查通过端口80的流量。一张卡用于连接互联网,另一张卡连接至网络交换机。关键是要能够检查连接到该交换机的设备上用于调试目的的所有HTTP和HTTPS通信。

我为iptables编写了以下规则:

nat

-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.2.1:1337
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 1337

-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

在192.168.2.1:1337上,我使用Charles(http://www.charlesproxy.com/)进行了透明的http代理记录。

端口80一切都很好,但是当我为指向端口1337的端口443(SSL)添加类似规则时,通过Charles收到有关无效消息的错误消息。

我之前曾在Charles的同一台计算机上使用过SSL代理(http://www.charlesproxy.com/documentation/proxying/ssl-proxying/),但是由于某种原因未能透明地进行SSL代理。我用Google搜索的一些资源说这是不可能的-如果有人可以解释原因,我愿意接受它作为答案。

需要注意的是,我拥有上述设置的完全访问权限,包括连接到子网的所有客户端-因此,我可以接受Charles的自签名证书。该解决方案不必特定于Charles,因为从理论上讲,任何透明代理都可以。

谢谢!

编辑:稍微玩了一下之后,我就能让它在特定主机上正常工作。当我将iptables修改为以下内容时(并以查尔斯打开1338作为反向代理):

nat

-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.2.1:1337
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 1337

-A PREROUTING -i eth1 -p tcp -m tcp --dport 443 -j DNAT --to-destination 192.168.2.1:1338
-A PREROUTING -i eth1 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 1338

-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

我能够得到回应,但没有目标主机。在反向代理中,如果我仅指定1338中的所有内容都传递给我想击中的特定主机,它将正确执行握手操作,并且我可以打开SSL代理来检查通信。

设置不理想,因为我不想假设从1338起的所有内容都交给该主机-知道为什么要剥离目标主机了吗?

再次感谢


您有什么具体问题?因为您信任它动态生成的证书,所以这是可能的-它可以是MITM并捕获通信的纯文本,并使连接仍受客户端信任。
Shane Madden

我编辑了我的帖子-我相信目标主机会被删除
Badunk 2012年

Answers:


10

您遇到的问题与阻止在单个IP地址/端口上使用多个证书的问题相同(不使用服务器名称指示)

在纯HTTP中,您的透明代理可以通过查看Host标头来判断客户端要连接到哪个主机。

当HTTPS MITM透明代理收到请求时,它首先不知道客户端正在请求哪个主机名。(我什至不确定它是否可以使用这些规则来获取IP地址,这至少可以使它使用反向DNS查找来进行猜测,即使在一般情况下也不大可能。)

  • 为了获得预期的主机名,MITM代理将必须读取HostHTTP消息中的标头,只有在成功握手后才能出现标头。
  • 为了成功进行握手,MITM代理需要生成与预期主机名匹配的欺骗证书。

结果,MITM代理在握手之前不知道要生成哪个证书。

这可以与非透明的MITM代理一起使用,因为您至少会通过HTTP CONNECT方法获得所需的主机名。


这对我解释了很多,谢谢!我觉得我可以开始提出正确的问题了。但是,如何建立透明的SSL代理呢?握手是什么样的?
badunk 2012年

1
@badunk,我认为您不能,除非您在客户端禁用所有证书验证。
布鲁诺

代理获取正确主机名的另一种方法是,在继续客户端与代理之间的握手之前,向目标IP地址发出请求以获取其证书。
布鲁诺

mitmproxy是一个HTTPS代理。您不必禁用所有证书验证,但必须安装mitmproxy证书,因为它将用于所有https连接。
泰勒

3

只是有关此主题的一些基本信息。

据我所知,只有少数设备可以成功完成此操作。但是,它们并不是真正面向普通公众的。我本人正在使用带有SSL卸载功能的Fortinet Fortigate。

它的基本作用是:它会拦截与主机建立的SSL连接,并在硬件中解密该连接,然后检查您要去的地方,并根据该信息做出防火墙决定。

之后,它建立与该主机的自己的连接以检索数据,并使用用户提供的CA将原始请求重新签名给客户端。为了使此工作顺利进行,需要将CA置于客户端上的受信任根CA中。

这些设置用于组织中以执行有关Internet使用的公司策略。由于使用Active Directory,因此很容易在客户端中安装公司CA,这对于大型组织而言不成问题。

由于SSL流量已加密,因此这是无需创建手动代理即可执行的唯一方法。它基本上是一个MITM,因此涵盖所有法律问题非常重要。


1

关于这个其他问题,您可能还会看到一些其他建议:透明的SSL代理神话和事实。并且此链接说明了如何精确配置Squid使其成为透明的SSL代理。这不是您要查找的内容,但至少可以使您了解可能出了什么问题。

iptables规则似乎还可以,但是我不知道您使用的代理软件是否能够执行您尝试执行的操作。该文档肯定是这种情况。


0

为了增加Bruno的解决方案,我进行了一些调查,并希望与大家分享如何获得另一个不理想的快速解决方案。

设置完这些iptables之后,我可以在端口1338上放置一个反向代理,并将其转发到端口1337上的本地主机。由于端口1337是透明的http代理,并且数据已解密,它将使用主机头并将其作为目的地主办。

主要缺点是我已经将https连接转换为http -并非总是适用于每台服务器(更不用说我从中暴露出的安全漏洞了)。

我在软件范围内工作。我相信按照Bruno的观点,更干净的解决方案是假设1338年以后的所有流量都应解密。解密后,检查目标主机,然后使用SSL代理请求。


不确定我是否理解,当然,您不是https://从客户端的角度进行此连接吗?
布鲁诺2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.