zoukankan      html  css  js  c++  java
  • ssh动态转发小记

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

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

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

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

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

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

    八、绑定本地端口

    既然SSH可以传送数据,那么我们可以让那些不加密的网络连接,全部改走SSH连接,从而提高安全性。

    假定我们要让8080端口的数据,都通过SSH传向远程主机,命令就这样写:

      $ ssh -D 8080 user@host

    SSH会建立一个socket,去监听本地的8080端口。一旦有数据传向那个端口,就自动把它转移到SSH连接上面,发往远程主机。可以想象,如果8080端口原来是一个不加密端口,现在将变成一个加密端口。

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

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

    -D [bind_address:]port
    Specifies a local “dynamic” application-level port forwarding. This
    works by allocating a socket to listen to port on the local side,
    optionally bound to the specified bind_address. Whenever a connection
    is made to this port, the connection is forwarded over the secure chan‐
    nel, and the application protocol is then used to determine where to
    connect to from the remote machine. Currently the SOCKS4 and SOCKS5
    protocols are supported, and ssh will act as a SOCKS server. Only root
    can forward privileged ports. Dynamic port forwardings can also be
    specified in the configuration file.

    这里关键在于说明了,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:

    sudo nylon -p 10800 -f -vvvvv

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

    nylon: (localhost:51241 <=> tb-in-f94.1e100.net:https) Terminated connection
    nylon: (localhost:51237 <=> tb-in-f199.1e100.net:https) Terminated connection
    nylon: Connecting localhost:51505 <=> ec2-75-101-145-14.compute-1.amazonaws.com:http
    nylon: Connecting localhost:51504 <=> ec2-75-101-145-14.compute-1.amazonaws.com:http
    nylon: Connecting localhost:51510 <=> 203.208.36.26:http
    nylon: Connecting localhost:51514 <=> 203.208.46.218:http

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

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

    ssh -D 8192 abc@localhost

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

    满意收工睡觉了 。。

  • 相关阅读:
    前端之JavaScript
    前端之CSS
    前端之HTML
    编程总结
    线程
    锁机制,信号机制,事件机制
    并发编程
    struct
    linux查看端口
    vue页面跳转传参
  • 原文地址:https://www.cnblogs.com/wellbye/p/3163966.html
Copyright © 2011-2022 走看看