浅谈SSH转发

21

SSH转发(SSH forwarding)又称为SSH隧道(SSH tunneling),是一种通过SSH加密通信协议来传输其他协议数据的技术。它可以让我们在不直接暴露服务端口的情况下,安全地通过SSH连接远程主机,访问那些只能内部访问的服务。

SSH转发主要有三种类型:本地转发(local forwarding)、远程转发(remote forwarding)和动态转发(dynamic forwarding)。

本地转发

本地转发是指将本地计算机上的一个端口转发到服务器上。这种方式比较简单,可以方便地实现本地应用程序与远程服务器之间的通信。例如,我们可以通过本地转发将本地计算机上的Web应用程序映射到远程服务器上,从而实现远程访问。

具体操作步骤如下:

  1. 在本地计算机上使用ssh命令连接到远程服务器:
ssh -N -L [local_port]:localhost:[remote_port] [user]@[server_ip]

其中,-N表示不要执行远程命令;-L表示进行本地转发;[local_port]表示本地端口号;localhost表示 远程服务器 地址;[remote_port]表示远程服务器端口号;[user]表示远程服务器用户名;[server_ip]表示远程服务器IP地址。例如:

ssh -N -L 8080:localhost:80 user@192.168.1.100
  1. 输入密码后,即可建立SSH连接。此时,在本地计算机上打开浏览器输入 http://localhost:8080 就可以访问远程服务器的80端口了。

场景①

主机B与主机C处于同一内网中,主机B能够与外界联系而主机C不能。这时不处于内网中的主机A如果想要访问主机C,就可以通过SSH连接主机B+端口转发来进行。

台式机B上运行着虚拟机C,虚拟机使用虚拟机软件搭建的虚拟网络与宿主主机B相连接,但在主机B以外无法直接访问该虚拟网络。想要通过SSH,用与台式机B处于同一WiFi下的笔记本A来远程控制虚拟机C,(在A上)执行端口转发命令:

ssh -L 22022:10.0.2.15:22 desktop_user@192.168.1.11	# cmd.1-1

其中,22022号端口是随便选的一个没被占用的端口;192.168.1.11是台式机B在WiFi中的IP;desktop_user是主机B上的用户名;10.0.2.15是虚拟机C在主机B为其搭建的虚拟网络中的IP;22号端口是默认的SSH端口。已知virtual_user是虚拟机C上的用户名,这时在笔记本A上执行应用的访问请求命令:

ssh -p 22022 virtual_user@localhost	# cmd.1-2

我们在笔记本A上以SSH协议访问本机(localhost)的22022号端口,这个请求就像通过了隧道(SSH隧道)一样抵达台式机B,台式机B则把这个请求变为对虚拟机C的22号端口的访问,并为A返回结果。其中,使用「-p」旗标是为了访问主机A的特定端口而不是SSH默认的22号端口;由于我们在主机A上执行命令,A管自己叫localhost,假如在其他主机上执行则需相应地改为主机A的域名或IP等他们对A的称呼。

cmd.1-2中我们是将SSH当作普通应用使用的。参考Fig.1,cmd.1-1在A与B之间建立SSH隧道,此时A上的SSH客户端和B上的SSH服务器对应图中的SSH Client和SSH Server;cmd.1-2则表达应用的访问请求,此时A上的SSH客户端和C上的SSH服务器对应图中的application client和application server。

以上cmd.1-1和cmd.1-2合起来实际是想(在A上)进行:

ssh -p 22 virtual_user@10.0.2.15	# cmd.1-3

当然,如果这cmd.1-3能被成功执行的话,就不需要端口转发了。

场景②

防火墙阻止了主机A对主机B一些端口的连接,但主机B仍有部分端口是对主机A开放的。这时主机A如果需要访问主机B上被防火墙阻挡的端口,就可以通过SSH连接主机B+端口转发来进行。需注意,这时所谓的主机C就是主机B。

某某云的云服务器B默认的防火墙设置仅开放了22号端口,其他入方向的访问都被屏蔽了。我们为云服务器B安装了桌面环境,现在想要在自己的计算机A上,通过VNC远程控制云服务器B的桌面。(在A上)执行端口转发命令:

ssh -L 5920:localhost:5901 cloud_user@server.example.com	# cmd.2-1

因为C就是B自己,所以C的位置填localhost;5920随便选;5901是云服务器B上VNC服务进程收听的端口;cloud_user是B上的用户名;http://server.example.com是B的域名,换成公网IP也行。
下面在计算机A上打开RealVNC VNC Viewer(VNC客户端),输入VNC服务器地址:

localhost:20

20=5920−5900,这是采用5901到5999之间端口时RealVNC的特殊设定。开始使用优雅(或许吧)的GUI来操作云服务器吧!

远程转发

远程转发是指将服务器上的一个端口转发到本地计算机上。这种方式更适合于管理或维护服务器时,需要通过SSH连接到服务器并访问特定的服务。

