HTTPS隧道

27

在我的工作场所,流量阻塞器/防火墙越来越糟糕了。我无法通过22端口连接到家里的计算机,缺乏ssh访问让我感到沮丧。以前我可以通过将SSH移动到5050端口来使用它,但我认为一些最近的过滤器现在将这个流量视为即时消息,并通过另一个代理重定向它。那是我最好的猜测;无论如何,我的ssh连接现在在我登录之前就中断了。

这些日子里,我一直在使用Ajaxterm通过HTTPS,因为443端口仍然没有被修改,但这远非理想。(差劲的终端仿真、缺乏端口转发、我的浏览器以惊人的速度泄漏内存...)我尝试在mod_ssl上设置mod_proxy_connect,想通过HTTPS发送“CONNECT localhost:22 HTTP/1.1”请求,然后我就能搞定了。不幸的是,这似乎行不通;HTTPS连接起作用,直到我完成发送请求,然后SSL出了问题。看起来,mod_proxy_connect接管了整个连接,而不是继续通过mod_ssl进行管道传输,使HTTPS客户端感到困惑。

有没有办法让它正常工作?我不想通过纯HTTP进行此操作,有几个原因:

  • 留下一个巨大的开放代理是很烂的
  • 一个巨大的开放代理在HTTPS上也不好,但需要身份验证,我感觉还可以
  • HTTP通过代理——我对我的流量被嗅探并不太担心,因为它将通过隧道以“明文”形式传输ssh——但它更容易被篡改,而HTTPS则基本上不能被代理。

要求:

  • 必须在443端口上正常工作,并且不干扰其他HTTPS流量(即我不能只将SSH服务器放在443端口上,因为我将无法再通过HTTPS提供页面)。
  • 我已经或者可以编写一个简单的端口转发客户端,可在Windows(或Cygwin)下运行。

编辑

DAG: 在HTTP(S)上隧道传输SSH被指出,但它并没有帮助:在文章末尾,他们提到Bug 29744 - CONNECT does not work over existing SSL connection 阻止了HTTPS隧道传输,这正是我遇到的问题。此时,我可能需要考虑使用一些CGI脚本,但如果有更好的解决方案,我就不想把它列为要求。


2
最大的原因是我们公司使用的VPN软件只有Windows客户端,所以我不能在家工作(5个盒子中有5个运行Linux,而我不想麻烦地使用虚拟Windows)。我曾经使用ssh进行远程桌面的反向隧道,但现在已经失效了。 - ephemient
他们的评论框太短了,我忘记完成了。他们不喜欢任何人运行未经批准的VPN,即使他们知道人们经常使用WebEx... 耸肩 系统管理员,不能与他们同生共死,也不能没有他们。 - ephemient
这已经不那么重要了,因为现在有一个支持Nortel VPN的vpnc分支,所以我不再需要自己的定制后门。虽然如此,我仍然感到不舒服依赖于vpnc-nortel;它曾经在相同的设置上出现问题,而且如果将来出现问题,我也不知道足够的知识来修复它... - ephemient
一个快速的解决方案是webshell,我经常使用它。 - Tim Post
Apache Bug 29744已在2.4版本中修复。还有一个补丁适用于2.2.22,我将其应用于我的Ubuntu 14.04 LTS构建,仅部署mod_proxy_connect.so。 - Mark
代理隧道失败了,但是一个真正可怕的(echo -ne "CONNECT localhost:22 HTTP 1.1\r\nHost: proxy.fqdn\r\nProxy-Connection: Keep-Alive\r\n\r\n" && cat) | openssl s_client -quiet -connect proxy.fqdn:443 对我来说作为OpenSSH ProxyCommand起作用。 - Mark
13个回答

9
了解为什么公司有这样的限制政策是很重要的,可能是有正当理由。如果你仍然想绕过此政策,可以编写一个小代理程序,在你的服务器上监听443端口,然后根据请求将流量转发到你的Web服务器或SSH守护进程。不过有两个注意点:
1. 为了确定是HTTPS请求还是SSH请求,需要尝试读取一些数据并设置(小)超时,因为TLS/SSL握手从客户端发送一些数据开始,而SSH握手从服务器发送一些数据开始。超时时间必须足够长,以便在TLS/SSL握手中传递初始数据时延迟,因此建立SSH连接会变慢。
2. 如果公司中的HTTP代理比较聪明,它实际上会窃听你连接到443端口时预期的TLS/SSL“握手”,一旦它检测到不是TLS/SSL握手,它可能会终止SSH连接尝试。为了解决这个问题,您可以将SSH守护程序封装到TLS/SSL隧道中(例如,stunnel),但是然后您需要根据客户端请求中的TLS/SSL版本来区分请求,以确定将TLS/SSL连接路由到Web服务器还是TLS/SSL隧道化的SSH守护程序。

这是一个hack,但比我看到的所有其他选项都不那么混乱。感谢提供详细信息,它们将为我节省很多时间! - ephemient
3
最近我发现了 http://www.rutschle.net/tech/sslh.shtml,这是这个想法的一种实现。不幸的是,即使在端口443上运行,防火墙似乎也会向SSH连接注入RST数据包... - ephemient

