SSH协议是一个非常棒的协议,因为他的存在,在互联网上传输才会的安全。

一般在Linux上,ssh客户端程序都会安装,ssh服务端程序不会安装。如果需要安装自己apt或者yum安装一下。

ssh的端口转发给我们带来了很多方便。比如我们在一个公共的WIFI环境或者局域网中,我们的网络包可以被他们截取,有了ssh的端口转发,他们之间会有一个加密的过程,防止被监听。

另外通过ssh端口转发,我们可以访问一些不能访问的网站。想象一下,你处于一个局域网中、或者学校的网络中,那么你的网络无法访问某些网站,此限制看网络管理员是如何限制的。比如在天朝,你无法访问facebook;再或者有些网站会封锁中国的IP,这些通过ssh的端口转发,就可以轻松的访问到。

ssh端口转发

ssh端口转发

根据图例说明:我们用浏览器访问www.google.com,此时浏览器开启了一个端口15453,但是发现在访问到某个节点,此网络包被丢弃了或者返回了错误的信息,导致我们无法访问www.google.com。但是我们想到了另外的一个方法,因为我们发现我们可以访问proxy.remotehost.com,而且他可以访问google.com,因此我们利用proxy.remotehost.com来做一个跳转。

因此我们利用的ssh的动态端口转发技术来达到这个目的。通过命令,我们在本地开启了一个7070端口,并且将7070端口关联到了proxy.remotehost.com的22号端口上。通过对浏览器设置,将所有的请求都转发到127.0.0.1:7070上,通过ssh的隧道,会将数据包传递到了proxy.remotehost.com:22。proxy服务器会随机开启一个端口去访问google.com。然后将数据在返回给proxy,再返回给浏览器。这就是一个代理转发的一个过程了。

下面我来看看如何具体的操作。

基本的动态端口转发

首先在我们的机器运行一下命令,先开启本机的7070端口到远程的22号端口的连接。

ssh -D 7070 -l username proxy.remotehost.com

参数说明:

  • -D 7070 -D [bind_address:]port D参数说明我们开启一个本地的端口转发。通过在本地分配一个socket去监听端口。只要有连接请求到这个port上来时,这个连接就会被安全通过给转发出去,应用程序的协议将有远程机器来决定连接到哪里。目前支持SOCKS4SOCKS5协议,ssh会扮演一个SOCKS5服务器。另外只有root用于才能转发原始端口。
  • -l username 小写字母l参数指定了登录ssh服务器的用户名
  • proxy.remotehost.com 指定了我们需要登录的远程ssh服务器。默认使用ssh程序的指定端口,一般是22号端口,除非系统做了修改

通过这一个命令,再配合一下浏览器的设置,我们就能访问被封锁的网站了。但是不能太高兴了,还是有些问题的。

帐号一登录成功就被退出了?

我的帐号在输入密码成功后,就被强制退出了,这样不就不能进行动态端口转发了吗?

其实这情况很容易解决,因为你的帐号被远程服务器做了手脚了,ssh服务器禁止这个帐号登录请求shell终端了,不能执行远程命令。目的是防止你登录他的系统进行命令的操作。一般专门用于代理的帐号都做了这个限制。

这个时候我们就需要增加一个参数-N来解决这个问题了。

ssh -D 7070 -l username proxy.remotehost.com -N

-N 参数是不请求一个shell界面,不执行远程命令。这个在只是端口转发的时候非常实用(只能在SSH2协议下工作,现在一般都是SSH2协议了,SSH1协议有安全问题,基本不用了)

让这个端口转发连接后台运行

如果只是上面的命令,在登录成功后,你是无法在当前的shell终端中进行任何的操作的,此时你想要干其他的事情只能再起一个端口了。

通常这个是没有意义的,放一个无用的窗口在那边,我们可以增加一个-f参数,让这个连接在后台运行

ssh -D 7070 -l username proxy.remotehost.com -Nf

这样我们就可以用当前的shell终端继续工作了。或者弄一个开机自动运行的脚本,开机自动连接。

给ssh连接增加http代理

如果你的PC无法直接访问到ssh服务器上,但是只有http代理可以访问,那么我们要建立这个socks5的动态端口转发只能为他加上一个代理了。

ssh -D 7070 -l username proxy.remotehost.com -Nf -o ProxyCommand="connect -H web-proxy.oa.com:8080 %h %p "

加上了-o ProxyCommand="connect -H web-proxy.oa.com:8080 %h %p "这个参数,就让我们的ssh连接建立在了一个http代理上了,这个应用对于在公司内网里面非常实用。

其中ProxyCommand指定了使用connect程序来进行代理。通常还可以使用corkscrew来达到相同的效果。

附connect的安装。

如果你是Ubuntu或者Debain系列的使用

sudo apt-get install connect-proxy

如果你是Ubuntu、Debain系列没找到源或者是Centos系列的,需用从下面去访问下载http://pkgs.org/download/connect-proxy。寻找一个适合你系统的包下载下来。

rpm -ivh connect-proxy-1.93-2.el6.x86_64.rpm
或者rpm -Uvh connect-proxy-1.93-2.el6.x86_64.rpm

一段时间没动作,连接自动断开了

一段时间没有发送消息,就出现了

Write failed: Broken pipe

这样的情况,这样的情况就是因为长时间没有发送消息,此隧道被关闭了。

因此我们需要设置一下ssh,让其每隔一段时间就发送一些消息,想服务器说明我还活着,不管关闭了我们的连接。

ssh -D 7070 -l username proxy.remotehost.com -Nf -o ProxyCommand="connect -H web-proxy.oa.com:8080 %h %p " -o ServerAliveInterval=60

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: Linux下ssh动态端口转发 – https://www.chenyudong.com/archives/linux-ssh-port-dynamic-forward.html