ssh隧道功能,也就是端口转发功能非常好用,可以实现一些代理功能或者是穿透内网功能。

ssh的端口转发(或者叫做隧道)命令分为三种:

本地:ssh -C -f -N -g -L listen_port:DST_Host:DST_port user@Tunnel_Host

远程:ssh -C -f -N -g -R listen_port:DST_Host:DST_port user@Tunnel_Host

动态:ssh -C -f -N -g -D listen_port user@Tunnel_Host

乍一看有点乱,仔细一分析就更蒙了-_-!

但是再深入的分析了搜索出来的相关的说明和别人的一些分享之后,终于搞清楚了使用方法。下面详细的看各个参数的用法。

-L port:host:hostport

将本地机(客户机)的某个端口转发到远端指定机器的指定端口.

ssh -C -f -N -g -L listen_port:DST_Host:DST_port user@Tunnel_Host

以这个为例,在本地监听一个端口listen_port,把listen_port的所有数据通过Tunnel_Host全部转发到DST_Host:DST_port上去。

-R port:host:hostport

将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口.

ssh -C -f -N -g -R listen_port:DST_Host:DST_port user@Tunnel_Host

远程端口转发,在Tunnel_Host上面监听一个端口 listen_port,把listen_port的所有数据通过Tunnel_Host全部转发到DST_Host:DST_port上去。

DST_Host:DST_port是对于本机来说的,但却是通过Tunnel_Host来访问的,所以Tunnel_Host必须能访问到DST_Host:DST_port,才能进行转发。

举个例子:我在家里和公司各有一台电脑,均没有公网ip,不能互通,但是我有一个有公网ip的VPS,我的两台电脑都可以访问vps,但是vps不能访问我的两台电脑,然后通过公司电脑ssh到vps建立一条隧道,我在家里就可以访问公司里的电脑了。说起来罗嗦的不得了,但是做起来很容易:

在公司的电脑上:ssh -C -f -N -g -R 8080:127.0.0.1:80 root@vps的ip

然后在家里直接访问vps的8080端口,就相当与访问了公司电脑的80端口了,over。

当然80端口只是web端口,我们可以转发22或者3389端口,就可以远程控制公司的电脑了。

-D port

指定一个本地机器 “动态的’’ 应用程序端口转发. 这个动态的就简单了,

ssh -N -f -D 8000 登录名@我的vps的ip

就相当与在本机上开了一个sock代理,端口是8000,给浏览器挂上127.0.0.1:8000的代理,查一下本机ip,发现已经变成vps的ip了。

我的上面用的vps是ubuntu系统,有的时候做了远程端口转发之后发现不能从外面访问,需要修改一下vps上面ssh的一个配置,/etc/ssh/sshd_config,把这个改成yes,如果没这句就加上:

GatewayPorts yes

然后重启sshd。这个作用是把转发的端口绑定在0.0.0.0的接口上,让外部地址也可以访问。

还要注意一点就是listen_port必须是没有被使用的,不然会监听失败。

下面是几个辅助参数,看着乱的话可以忽略,用的时候按需加上就好了。

-C Enable compression.
压缩数据传输。

-f Fork into background after authentication.
后台认证用户/密码,通常和-N连用,不用登录到远程主机。

-N Do not execute a shell or command.
不执行脚本或命令,通常与-f连用。

-g Allow remote hosts to connect to forwarded ports.
在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接。

-p port Connect to this port. Server must be on the same port.
被登录的ssd服务器的sshd服务端口,省略就是默认的22端口。


======================================================

九、本地端口转发

有时,绑定本地端口还不够,还必须指定数据传送的目标主机,从而形成点对点的"端口转发"。为了区别后文的"远程端口转发",我们把这种情况称为"本地端口转发"(Local forwarding)。

假定host1是本地主机,host2是远程主机。由于种种原因,这两台主机之间无法连通。但是,另外还有一台host3,可以同时连通前面两台主机。因此,很自然的想法就是,通过host3,将host1连上host2。

我们在host1执行下面的命令:

  $ ssh -L 2121:host2:21 host3

命令中的L参数一共接受三个值,分别是"本地端口:目标主机:目标主机端口",它们之间用冒号分隔。这条命令的意思,就是指定SSH绑定本地端口2121,然后指定host3将所有的数据,转发到目标主机host2的21端口(假定host2运行FTP,默认端口为21)。

这样一来,我们只要连接host1的2121端口,就等于连上了host2的21端口。

  $ ftp localhost:2121

"本地端口转发"使得host1和host3之间仿佛形成一个数据传输的秘密隧道,因此又被称为"SSH隧道"。

下面是一个比较有趣的例子。

  $ ssh -L 5900:localhost:5900 host3

它表示将本机的5900端口绑定host3的5900端口(这里的localhost指的是host3,因为目标主机是相对host3而言的)。

另一个例子是通过host3的端口转发,ssh登录host2。

  $ ssh -L 9001:host2:22 host3

这时,只要ssh登录本机的9001端口,就相当于登录host2了。

  $ ssh -p 9001 localhost

上面的-p参数表示指定登录端口。

十、远程端口转发

既然"本地端口转发"是指绑定本地端口的转发,那么"远程端口转发"(remote forwarding)当然是指绑定远程端口的转发。

还是接着看上面那个例子,host1与host2之间无法连通,必须借助host3转发。但是,特殊情况出现了,host3是一台内网机器,它可以连接外网的host1,但是反过来就不行,外网的host1连不上内网的host3。这时,"本地端口转发"就不能用了,怎么办?

解决办法是,既然host3可以连host1,那么就从host3上建立与host1的SSH连接,然后在host1上使用这条连接就可以了。

我们在host3执行下面的命令:

  $ ssh -R 2121:host2:21 host1

R参数也是接受三个值,分别是"远程主机端口:目标主机:目标主机端口"。这条命令的意思,就是让host1监听它自己的2121端口,然后将所有数据经由host3,转发到host2的21端口。由于对于host3来说,host1是远程主机,所以这种情况就被称为"远程端口绑定"。

绑定之后,我们在host1就可以连接host2了:

  $ ftp localhost:2121

这里必须指出,"远程端口转发"的前提条件是,host1和host3两台主机都有sshD和ssh客户端。

十一、SSH的其他参数

SSH还有一些别的参数,也值得介绍。

N参数,表示只连接远程主机,不打开远程shell;T参数,表示不为这个连接分配TTY。这个两个参数可以放在一起用,代表这个SSH连接只用来传数据,不执行远程操作。

  $ ssh -NT -D 8080 host

f参数,表示SSH连接成功后,转入后台运行。这样一来,你就可以在不中断SSH连接的情况下,在本地shell中执行其他操作。

  $ ssh -f -D 8080 host

要关闭这个后台连接,就只有用kill命令去杀掉进程。




=======================================================



SSH自动断开连接的原因


方法一:

 

用putty/SecureCRT连续3分钟左右没有输入, 就自动断开, 然后必须重新登陆, 很麻烦.

在网上查了很多资料, 发现原因有多种, 环境变量TMOUT引起,ClientAliveCountMax和ClientAliveInterval设置问题或者甚至是防火墙的设置问题. 所以可以这么尝试:


如果你在windows下通过工具连接,可以设置为
secureCRT:选项---终端---反空闲 中设置每隔多少秒发送一个字符串,或者是NO-OP协议包
putty:putty -> Connection -> Seconds between keepalives ( 0 to turn off ), 默认为0, 改为300.