具体操作步骤如下:

  1. 在本地计算机上使用ssh命令连接到远程服务器:
ssh -N -R [remote_port]:localhost:[local_port] [user]@[server_ip]

其中,-R表示进行远程转发;[remote_port]表示远程服务器端口号;localhost表示本地计算机地址;[local_port]表示本地计算机端口号;[user]表示远程服务器用户名;[server_ip]表示远程服务器IP地址。例如:

ssh -N -R 2222:localhost:22 user@192.168.1.100
  1. 输入密码后,即可建立SSH连接。此时,在本地计算机上使用ssh命令连接远程服务器:
ssh -p 2222 [user]@localhost

其中,-p表示端口号。例如:

ssh -p 2222 user@localhost

就可以连接到远程服务器了。

场景③

主机A与主机C处于同一内网中,主机A能够与外界联系而主机C不能。这时(在主机A上)如果想让不处于内网中的主机B访问主机C,就可以通过SSH连接主机B+端口转发来进行。

台式机A上运行着虚拟机C,虚拟机使用虚拟机软件搭建的虚拟网络与宿主主机A相连接,但在主机A以外无法直接访问该虚拟网络。想要通过SFTP,用与台式机A处于同一WiFi下的笔记本B来向虚拟机C传输文件,(在A上)执行端口转发命令:

ssh -R 22122:10.0.2.16:22 laptop_user@192.168.1.233	# cmd.3-1

其中,22122号端口是随便选的一个没被占用的端口;192.168.1.233是笔记本B在WiFi中的IP;laptop_user是主机B上的用户名;10.0.2.16是虚拟机C在主机A为其搭建的虚拟网络中的IP;22号端口是默认的SFTP端口。已知virtual_user是虚拟机C上的用户名,这时在笔记本B上执行应用的访问请求命令:

sftp -P 22122 virtual_user@localhost	# cmd.3-2

请注意这是一条运行在B上的应用命令;B上的SFTP客户端这时充当Fig.2中的application client。此处localhost是主机B对自己的称呼。对B的22122号端口的访问被转发至A,A访问C,即10.0.2.16的22号端口并将结果返回给B。于是B就通过远程端口转发成功访问了C上的SFTP服务器。

以上cmd.3-1和cmd.3-2合起来实际是想(在B上)进行:

sftp -P 22 virtual_user@10.0.2.15	# cmd.3-3

当然,这cmd.3-3也是不能被直接成功执行的。

场景④

处于内网之中的主机A可以访问公网,但不具有公网IP;公网中的主机B无法找到A,但为A开放各个端口的访问(A可以直接连接B,反之则不行)。这时A想要让B访问自己,就可以通过SSH连接主机B+端口转发来进行。需注意,这时所谓的主机C就是主机A。

注意:OpenSSH服务器对于远程端口转发的设定,默认只接受远程主机B本机上的应用发起的请求。想要从其他连接到B的设备发起请求,需将「sshd_config」文件中「GatewayPorts」选项后的「no」修改为「yes」。

手头上计算机A运行着http服务,但A没有公网IP,其他设备不能使用该服务。恰好云服务器B有公网IP(甚至域名),便于被访问。在不将http服务迁移至云服务器B的前提下,可以使用SSH端口转发使其他设备通过访问B的方式访问A上的http服务。(在A上)执行端口转发命令:

ssh -R 80:localhost:80 cloud_user@server.example.com	# cmd.4-1

这时C便是A自己(localhost);80号端口是http默认端口,为简便两个都用默认;cloud_user还是B上的用户名;http://server.example.com还是B的域名。

接下来在其他设备上打开浏览器,输入地址:

http://server.example.com/

于是大家可以通过访问http://server.example.com来访问本地计算机A提供的http服务了。

动态转发

动态转发是指将本地计算机上的所有网络流量都通过SSH连接转发到远程服务器。这种方式比较灵活,可以让我们通过一个安全的通道来访问互联网。

具体操作步骤如下:

  1. 在本地计算机上使用ssh命令连接到远程服务器:
ssh -N -D [local_port] [user]@[server_ip]

其中,-D表示进行动态转发;[local_port]表示本地端口号;[user]表示远程服务器用户名;[server_ip]表示远程服务器IP地址。例如:

ssh -N -D 8080 user@192.168.1.100
  1. 输入密码后,即可建立SSH连接。此时,在本地计算机上设置代理服务器的地址为127.0.0.1,端口号为8080。例如,在浏览器中设置代理服务器为“127.0.0.1:8080”,就可以通过SSH连接安全地访问互联网了。

以上就是SSH转发的三种类型及其操作步骤。需要注意的是,SSH转发需要在安全可信的环境下使用,否则可能会被黑客利用。同时,也需要注意设置好防火墙和其他安全措施,以保护系统和数据的安全。

参考https://zhuanlan.zhihu.com/p/148825449