找回密码
 立即注册
搜索
查看: 202|回复: 0

利用SSH实现穿越防火墙的IP隧道

[复制链接]

2

主题

5

回帖

9

积分

新手上路

积分
9
发表于 2003-3-31 15:09:33 | 显示全部楼层 |阅读模式
说明:

介绍如何利用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 进行了端口映射)。

总之,类似上面的问题会出现在任何多端口转移时的情况。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|海浩社区

GMT+8, 2025-9-21 07:46 , Processed in 0.075913 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表