做隧道里的鱼: ssh 端口转发

工具 2021-03-30 2843 字 1505 浏览 点赞

起步

很惭愧,用 linux 也有好长一段时间了——至少 2 年以上,但在 ssh 命令上只会浅显的登陆而已,直到才不久领略了它的强大。基于 ssh 建立的安全通道,可使你在多个不同网段间来回穿梭(当然有前提),恍若化身游鱼,在隧道里自在。这种比喻很抽象,后面会让你体会到。所以了,明明网上关于 ssh 端口转发的文章很多,干嘛要自己写一篇呢?

我希望用我以为容易理解的方式写出来。

本地端口转发

如果你使用过云服务器,你就会晓得一般云服务器只对外暴露 22 端口,如果你要访问 3000 端口,对不起,请去安全组添加访问规则。我就想临时访问一下也这么麻烦吗?是的,就要这么麻烦

当然不必,我们只需要把云服务器上的 3000 端口映射到本地的某个端口即可,一条 ssh 命令就能做到。命令如下:

ssh -L [host1:]port1:host2:port2 remote_host

host1 是本地 ip,一般省略掉,port1 是“本地的某个端口”;host2 和 port2 表示哪个主机上的哪个端口要映射;remote_host 是跳板机的 ssh 连接信息。

现在我要想把云服务上的 3000 端口映射到本地 4000 端口,命令应该这么敲:

ssh -L 4000:localhost:3000 root@remote_host -p 22

# 如果你的跳板机 sshd 监听 22 端口,可以省略 -p 22;否则必须加上 -p 指定跳板机端口

因为需要映射的端口在建立连接的跳板机上,所以 host2 为 localhost。这也就说明了,如果 host2 能访问到 host3 上的 port2 端口,ssh -L 就也能把 host3:port2 映射到本地某个端口上。即:

ssh -L 4001:remote_host3:3000 root@remote_host -p 22

# 要求,在跳板机 remote_host 上,可以访问到 remote_host3:3000

下图是一位国际网友的生动绘画,很形象的解释了本地端口转发,请好好领悟。

Local Port Forwarding|460*350

远程端口转发

试想,如果我想用家里的电脑访问公司里的电脑,我可以做到吗?大概率不行,因为两台电脑在不同局域网中,ping 都 ping 不通,肯定访问不了。

但如果我有一台云服务器呢?我只需要把公司里的电脑(在局域网 A 中)的 22 端口映射到云服务器的 port1 端口上,再把这个端口映射到家里的电脑(在局域网 B 中)port2 端口上。完成前述操作,只需要在家里的电脑上执行 ssh root@127.0.0.1 -p por2 就可以直接登录到公司电脑上了。

“把云服务器上的端口映射到家里的电脑上”,这就是一个本地端口转发,已经会了。将本地端口映射到云服务器上,只需要有如下命令即可:

ssh -R [host1:]port1:host2:port2 root@remote_host -p 22

ssh -L 刚好相反,host1 一般省略,port1 表示云服务上的 port1 端口,host2、port2 表示本地的哪个主机上的哪个端口。

执行 ssh -R 命令时,我就是需要把正在操作的机器上的 22 端口映射到云服务器的某个端口,所以 host2 为 localhost,port2 为 22,完整如下:

ssh -R 2222:localhost:22 root@remote_host -p 22

同理,如果执行 ssh -R 的电脑上可以访问到 host3:22,那我也能直接将 host3:22 映射到云服务器上:

ssh -R 2222:host3:22 root@remote_host -p 22

网友绘图如下:
Remote Port Forwarding|460*350

一些有用的参数

如果只是执行 ssh -L xxxssh -R xxx ,执行之后的界面就像是普通的 ssh 登录后的样子。我们可以加一些参数:

  • -C 要求传输压缩数据。
  • -N 不执行远端命令,只用来端口转发。
  • -T 关闭 pseudo-terminal 分配。
  • -f 登录成功之后转到后台执行。
  • -n 重定向 stdin 到 /dev/null,配合 -f 后台任务。

也就是说,你可以:ssh -CNTfnR xxx 或者 ssh -CNTfnL xxx

此外,关于 ssh 还有一个常用的小技巧是 -t,强制分配 pseudo-terminal。可以认为 -t 后面接的是要执行的终端命令,表示:登陆上某台机器后,在这台机器上执行指定的命令,命令结束后退出登录。例如:

ssh root@host -p 22 -t ls

我曾在 零基础手动搭建 k8s 那点事: 访问 dashboard 中使用过 -t,文中有详细介绍当时的使用背景。

感谢



本文由 Guan 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论