|
说明:
介绍如何利用SSHD实现Internet范围内任意机器间的TCP连接。本文根据实际操作整理,供诸位参考。有关ssh的详细命令选项解释,请参考SSH帮助和手册。
实验目标:
1。实现从Internet上访问NAT路由器后面的上网PC上的服务,如HTTP, Real Helix Server, FTP等服务。
2。实现Internet范围内的PCAnywhere远程监控
3。实现两台上网PC机间基于TCP的任意端口的直接连接,例如双人对战的游戏。
环境:
需要一台有公开IP地址的Linux/Unix服务器运行SSHD。
配置时需要在该主机上有 root 访问权限,配置完成后则仅需要一般帐号权限(不必登录主机)。
实验环境: Linux 2.4.19 (Mandrake)
方案:
SSH支持两种 IP Forwarding,一种是Local 方式,另一种是 Remote方式。
在PC机一段(需要安装 OpenSSH,或者 Cygwin)运行
C:\>ssh -R 40080:localhost:80 host -l user
即可让主机监听 40080,将对该端口的连接请求转发给 localhost:80,即PC机上的80端口,而本地web服务器对localhost:80的数据报文等也会经主机传送到客户端。
上述SSH进程不退出,则该连接一直有效。
具体操作和说明:
1。缺省情况下, sshd 在进行 -R 模式的IP Forwarding时,只会允许来自本机对监听端口的连接请求,并拒绝来自外部地址的连接请求。需要在 sshd的配置文件上进行有关设置,使sshd能够转发来自其它主机的连接请求。
在 /etc/ssh/sshd_config 中增加: GatewayPorts yes 一行,然后重新启动 sshd 服务即可。
技术细节:如果没有在 sshd_config 中增加 GatewayPorts yes 一行,可以发现 sshd 仅仅在 127.0.0.1上监听-R 第一个参数指定的端口,而不是在 0.0.0.0上。增加上述配置后,则监听在 0.0.0.0地址上,即运讯来自其它主机对该端口的连接请求。
(找这个参数花了不少时间).
2。-R 参数说明:
-R hostport:forwarded_IP:forwarded_port
其中 hostport 是指sshd将监听的端口,forwarded_IP:forwarded_port 是将要转发的IP地址和端口号。需要注意的是,因为 ssh 命令是在PC机上运行的,因此 forwarded_ip指定为 localhost时,其实是指PC机本机,而不是运行 sshd的服务器。这一点在 ssh 的手册中说的很含糊。当然,在这里也可以将forwarded_ip制定为非本机(即运行ssh的PC机),可以是任意一台本PC机可以通过TCP访问的机器,例如本地局域网的另外一台PC机,或者Internet上的任意一个主机(如果PC机可以通过NAT路由器访问Internet的话).
从技术细节上看,对forwarded_ip:forwarded_port的连接是由 ssh 客户端负责维护的(而不是 sshd 服务器),因此可以是本PC机可以访问任意地址。
例如 c:\>ssh -R 40080:www.ibm.com:80 myhost... 即是告诉myhost主机上的sshd服务器监听其上的 40080端口,将所有数据经过 SSH 通道传到本PC机,然后本PC机上运洗过你的SSH客户端再将所有请求和数据转发到 www.ibm.com:80。 (当然这样做没有太多意义)
3。-L 参数
-L local_listen_port:destination_ip:destination_port
-L 参数刚好和 -R 参数相反。是告诉 SSH 客户端将所有本地端口上的请求通过SSH通道转发给sshd,然后sshd再根据参数将上述数据转发给最终目标地址。
其中 local_listen_port 是 ssh客户端在本机将 LISTEN的端口,而 destination_ip:destination_port则是 sshd 服务器将要转发的目的地址和端口。因此在 -L 2401:localhost:2401 中,第一个2401是本地监听端口,localhost是指相对于sshd服务器的localhost(即其自身),而不是相对于本PC机的localhost.这一点ssh手册中也说得比较含糊。
例如: c:\>ssh -L 40080:www.ibm.com:80 ... 则将所有访问本地 40080 端口的数据和连接请求通过sshd 转发到 www.ibm.com:80 地址。有关 -L 的用google上有大量的例子。可以用于对 POP3, SMTP, CVS, Telnet, FTP...等常用服务提供加密信道。而且大多数情况下,-L参数中的 destination_ip都是localhost,即sshd服务器本身。(因为SSH并不保护从sshd服务器联向其它服务器的数据报)
4。PCAnywhere
PCAnywhere Host 模式时监听 5631/tcp 和5632/udp两个端口(这两个端口均可修改)。
在有全程PC监控需求时,在运行PCAnywhere Host的PC端运行:
C:\>ssh -R 5631:localhost:5631 -e none -N host -l user
C:\>ssh -R 5632:localhost:5632 -e none -N host -l user
在运行 PCAnywhere Remote的PC上,正常启动PCAnywhere,把要监控的PC机的地址改为 host的IP地址即可。
5。两台联网PC机之间任意TCP端口的连接
假设PC1和PC2都经过宽带或者电话拨号上网,它们彼此不知道对方的IP地址。而且由于可能处于不同的ISP的NAT后面,即使知道了对方的IP地址,也可能无法连接。这时可以同时使用SSH的 -L 和 -R 实现任意端口互联。假设某应用要求PC1,PC2均监听3001端口以实现互联。
PC1:
C:\> ssh -L 3002:localhost:8002 host -l user
C:\> ssh -R 8001:localhost:3001 host -l user
PC2:
C:\> ssh -L 3002:localhost:8001 host -l user
C:\> ssh -R 8002:localhost:3001 host -l user
PC1 :3002=====> host:8002 =======> PC2: 3001
PC1 :3001=====< host:8001 <======= PC2: 3002
这样 PC1或PC2只需要向本地 3002端口发起连接请求即可建立到对方3001端口的连接。
6。可利用域名注册服务商提供的免费URL转发服务完成基于家中PC机的网站。例如 www.net.cn 就提供免费的 URL 转发服务。例如在 www.net.cn上定义 http://www.mydomain.com 转发到 http://www.sshdhost.com:5050 (一般在12小时内生效)
在自己的PC上执行以下命令:
C:\>start ssh -e none -N -R 5050:localhost:80 www.sshdhost.com -l user
这样,Internet 用户在浏览器中输入 http://www.mydomain.com 时,就访问PC机上的 Web Server。
备注:
1。本来是要自己写一个软件来完成上述任务的,写起来并不难。但利用现成的总是更有效。
2。市面上有商业化的软件,例如 Dynamic DNS之类的,也有 Reverse Proxy(没有做过实验,不知道在 proxy server与最终 server之间能否增加NAT路由器,即最终server的IP地址对Proxy不可见)等。
Zebedee是个不错的实现安全TCP Tunnel的软件包。Zebedee支持 Linux和Win32。Zebedee的名字来自于其使用的三大技术:Zlib,Blowfish,Diff-Hellman。源代码和binary下载地址 http://www.winton.org.uk/zebedee/
3。由于SSH只对TCP提供转发,要解决UPD的问题,必须利用TCP/IP协议栈更底层的函数进行完成。可参见 http://www.employees.org/~hek2000/projects/firewallTunnel/ (Open Source),由于没有 Windows Client支持,未作实验。
4。Win32 端的SSH软件
最方便小巧的是 OpenSSH。下载地址 http://www.openssh.org . 此外, Cygwin 也内置了全套的 OpenSSH软件包。http://www.cygwin.com
如果仅仅需要对外的IP转发(即仅仅 -L 方式),也可以使用 SecureCRT提供的IP转发功能。
5。SSH隧道的缺点:以 c:\> ssh -R 40080:localhost:80 www.edenventure.com ... 为例,当一个来自Internet的 http://www.edenventure.com:40080 请求到达 sshd 服务器后,sshd将该请求数据发送给PC上的ssh 客户端,ssh客户端根据 -R 参数中的制定目的地址 ( localhost:80) 建立一个 TCP连接。假设在PC机80端口上运行了一个本地的Web服务器,则对于该Web服务器来说,所有的客户都是来自本地的(即 ssh 客户端).因为这里的TCP连接是非透明的。要解决这个问题,需要参考3中的方案。
6。当利用SSH -R 实现多个端口的映射时的注意事项。以本地PC机运行 Real Helix Universal Server为例。该流媒体服务器监听大约20个左右的端口( 80,554,4040,7070,7878,30001-30010,50001-50010等).若想通过这种方式完成利用PC机向Internet用户提供流媒体点播或者直播服务,则需要考虑Helix 的web服务器产生对 554 端口的URL引用时的地址替换。
例如, http://localhost/ramgen/broadcast/tv/cnn 将使得 IE自动启动 RealOne Player,并指导 RealOne Player连接 rtsp://localhost:554/broadcast/tv/cnn 这对于本地用户工作很好。但对于通过 SSH 随但访问的 Internet用户(他们并不知道通过了SSH隧道),他们访问视频服务的URL是 http://www.aaa.com:40080/ramgen/broadcast/tv/cnn ,这个URL是正常的http,可以得到 Helix Web服务器的正常服务,返回的HTTP 包中的MIME参数会使的Internet用户的IE自动启动RealOne Player。但RealOne Player得到的参数仍然是 rtsp://localhost:554/broadcast/tv/cnn (因为在Helix Web Server看来,请求来自本地)。这样Internet用户就无法自动连接到真正有效的地址: rtsp://www.abc.com:40554/broadcast/tv/cnn (假设使用了ssh -R 40554:localhost:554 进行了端口映射)。
总之,类似上面的问题会出现在任何多端口转移时的情况。 |
|