ssh,一般常用来做远程登录管理,也就是连上远程机器,得到一个shell,然后交互式地在上面敲命令-看结果-再敲命令。

偶尔也会用在脚本里,做些自动化批处理上传下载的操作,但本质上也是用shell来执行一个字符串命令。

但是,ssh还有一个很重要的功能,即端口转发,这个功能更偏向于为其它程序提供服务,而基于shell的功能则可认为是更偏向于为人服务。

端口转发有三类:本地转发,远程转发,动态转发。

其中本地转发和远程转发并没有本质区别,都是在“localip:port”和"remoteip:port”之间建立安全的ssh连接,之外的事情则由请求建立此连接的应用程序自理。两者的区别仅在于是谁先向谁发起连接请求。一般来说都是会从本地发起,但如果远端处于内网防火墙里,那么就会类似ftp被动模式那样,由远端主动发起,这就叫所谓远程转发了。总之这两个术语的名字并不能很好的顾名思义,如果改为“本地发起的转发”和“远程发起的转发”可能更准确些。

动态转发则不一样,ssh本身不再仅是连接提供者了,它其实还承担了socks服务器的作用,这一点其实需要认真理解,而且在网上搜索看到的资料很少有讲清楚的,比如这一篇:(来自http://www.ruanyifeng.com/blog/2011/12/ssh_port_forwarding.html)

这个解释是很迷惑的,因为它没有说清楚数据到底发给了谁。在这里我们根本没有指定远程接收者,如果说接收者就是sshd自身的话那也很难理解,作为一个通用连接,收到的数据可能是任意格式协议的,都发给sshd有什么用它怎么处理呢?

其实还是看标准手册就有清楚的解释了:

这里关键在于说明了,sshd会根据收到的数据去猜测实际上这些数据要发给谁。怎么猜测呢?那当然是要事先规定好数据的格式的,也就是上面提到的socks协议格式。

可见,动态转发实际是指socks转发,也就是说sshd除了验证服务器这个第一身份外,其实还兼职当了socks服务器。这就又涉及到对socks协议的理解。于是我又bg了一把,大致了解如下:

socks是一个做代理转发的协议,socks服务器默认在1080端口监听,socks客户端连上后发接头暗号05 01 00,服务器则回05 00,表示对接成功。客户端再把目标ip:port发过去,服务器连上目标后,把它自己所用的port发回来。然后客户端就去连这个port,连上后正常收发数据,就像跟真正的目标在通信一样了,背后全是socks服务器在倒腾数据。socks协议有两个版本,socks4只支持tcp,socks5支持udp。

这样的话就很清楚了,也就是说sshd本身就是个socks服务器,用-D port host方式建立的动态转发连接,这个port实际是给socks客户端用的,并不是任何程序都能随便开个动态转发乱发数据。而socks协议本身通过转代理转发,(在接头通过后)以黑盒形式支持任何协议,这也许才是“动态”转发的含义吧!

-----------以下是做个实验测试--------------

首先,装一个正常的socks服务器,用来验证下socks客户端,比如浏览器的代理模式。

port search socks可以得到一堆与socks协议有关的软件,这里选择nylon做为server来测试。必须承认这个名字取得相当有才。。socks在此本意为缩写但原词却是袜子的意思,于是这作者给他写的服务器取名nylon,来个尼绒袜子,真绝配!

以前台应用模式(默认是后台服务)启动nylon:

可以看到有提示打出,预料每当有连接进来,都会打出新提示,下面在chrome里做测试,刚好装了goagent插件,在里面添加一个代理模式,将socks代理选项设为127.0.0.1:10800,并切换到该模式,再去打开网页,果然,随着网页刷出,nylon的控制台上也刷出了log:

用ctrl-c将其关闭后再刷浏览器,提示代理不通,证实刚才确实通过nylon做了socks代理访问。

现在试试sshd兼职的socks服务怎样。直接以本机做server测试即可:

在chrome里修改代理端口为8192再一刷,刚才不通的网页又打开了,证实sshd兼职socks server确实有用!

满意收工睡觉了 。。

05-18 18:58