目录

SSH端口转发

SSH 端口转发又称为 SSH 隧道,是通过 SSH 协议建立隧道,实现本地主机和远程主机的端口绑定,数据由 SSH 协议进行加密传输。

SSH 有三种端口转发模式:

  • 本地端口转发(Local port forwarding);
  • 远程端口转发(Remote port forwarding);
  • 动态端口转发;

本文介绍 SSH 的这三种端口转发和持久化工具 autossh。

本地端口转发

SSH 绑定本地端口,将本地端口的访问转发到远端。使用 -L 参数,格式为 本地端口:目标主机:目标主机端口

假设本地主机为 host1,host1 能够访问 host2, host2 能够访问 host3,但 host1 无法直接访问 host3。

在 host1 上执行:

1
ssh -L 8888:host3:8000 host2

表示绑定本地 8888 端口,该端口的访问流量会由 host2 转发至 host3:8000 端口。

在 host1 上执行:

1
ssh -L 8888:localhost:8000 host2

表示绑定本地 8888 端口,该端口的访问流量会转发至 host2:8000 端口。注意目标主机的 localhost 指的是目标主机本身。

本地端口默认绑定到 localhost,只能本地访问,若要可以外网访问(绑定 0.0.0.0),可以写成:

1
ssh -L :8888:host3:8000 host2

远程端口转发

SSH 绑定远程端口,将远程端口的访问转发到本地。使用 -R 参数,格式为 远程主机端口:目标主机:目标主机端口

SSH 远程端口转发非常适合用来做内网穿透。假如 host1 是公网主机,host2 是内网主机且能够访问公网,host3 是内网主机不能访问公网,但 host2 可以访问 host3。如果要从 host1 访问 host3,可以用 host2 中转。

在 host2 上执行:

1
ssh -R 8888:host3:8000 host1

表示绑定 host1 的 8888 端口,该端口的访问流量会由 host2 转发至 host3:8000 端口。

在 host2 上执行:

1
ssh -R 8888:localhost:8000 host1

表示绑定 host1 的 8888 端口,该端口的访问流量会转发至 host2:8000 端口,注意目标主机的 localhost 指的是本地主机(发起 SSH 连接的主机)。

远程端口也是默认绑定到 localhost,若要外网访问(绑定 0.0.0.0),需要修改远程主机的 /etc/ssh/sshd_config 配置:

1
GatewayPorts yes

记得重启 sshd 服务:

1
systemctl restart sshd

动态端口转发

上述两种端口转发都是固定端口对固定端口的转发。动态端口转发不必指定端口号,可以将本地任意端口的流量转发到 SSH 远端。

动态端口转发使用 -D 参数,参数为 绑定地址:绑定本地端口。SSH 会启动一个 SOCKS 服务器监听该地址和端口,当使用该端口作为 SOCKS 代理时,请求的流量会被转发到远端。

例如在 host1 上执行

1
ssh -D 8000 host2

则在 host1 的 Firefox 中指定 localhost:8000 作为 socks 代理时,可以直接访问 host2 能够访问的主机和端口。

SSH 的其他参数

  • -N 只连接远程主机,不打开远程 shell;
  • -T 不为这个连接分配 TTY;

这两个参数可以一起使用,代表这个 SSH 连接只用来传输数据,不执行远程操作。

  • -f 表示 SSH 连接成功后,转入后台运行。

autossh

SSH 连接可能会意外断开或 hang 住,用进程监控工具,并不能有效检测到 hang 住的情况,autossh 就是为了解决这个问题。

autossh 会启动一个 SSH 进程,并实现一个端口转发循环,当发现进程死掉或者端口转发循环的流量停止时,会重启 SSH 进程,有效避免了 hang 住导致 SSH 端口转发不可用的情况。

安装:

1
sudo apt install autossh

autossh 命令的参数除了 -M 参数(用于手动指定端口转发循环的端口)外,其他参数与 ssh 命令相同,并会把这些参数传递给监视的 SSH 进程。

所以一个稳定的 SSH 远程端口转发的命令可以是:

1
autossh -NT -R 8888:localhost:8000 host1

可以将 autossh 与 supervisor 等进程管理工具配合使用,建立长期稳定的 SSH 端口转发。

参考