SSH端口转发
SSH 端口转发又称为 SSH 隧道,是通过 SSH 协议建立隧道,实现本地主机和远程主机的端口绑定,数据由 SSH 协议进行加密传输。
SSH 有三种端口转发模式:
- 本地端口转发(Local port forwarding);
- 远程端口转发(Remote port forwarding);
- 动态端口转发;
本文介绍 SSH 的这三种端口转发和持久化工具 autossh。
本地端口转发
SSH 绑定本地端口,将本地端口的访问转发到远端。使用 -L
参数,格式为 本地端口:目标主机:目标主机端口
。
假设本地主机为 host1,host1 能够访问 host2, host2 能够访问 host3,但 host1 无法直接访问 host3。
在 host1 上执行:
|
|
表示绑定本地 8888 端口,该端口的访问流量会由 host2 转发至 host3:8000 端口。
在 host1 上执行:
|
|
表示绑定本地 8888 端口,该端口的访问流量会转发至 host2:8000 端口。注意目标主机的 localhost
指的是目标主机本身。
本地端口默认绑定到 localhost
,只能本地访问,若要可以外网访问(绑定 0.0.0.0
),可以写成:
|
|
远程端口转发
SSH 绑定远程端口,将远程端口的访问转发到本地。使用 -R
参数,格式为 远程主机端口:目标主机:目标主机端口
。
SSH 远程端口转发非常适合用来做内网穿透。假如 host1 是公网主机,host2 是内网主机且能够访问公网,host3 是内网主机不能访问公网,但 host2 可以访问 host3。如果要从 host1 访问 host3,可以用 host2 中转。
在 host2 上执行:
|
|
表示绑定 host1 的 8888 端口,该端口的访问流量会由 host2 转发至 host3:8000 端口。
在 host2 上执行:
|
|
表示绑定 host1 的 8888 端口,该端口的访问流量会转发至 host2:8000 端口,注意目标主机的 localhost
指的是本地主机(发起 SSH 连接的主机)。
远程端口也是默认绑定到 localhost
,若要外网访问(绑定 0.0.0.0
),需要修改远程主机的 /etc/ssh/sshd_config
配置:
|
|
记得重启 sshd 服务:
|
|
动态端口转发
上述两种端口转发都是固定端口对固定端口的转发。动态端口转发不必指定端口号,可以将本地任意端口的流量转发到 SSH 远端。
动态端口转发使用 -D
参数,参数为 绑定地址:绑定本地端口
。SSH 会启动一个 SOCKS 服务器监听该地址和端口,当使用该端口作为 SOCKS 代理时,请求的流量会被转发到远端。
例如在 host1 上执行
|
|
则在 host1 的 Firefox 中指定 localhost:8000
作为 socks 代理时,可以直接访问 host2 能够访问的主机和端口。
SSH 的其他参数
-N
只连接远程主机,不打开远程 shell;-T
不为这个连接分配 TTY;
这两个参数可以一起使用,代表这个 SSH 连接只用来传输数据,不执行远程操作。
-f
表示 SSH 连接成功后,转入后台运行。
autossh
SSH 连接可能会意外断开或 hang 住,用进程监控工具,并不能有效检测到 hang 住的情况,autossh 就是为了解决这个问题。
autossh 会启动一个 SSH 进程,并实现一个端口转发循环,当发现进程死掉或者端口转发循环的流量停止时,会重启 SSH 进程,有效避免了 hang 住导致 SSH 端口转发不可用的情况。
安装:
|
|
autossh
命令的参数除了 -M
参数(用于手动指定端口转发循环的端口)外,其他参数与 ssh
命令相同,并会把这些参数传递给监视的 SSH 进程。
所以一个稳定的 SSH 远程端口转发的命令可以是:
|
|
可以将 autossh 与 supervisor 等进程管理工具配合使用,建立长期稳定的 SSH 端口转发。