用ssh打通反向隧道,内网也可对外提供服务

一般正规一点的网络环境,大多是这样的:防火墙后分为内网和中立区(DMZ),并且内网和DMZ虽然都能访问外网,互相却是无法直接访问的。内网和DMZ的区别就是,来自外网的访问,都通过防火墙上的规则映射到DMZ里的服务器上,而内网一般是不允许这样的。

现在需要解决的问题就是,在防火墙只能给DMZ开端口,内网和外网不可直接互访的情况下,如果让内网的机器对外提供服务。

ssh是很神奇的,使用它创建的隧道,可以起到代理的作用,数据流的方向是:

本机 -> 隧道 -> 外网

应用到我们的问题中,如果把隧道反过来,就是:

外网 -> DMZ -> 隧道 -> 内网

这就需要用到ssh的反向隧道,它在服务器上打开一个监听端口,这个端口的访问会被隧道传输到本地,结果再通过隧道传到服务器上,从监听端口返回给客户。这样,在我们的应用中,内网机器通过外网访问DMZ服务器,创建ssh反向隧道,就能够对外提供服务了。当然,防火墙上要将相应端口映射到DMZ的服务器上。

比如,在内网登录DMZ服务器:

ssh -R 8082:localhost:82 fwolf@svr5.tld -o ControlPath=/tmp/ssh_svr5_reverse_tunnel

这样,访问DMZ服务器svr5的8082端口,就是在访问本机的82端口。之所以带上-o ControlPath,是为了和其它访问svr5的进程使用不同的master模式(如果不是第一次创建这个master,而是使用了原来的连接的sockts,肯定就不会创建隧道了)。

有几个问题还需要注意一下:

  • 如果DMZ上监听端口小于1000的话,就必须用root用户登录DMZ服务器,比如root@svr5.tld
  • DMZ服务器上的sshd必须开启GatewayPorts选项,在文件/etc/ssh/sshd_config中加入GatewayPorts yes
  • 记得不要idle,参考中有在服务端设置的方法。
  • 如果放在其它脚本,比如/etc/rc.local中执行的话,除了配置自动登录,还可以带上-fN参数,放到后台去。

参考

Update @ 2008-07-25

注意,由于使用了反向隧道,所以ssh隧道实际作用相当于一个代理,访问的来源也自然就都成了127.0.0.1,如果同时还启用了denyhosts,千万记得要把本机地址127.0.0.1放入白名单/etc/hosts.allow,不然就会成为其他登录失败的牺牲品(失败的登录,其来源也成了loopback的地址):

ssh_exchange_identification: Connection closed by remote host
Fatal error: Lost connection with the server

没办法,为了网络通道的畅通,只能牺牲一部分安全性了。

更安全的原因所在

继续挑战Gregarius中积攒的未读feeds items,已经追到了2007年8月份,6666/17841条未读信息已经减少到3220/21258项:

吉利数字in my Gregarius

今天才看到fcicq的ActiveX 安全控件 = 不安全,不禁在想,到底什么原因导致ActiveX不安全呢?终于,我发现这并不能盲目归咎于微软产品质量不佳或者是ie的缺陷,也不能说是开发人员水平不行或者是不负责任,终极的原因,居然是小众和大众的区别。

简单说来,ActiveX是闭源的,那么真正了解它的完整工作机制的人必然是少数,每个人的智慧都有局限性,引申开来,每个团队也有考虑不到的地方,那么我们就可以认为,ActiveX必然存在着漏洞,并且小众之外的大众看不到、体会不到,甚至发现了一些端倪也无法判断原因出自何处,在无法得到充分、全面的用户检验的时候,维护团队仅靠一些自身质量控制和用户使用方面的反馈,也就有照顾不到的地方了。漏洞有了生存空间,安全性自然下降。更何况,ActiveX的运行平台,Windows以及ie,也具有类似性质,坏的效果往往不是累加而是乘积式的增长。

搞过一点软件开发的人都知道测试的重要性,初级一点的测试就是模仿用户操作,使用一些极限值、便捷值等来对软件进行检测,而高级一些的测试可不是谁都能作的工作,测试人员不仅要会“操作”软件,还要懂得软件实现的原理和机制,必要的时候要去翻文档、源码,来制定测试方案,这样才能找到一些深层次的问题。回到我们说的小众和大众的区别问题上来,当软件有了1000万用户时,可以把这1000万想像为初级测试用户,他们会反馈一些使用中遇到的问题,协助软件更改,这是闭源软件的方式,在开源软件的运作模式中,这些用户里可能会有万分之一的用户出于学习、好奇或进行改进的原因,去翻阅源码,在阅读过程中自然有一定的检查效果,其中的经验丰富精力充沛者还会进行测试、亲手修改,部分类似与高级测试人员的工作。只要施以得当的管理,让这些测试、修改的效果得以发挥,软件的质量及安全性自然会更高一些。

之所以会想到这些,是因为我记得以前微软还是谁在抨击开源软件的质量和安全性的时候提到过,闭源软件是由高素质的开发团队,有严谨的质量控制管理的情况下生产出来的,所以质量更好,安全性更优。我虽然不能全盘否定这一观点,但这么说太片面了。绝对的安全肯定是一个“无穷大”的数字,每一份努力都能够离这个“无穷大‘更近一些。广大人民的力量是无穷的,更不要说为了薪水工作和为了理想信念干活的结果差异了。

其实,小众和大众的影响在其它很多方面有体现:我们在颁布法律或规章的时候,要开听证会,要征集意见,就是要把小众群体起草出来的东西,让大众去检查、补充、完善;我们要讲团队合作,要讲民主,就是要避免小众决策的片面,能力的局限;我们把重要建设项目的方案公开让大家讨论,也是在借助大众的智慧。人多力量大,众人拾柴火焰高,三个臭皮匠还抵个诸葛亮呢,如果谁坚持要说有限的团队就能够生产出完美的产品,我们大可一笑置之。

最后,小众和大众都是相对的概念,应用的范围要适度,服务器的管理员只设一人是不安全的,公司里人人都是管理员也不安全,监狱安防设计图自然也不能搞什么全民共享,那《越狱》就失去大卖点了 :)。真正安全的方式是要绝对经得起推敲、检验的,在这方面,非对称加密如pgp、gpg堪称典范,充分利用公开的机制达到了保密的目的。