Contents
  1. 1. ssh端口转发概念
  2. 2. 本地端口转发与远程端口转发
  3. 3. 本地转发实例分析
  4. 4. 远程转发实例分析
  5. 5. 动态转发
  6. 6. 参考资料

ssh端口转发概念

ssh会自动加密和解密所有客户端和服务端间的网络数据,同时ssh提供了一个很有用的功能,就是端口转发。它能够将其他tcp端口的网络数据通过ssh链接来转发,并且自动提供相应的加密和解密服务。这一过程也被叫做隧道(tunneling),这是因为ssh为其他tcp链接提供了一个安全的通道来进行传送得名的。如telnet、smtp和ldap这些tcp应用都能从中获益,避免了用户名、密码和隐私信息的明文传送。而且,如果在某一环境里防火墙限制了一些网络端口的使用,但是允许ssh的连接,那么能够通过讲tcp端口转发给ssh进行通讯。

总结之,ssh端口转发能够提供两大功能:

  • 加密ssh client和ssh server端之间的通讯数据
  • 突破防火墙的限制完成一些之前无法建立的tcp连接

ssh端口转发图

如上图,在使用了端口转发后,tcp端口A和B之间并不直接通讯,而是转发给了ssh客户端和ssh服务端进行通讯,从而实现了数据加密同时绕过了防火墙的限制。


本地端口转发与远程端口转发

ssh分客户端和服务端,应用程序也分客户端与服务端,ssh和应用程序都是用连接方向的,例如ssh是从ssh
client连接到ssh
server,应用程序是从应用客户端连接到应用服务端。如果两者的连接方向是相同的则是本地端口转发,否则是远程端口转发。


本地转发实例分析

譬如本人有个台式机和笔记本,两者通过路由器连接,在笔记本上有shadowsocket翻墙软件,如果这时候我要在台式机上的火狐浏览器要通过笔记本上的shadowsocket来翻墙,该怎么做呢?

答案肯定是本地端口转发,命令格式如下:

1
ssh -L <local port>:<remote host>:<remote port> <ssh hostname>

其中localport是ssh客户端client的端口,可以自定义,在选择端口时要注意非管理员账号是无权绑定1-1023端口的,所以一般是选择一个1024-65535之间的并且尚未使用的端口号即可。remotehost指的是应用程序服务器所在机器,这里指的是我的笔记本,也就是翻墙软件shadowsocket软件所在的主机上,remote port指的是shadowsocket应用程序占用的端口,ssh hostname指的是ssh server 所在的主机,这里指的是我的笔记本。这时在台式机上运行如下命令:

1
ssh -L 1111:localhost:8119 192.168.1.51

这里1111端口是台式机的ssh
client端口,需要把firefox浏览器的代理设置为localhost:1111,ssh hostname为192.168.1.51,上面的localhost指的是192.168.1.51。firefox 浏览器代理设置如下:
firefox 浏览器代理设置


远程转发实例分析

设想有这么种情况,我的笔记本和台式机之间有防火墙,这时只允许从笔记本连接到我的台式机,而不能从台式机上连接到笔记本上,这也就意味着ssh
server和shadowsocket翻墙代理不在同一个主机上,ssh server和ssh
client及firefox和shadowsocket的连接方向相反,这时要实现台式机上的翻墙就要采用远程端口转发了,命令格式如下:

1
ssh -R <local port>:<remote host>:<remote port> <ssh hostname>

在这个例子里,在笔记本命令行上运行一下命令:

1
ssh -R 1111:localhost:8119 192.168.1.28

同时台式机上的firefox浏览器设置和本地端口转发一样。


动态转发

上面讲到的本地端口转发和远程端口转发都有一个固定应用程序服务端口号,例如前面的8119,两个应用程序端对端的交换信息,但是如果没有这个服务器端口怎么办?譬如说用浏览器进行google搜索和使用twitter。
动态转发的命令格式如下:

1
ssh -D <local port> <ssh server>

例如:

1
ssh -D 1111 <ssh server>

动态端口转发图
其实这里ssh是创建了一个socket代理服务器。在shell命令行下运行man
ssh,查看-D选项的描述文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-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
channel, 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.
IPv6 addresses can be specified by enclosing the address in square
brackets. Only the superuser can forward privileged ports.
By default, the local port is bound in accordance with the GatewayPorts
setting. However, an explicit bind_address may be used to bind the
connection to a specific address. The bind_address of ``localhost''
indicates that the listening port be bound for local use only, while an
empty address or `*' indicates that the port should be available from
all interfaces.

参考资料

developerWorks中国网站Linux专区

Contents
  1. 1. ssh端口转发概念
  2. 2. 本地端口转发与远程端口转发
  3. 3. 本地转发实例分析
  4. 4. 远程转发实例分析
  5. 5. 动态转发
  6. 6. 参考资料