7
你应该能够使用iptables将工作机器上的ssh流量转发到ssh,而所有其他连接到端口443的家庭服务器的机器都会得到Apache服务器。尝试像这样的规则:iptables -t nat -A PREROUTING -p tcp -s 111.111.111.111 --dport 443 -j REDIRECT --to-port 22,其中111.111.111.111是您办公室电脑的IP地址。这一切都假定您正在运行Linux >= 2.4,到目前为止应该是这样的。它已经出现了近十年了。iptables的文档在http://www.netfilter.org

1
Linux 2.4... 十年... 哈哈!你没有提到他的处理器是否足够强大来运行2.4! - Declan Shanaghy
聪明的想法!我没有想到那个。 - ephemient

6
在家设置OpenVPN 2.1服务器,使用端口443(如果您在家中设置了任何HTTPS服务并将其设置为端口443,请触发OpenVPN的端口共享选项以处理端口443上的OpenVPN和HTTPS事务;此功能仅适用于非Windows操作系统)。
然后,在路由模式下在笔记本电脑上设置OpenVPN客户端,以访问在家中的OpenVPN服务器。您将能够通过使用OpenVPN创建的安全VPN网络在家或任何您喜欢的地方进行通话。这不再需要使用SSH来实现。

嗯,这与已接受的解决方案类似,但它是预先构建的。值得一看。 - ephemient

2

非常抱歉我要站在魔鬼的一边说话,但如果他们在你的工作场所阻止端口,则很可能是因为他们不希望人们违反安全规定。

如果你得到老板的许可打开隧道,那就没问题了。但是,如果发生任何事情,无论什么事情,他们发现你有一个隧道,我几乎可以保证,你会成为替罪羊。因此,如果他们正在设置防火墙来阻止隧道,请不要在工作中打开隧道。


2

您是否考虑在您的计算机上使用两个IP地址?

将Apache/HTTPS绑定到一个IP_1:443,将您的sshd绑定到另一个IP_2:443,如何呢?


很遗憾,我的家用机器只有一个上行链路,而且ISP不提供多个IP地址。虽然成为多宿主将是一件好事:D - ephemient

2

你能设置一个中间人吗?

在云端运行一个小型/免费/便宜的实例,监听443端口的SSH连接,然后通过该云实例隧道到你家里的主机上的22号或其他喜欢的端口。

这可能会增加一些延迟,但它解决了不改变原始家庭设置的问题。


1

由于Apache在没有SSL的情况下对CONNECT没有任何问题,因此我关闭了SSL功能,并使用stunnel提供我的网站的https版本。这不需要重新编译,并允许您的网站正常提供https。到目前为止,这是我知道的最干净的解决方法。

有关详细信息,请参见http://chm.duquesne.free.fr/blog/?p=281


1

我认为你需要找到一个当前未使用的端口,然后监听它。443是显而易见的选择,但你说这不可能。那么邮件(25、110、143)、Telnet(23)、FTP(21)、DNS(53)甚至whois(43)呢?


5050 是我发现的唯一一个既没有被我的 ISP (他们不喜欢开放邮件中继(25),也可能因为其他原因)所阻止,又没有被工作中的防火墙(谁需要除了 HTTP 之外的东西?)所封锁的端口。 - ephemient
在另一个端口上提供HTTPS服务会有多烦人呢?过去我是在443端口上运行SSH服务器,但那时我没有提供其他任何服务(或者更确切地说,我提供了更多服务,但都是通过隧道传输的)。 - Harley Holcombe
对我个人来说,这并不会很烦人,但我不是唯一使用我的家庭服务器的人。我可能可以协调这样的转变,但那更像是最后的选择。 - ephemient
另一个更加万不得已的选择可能是编译自己的Apache。那个Bugzilla页面上有一个补丁可以解决你的问题。这个漏洞已经存在了4年,不确定何时会得到关注。仔细看一下,还有一些mod_proxy.so二进制文件也值得一看。 - Harley Holcombe
关于补丁的评论担心可能存在内存泄漏问题。解决Apache的桶式设计可能会很困难。 - ephemient

1

代理隧道可能是您的答案

http://proxytunnel.sourceforge.net/

假设我的SSH服务器是host.domain.tld,我的工作代理服务器是10.2.4.37。
我会将以下内容添加到我的本地SSH配置文件中:
Host host.domain.tld ProxyCommand /usr/local/bin/proxytunnel -q -p 10.2.4.37:3128 -d %h:%p ProtocolKeepAlives 30

我们的HTTP代理是透明的,我不知道它在网络上的位置。通常他们只允许连接到特定的端口。 - ephemient
运行跟踪路由以查找您的网关,然后转到"What if my ip"网站查看是否匹配。如果不匹配,则下一步是检查响应并查看我们的代理设置中的地址。 - Don-Pierre Halfaway

1

不行:公司使用的是透明代理,而不是你可以发送CONNECT请求的显式代理。此外,问题说明我需要能够继续在443端口上运行HTTPS,而不是被sshd占用。 - ephemient

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接