SSH 端口转发

来源:互联网 发布:中国联合网络通信市分 编辑:程序博客网 时间:2024/06/05 17:03

所谓端口转发就是将本来发往某个目的地的数据包转发到其他的地址和端口上。其实这个是很常见的应用,包括外网要访问局域网内部的机器都要用到端口转发,只是我以前没注意到ssh也可以干这事。端口转发分为本地端口转发和远程端口转发两种,其实两者大同小异,只是ssh建立连接的方向不一样。为了以后方便讨论,现假设有三台主机A,B,C,主机名分别为hosta,hostb,hostc。

本地端口转发

本地转发中的本地是指将本地的某个端口转发到其他主机的某个端口,这样当我们的程序连接本地的这个端口时,其实间接连上了其他主机的某个端口,当我们发数据包到这个端口时数据包就自动转发到了那个远程端口上。本地端口转发的ssh命令格式如下:

ssh -L [bind_address:]port:host:hostport hostname

Linux manual解释如下:

Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side. 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 a connection is made to host port hostport from the remote machine. Port forwardings can also be specified in the configuration file. IPv6 addresses can be specified with an alternative syntax:[bind_address/]port/host/hostport or 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.

可知运行上面命令后ssh会在本地主机监听端口port,如果有一个指向该端口的连接就将其转发的主机host的hostport端口上,hostname是用于转发的中间主机,它可以和host一样也可以不一样。事实上,运行这条命令之后,本地主机的ssh客户端会连接上hostname主机上的ssh服务器端,通过这条链路将到本地端口的连接转发的host主机的hostport端口上。所以本地主机到hostname主机的通信是安全的,因为这两者是通过ssh连接的,然而从hostname到host的通信是不安全的,这点需要注意。另外本地端口绑定的地址是可选的,即可以指定该端口接收连接来自的网络接口,如果不指定则根据配置的GatewayPorts选项确定:如果该选项为yes则其他主机上程序可以连上该本地端口,否则只能使用回环接口,即只有本主机上的程序能连上该端口。如果指定了绑定地址则无视GatewayPorts选项。 
例如我现在想将主机A的1132端口通过主机B转发到主机C的21端口(ftp默认端口)上。要用本地端口转发在主机A上运行如下命令:

ssh -L 1132:hostc:21 hostb

这条命令之后所有发向主机A上1132端口的连接好像都变成了与主机C上21端口的连接。

同样地,我可以不通过中间主机B,而用ssh直接连上主机C进行端口转发,在主机A上运行如下命令:

ssh -L 1132:hostc:21 hostc

这条命令和上一条效果是一样的,都是将端口转发到主机C,区别在ssh连接的是哪个主机。之所以第一条命令要先连上主机B作为中转是因为在有些情况下主机A和主机C无法连通,而主机A和主机B可以连通,同时主机B可以和主机C相连,这时就可用ssh先连上主机B再通过其转发端口,这样我们就可以在无法连上主机C的情况下也可以使用主机C的ftp服务。如下图所示,这种情况下主机A和主机B之间就形成了一条ssh隧道,在这条隧道中数据传输时加密的,所以不用担心传输内容被诸如防火墙之类的屏蔽。因此本地端口转发的一大用处就是在局域网内部通过建立一条到外网主机的ssh隧道,以此来访问被局域网网关屏蔽的外部服务。

远程端口转发

与本地端口转发相对的是远程端口转发。与本地转发不同,它指定的是远程主机的一个端口,将指向该端口的连接转发到本地端(不一定是本机)。可知远程转发和本地转发本质上是一样的,主要区别在于需要转发的端口是在远程主机上还是在本地主机上。远程端口转发ssh命令格式如下:

ssh -R [bind_address:]port:host:hostport hostname

Linux manual解释如下:

Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side. This works by allocating a socket to listen to port on the remote side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to host port hostport from the local machine.

Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only when logging in as root on the remote machine. IPv6 addresses can be specified by enclosing the address in square braces or using an alternative syntax:[bind_address/]host/port/hostport.

By default, the listening socket on the server will be bound to the loopback interface only. This may be overriden by specifying a bind_address. An empty bind_address, or the address‘*’, indicates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server’s GatewayPorts option is enabled (see sshd_config(5)).

在这里要转发的端口port是在远程主机hostname上,将指向该端口的连接转发到本地端的主机host的hostport端口上,此时ssh会在远程主机hostname的port端口上监听到来的连接。同本地转发一样,这里也可以指定远程转发端口绑定的地址,但与本地转发不同的是只有在远程主机配置中将GatewayPorts 选项设为yes绑定的地址才有效,否则就算设置了绑定地址该端口也只会接收来自回环接口的连接。

比如我现在在主机A上想要将主机B的1132端口转发到本机的22端口(ssh默认端口)上,则在主机A上运行ssh命令如下:

ssh -R 1132:127.0.0.1:22 hostb

该命令执行之后主机A的ssh客户端向主机B的ssh服务器端建立一条连接,而后所有指向主机B上1132端口的连接都会转发到主机A的22端口,如下图所示。我现在可以在主机B上运行如下命令:

ssh -p 1132 root@127.0.0.1

这样就相当于我远程登录了主机A,所以远程端口转发可以用来从外网访问局域网内部的服务。

ssh还有两个选项与上诉端口转发命令一起使用。

-N选项:指示当前ssh连接上服务器端之后不执行远程命令。

-f选项:指示当前ssh命令在后台执行



原创粉丝点击