在没有 VPN 的情况下通过 TLS 重定向所有网络流量

all*_*tic 10 firefox firewall proxy https

假设:

服务器:

  • 我有一个 Debian Squeeze 服务器,可在公共 Internet 上路由,具有静态 IPv4 地址。
  • 我可以不受限制地访问修改服务器上的软件。
  • 服务器可以监听任意端口,重新配置防火墙规则,基本上没有限制服务器可以做什么。

客户:

  • 我可以在本地系统(没有管理员权限的锁定 Windows 桌面)上运行 Firefox、Java 程序、.NET 程序和一些不需要管理员访问权限的本机可执行文件。
  • 我可以在 Firefox 中安装插件。
  • 我可以侦听环回 ( localhost) 接口上的任何端口。因此,上述程序可以绑定到本地端口并执行任意网络 I/O,而无需通过代理。
  • 所有公共 Internet访问都通过限制性 HTTP 代理进行路由,该代理会阻止许多站点,并进行仔细的状态检查。在端口 80 上,它只允许 HTTP(无 TLS/SSL)。在端口 443 上,它允许CONNECT基于 SSL/TLS 访问不受域名/IP 地址阻止的远程主机。
  • 限制性 HTTP 代理不会对允许通过代理的 TLS 连接执行深度数据包检查,并且不会对这些连接执行中间人攻击。
  • 我可以访问的上述服务器,没有被代理阻止。

目标:

我想通过上述服务器,通过 SSL/TLS路由Firefox 发出的所有HTTP 和 HTTPS 请求。

关于“目标”的其他说明:

  • 即使端点站点(例如,http://superuser.com)没有对我的服务器使用 SSL/TLS,我仍然希望从我的客户端到我的服务器使用 SSL/TLS ,并让我的服务器执行 HTTP 请求——无论是否加密—— - 到我想要的目的地。
  • 不在乎我的服务器是否正在查看“清晰”的 SSL 流量。换句话说,如果远程服务器正在被例如访问,我不需要从本地客户端到远程服务器的完整端到端 SSL 加密https://google.com。换句话说,我相信服务器会对我的数据保密。
  • 我愿意安装任何不需要管理员权限并且可以在 32 位 Windows 7 上运行的软件或 Firefox 插件。
  • 开源软件优于专有软件,免费软件优于需要许可费的软件。
  • 现有软件比编写新软件更受欢迎,但如果这是唯一的方法,我愿意编写代码。

我正在寻找一个松散描述的“解决方案”,它描述了:

  • 客户端需要什么软件?如果有您知道的特定软件包,请为其命名;否则,请描述客户端软件必须执行的操作
  • 服务器上需要什么软件?如果有您知道的特定软件包,请为其命名;否则,请描述服务器软件必须执行的操作
  • 如果您在上面命名了特定的软件包,请描述设置它以满足我的目标所需的配置参数。
  • 如果出于某种原因您认为这是不可能的,请说明原因

我尝试过但不起作用的事情

  • squid在我的服务器上安装,我尝试在我的服务器上设置我自己的标准 HTTP 代理。这没有成功,因为当我通过常规 HTTP 在 Firefox 中请求网站时,Firefox也会尝试通过常规 HTTP 访问我的服务器!这是不可接受的,因为我本地网络上的代理当然可以观察和/或阻止我的客户端和服务器之间的常规 HTTP 流量。
  • VPN 不起作用,甚至无法通过 TLS 侦听端口 443 的 OpenVPN,因为我没有在本地计算机上安装tun可以执行第 3 层路由的网络适​​配器的权限,也不能执行任何类型的第 2 层路由(例如tap)。简而言之:我需要管理员权限才能安装 OpenVPN,即使我暂时拥有这些管理员权限,如果他们发现它已安装,公司也不会太高兴。Java 或 .NET 程序不太引人注目,特别是当它没有安装在添加/删除程序中并且没有像 OpenVPN 那样的内核驱动程序组件时。

all*_*tic 5

我想到了。:D这个解决方案满足了我的所有要求并完美地满足了我的所有目标。考虑到实现这一目标所需的间接级别,性能也不算太差。

因此,一般方法是:

  1. 设置本地证书颁发机构 (CA),并生成 RSA“服务器密钥”和“客户端密钥”(我使用了 256 位加密)。为此,我使用了Easy-RSA版本 3.0.0-rc2。

  2. 在“Debian Box”(公共 Internet 上的服务器)上运行任何 bog 标准 HTTP 代理,确保它仅在localhost 上侦听(它不应暴露于公共 Internet)。出于我的目的,我使用了Privoxy,但Squid也能正常工作。由于它只在 localhost 上侦听,因此不需要身份验证(除非您不信任您的机器上正在运行的进程;在这种情况下,是的……)

  3. 下载stunnel并将其安装在客户端和服务器上。执行此操作的过程将特定于操作系统;就我而言,我选择从源代码(偏执狂...)为 Windows 编译 stunnel,这是一个相当复杂的过程,我不会在这里详述。在服务器端,它在包管理器中可用:)

  4. Stunnel 的配置起初相当令人生畏,但它比看起来更简单!基本上,在服务器上,您需要类似于下面的“server's stunnel.conf”。在客户端上,您需要类似于下面的“client's stunnel.conf”。

  5. 启动Privoxy;在服务器上启动 stunnel,将其指向配置文件;在客户端上启动 stunnel,将其指向配置文件。Privoxy 的配置真的没有什么特别之处。默认对我来说很好。

  6. 在 Firefox(客户端选择的浏览器)中,将 HTTP 和 HTTPS 代理设置为与客户端的 stunnel 侦听的端口相同——可能类似于 localhost:8080。

