ssh隧道技术


什么情况下使用隧道

  1. 公司为了防止我们用XX软件封锁了它的端口或者服务器地址。
  2. nat穿越,或者叫ssh反向隧道访问内网的pc,比如:在家里访问我在公司的电脑。


通过在外网一个ssh服务器做代理,实现穿越功能。
我主要使用第二种功能,在家里访问公司的电脑。可以远程办公了。


建立本地隧道

建立本地隧道实现第一种隧道模式。
假设内网机子A要访问C,但被拒绝了,这样可以通过中间的B建立ssh本地隧道实现A-B-C的访问。
实际上这种一般不太常用,毕竟有很多代理服务器都可以方便实现代理功能。


在A上执行:


ssh -N -f -L 2121:C:21 B
ftp localhost:2121 # 现在访问本地2121端口,就能连接C的21端口了
这里我们用到了SSH客户端的三个参数:
-N 告诉SSH客户端,这个连接不需要执行任何命令。仅仅做端口转发
-f 告诉SSH客户端在后台运行
-L 做本地映射端口,被冒号分割的三个部分含义分别是
需要使用的本地端口号
需要访问的目标机器IP地址(IP: 234.234.234.234)
需要访问的目标机器端口(端口: 21)
最后一个参数是我们用来建立隧道的中间机器的IP地址(IP: 123.123.123.123)


我们再重复一下-L参数的行为。
-L X:Y:Z 将IP为Y的机器的Z端口通过中间服务器映射到本地机器的X端口。


在这条命令成功执行之后,我们已经具有绕过公司防火墙的能力,并且成功访问到了我们喜欢的一个FTP服务器了。


通过SSH隧道建立SOCKS服务器

如果我们需要借助一台中间服务器访问很多资源,一个个映射显然不是高明的办法。
幸好,SSH客户端为我们提供了通过SSH隧道建立SOCKS服务器的功能。


通过下面的命令我们可以建立一个通过123.123.123.123的SOCKS服务器。
ssh -N -f -D 0.0.0.0:1080 123.123.123.123 # 将端口绑定在0.0.0.0上
通过SSH建立的SOCKS服务器使用的是SOCKS5协议,在为应用程序设置SOCKS代理的时候要特别注意。


建立远程SSH隧道

现象我想在家里访问公司内网的电脑,这时从外到内访问显然是不行的,但从公司内往外访问是正常的。
所以就是用远程ssh隧道,先通过内网ssh到B,然后通过访问B的端口就可以访问内网的A了。


在A上执行:
ssh -N -f -R 2222:127.0.0.1:22 B
现在,在B机器上我们用下面的命令就可以登陆公司的A机器了。
ssh -p 2222 localhost


我们现在重点说说参数-R。该参数的三个部分的含义分别是:
远程机器使用的端口(2222)
需要映射的内部机器的IP地址(127.0.0.1)
需要映射的内部机器的端口(22)
例如:-R X:Y:Z 就是把我们内部的Y机器的Z端口映射到远程机器的X端口上。


实际上这里所说的本地隧道和远程隧道(-L,-R),实际上指的是ssh代理listen的端口在本地还是在远端。
如果在本地listen就是本地隧道,如果要是在远端listen一个端口就是远端隧道。


一些技巧

检查隧道状态

有些时候隧道会因为一些原因通信不畅而卡死,例如:由于传输数据量太大,被路由器带入stalled状态。这种时候,往往SSH客户端并不退出,而是卡死在那里。一种应对方法是,使用SSH客户端的ServerAliveInterval和ServerAliveCountMax选项。ServerAliveInterval会在隧道无通信后的一段设置好的时间后发送一个请求给服务器要求服务器响应。如果服务器在ServerAliveCountMax次请求后都没能响应,那么SSH客户端就自动断开连接并退出,将控制权交给你的监控程序。这两个选项的设置方法分别是在ssh时加入-o ServerAliveInterval=n和-o ServerAliveCountMax=m。其中n, m可以自行定义。


如何将端口绑定到外部地址上

使用上面的方法,映射的端口只能绑定在127.0.0.1这个接口上。也就是说,只能被本机自己访问到。如何才能让其他机器访问这个端口呢?我们可以把这个映射的端口绑定在0.0.0.0的接口上,方法是加上参数-b 0.0.0.0。同时还需要打开SSH服务器端的一个选项-GatewayPorts。默认情况下它应当是被打开的。如果被关闭的话,可以在/etc/sshd_config中修改GatewayPorts no为GatewayPorts yes来打开它。


自动连接和防断线脚本

Linux平台ssh默认不支持把密码作为参数,不过有sshpass可以搞定


http://sourceforge.net/projects/sshpass/files/latest/download


下载,解压,编译,把可执行文件拷贝到合适的目录,执行命令格式如下:


sshpass -p "password" ssh -D 7070 user@serverip


貌似ubuntu下可以直接apt-get install sshpass


然后写脚本autossh.sh,内容如下:



#!/bin/bash
while [ '' == '' ]
do
 ssh_d_process_num=`ps aux|grep -E 'ssh \-' |grep -v grep |wc -l`
 if [ "$ssh_d_process_num" == "0" ]; then
  /home/user/sshpass -p "password" ssh -D 7070 user@ServerIP &
 fi

 sleep 300
done
执行一下这个脚本就可以了。sleep 300代表300秒查看一次,可以根据需要调整。

动态域名

花生壳linux程序下载地址:
http://www.oray.com/peanuthull/download\_linux.php