我可能应该注意到,如果您的本地网络代理需要某种身份验证,您要么必须让 stunnel 为您进行身份验证,要么使用另一个本地拦截代理并将它们链接在一起——比如 Firefox -> stunnel -> local验证代理 -> LAN 代理/网关 -> 互联网 -> 您服务器的通道 -> privoxy。

这是很多复制,但它的工作原理!

;This is the *client's* stunnel.conf.
[https]
accept = localhost:9020
connect = your.lan.proxy:80
client = yes
protocol = connect
;protocolHost should be the same as the "accept" for the server
protocolHost = 1.2.3.4:443
;Same CAfile, different cert and key pair
CAfile = ca.crt
cert = client.crt
key = client.key
;VERY IMPORTANT!!! Make sure it's really your server and not a MITM attempt by your local network by making sure that the certificate authority "ca.crt" really signed the server's cert
verify = 2
;More performance tweaks...
sessionCachetimeout = 600
sessionCacheSize = 200
TIMEOUTidle = 600
Run Code Online (Sandbox Code Playgroud)

.

;This is the *server's* stunnel.conf.
[https]
;1.2.3.4 is a publicly-routable, static IP address that can be connected to by your box that's under the firewall
accept = 1.2.3.4:443
;localhost:8118 is an example of where your local forwarding HTTP(S) proxy might reside.
connect = localhost:8118
CAfile = ca.crt
cert = server.crt
key = server.key
;VERY IMPORTANT!!! Without this, anyone in the world can use your public stunnel port as an open proxy!
verify = 2
;Set some timeouts higher for performance reasons
sessionCacheTimeout = 600
sessionCacheSize = 200
TIMEOUTidle = 600
Run Code Online (Sandbox Code Playgroud)

配置完所有内容后,最终结果看起来像这样:

  1. 您的 Web 浏览器连接到localhost:9020(stunnel) 并将其视为可以接受 HTTP 和/或 HTTPS 连接的代理。
  2. 一旦 stunnel 从您的浏览器获得连接,它就会通过防火墙的代理/网关与您的远程服务器建立 TLS 会话。此时,您的客户端会验证您服务器的 PKI 证书,反之亦然。
  3. 一旦与您的远程服务器建立 TLS 会话,stunnel 就会将来自您的浏览器的数据(例如 HTTP 请求或 SSL 隧道请求)通过本地代理并直接传递到您的服务器。这个通道是加密的,所以你的本地网络无法分辨数据包含什么,他们只能通过流量分析来猜测。
  4. 一旦在您的服务器上stunnel运行的实例开始接收数据,它就会打开一个到 eg 的连接,这将是您的 HTTP(S) 代理服务器(在我的情况下为 Privoxy)正在侦听的位置。localhost:8118
  5. Privoxy 然后就像一个普通的转发 HTTP 代理服务器,并通过服务器的 ISP 将您的请求转发到公共 Internet。

涉及的套接字和缓冲区的数量使这种方法的开销非常高,尤其是当您通过代理嵌套 SSL 连接时,它的优点是您的本地网络无法知道您正在通过 SSL 访问哪些站点。我的意思是,它知道您正在访问您的服务器,但除此之外,它不知道您是在访问 Gmail 还是 SuperUser 或其他什么。而且您的本地网关无法过滤或阻止您。