SSH 三种端口转发情况示例
0. 前言
SSH 客户端可通过 SOCKS5 代理连接 SSH 服务器。MobaXterm 等 SSH 客户端工具可在设置中自行配置,SSH 命令行可使用如下格式命令(需要安装 netcat-openbsd )。
# 安装 netcat-openbsd
apt install netcat-openbsd
# 使用 SOCKS5代理,命令格式及示例
# ssh -o "ProxyCommand=nc -X 5 -x proxy_host:proxy_port %h %p" ssh_user@ssh_host
ssh -o "ProxyCommand=nc -X 5 -x 127.0.0.1:8080 %h %p" root@12.34.56.78
SSH 端口转发通常有如下三种情况:动态转发(常用于正向代理)、本地转发(远程端口映射至本地)、远程转发(本地端口映射至远程服务器)。本文参考 WangDoc - SSH 端口转发 ,根据个人理解对 SSH 的三种端口转发情况进行简单演示说明。
1. 动态转发
使用 SSH 隧道实现正向代理,连接任意目标服务器。 即:SSH 客户端与服务器建立加密隧道,由 ssh 进程监听本地端口,该端口提供 Socks5 代理服务。浏览器等客户端软件通过该 Socks5 代理连接目标服务器。由于 SSH 服务器向目标服务器发起的请求是根据浏览器等客户端原始请求决定的,故称为动态转发(Dynamic Port Forwarding)。
注1:流量皆为双向,为简化理解图中未画出反向流量,目标服务器可以是任意多个。
注2:Socks5 协议只负责在客户端和代理服务器之间通过认证后建立连接,以及转发原始流量,并非 “原始流量 in Socks5” 的形式。
graph LR; B(浏览器等客户端) -->|Socks5 认证 \n 客户端任意请求流量| C(SSH 客户端监听 \n 本机 Socks5 端口) subgraph SSH 隧道 C ==>|SSH 流量| S(SSH 服务器 \n) end S -->|客户端请求流量A| T(目标服务器1) S -->|客户端请求流量B| T2(目标服务器2)
ssh -D 7777 user@remote_host -N -v
其中 user 和 remote_host 分别为 SSH 服务器的用户名和 IP / HostName,详细参数解释如下:
- -D : 动态转发,指定本机提供 Socks5 代理服务的端口。
- -N : 该 SSH 连接只进行端口转发,不登录远程 Shell,不执行远程命令,只充当隧道。
- -v : 可选参数,在 Terminal 中输出详细 SSH 日志信息,查看更详细的日志可以使用 -vv -vvv 等参数。
2. 本地转发
将远程服务器的端口映射至本地。 即:创建由 ssh 进程监听的本地端口,发往该端口的流量都会通过 SSH 隧道,发送至特定远程主机的特定端口。由于是在本地计算机建立的转发规则,故称为本地转发(Local Port Forwarding)。
ssh -L local_port:target_host:target_port user@remote_host -N -f
其中 target_host 和 target_port 为要映射到本地的远程服务器 IP / HostName 和端口,local_port为映射到本地的端口。
- -L : 本地端口转发。
- -N : 该 SSH 连接只进行端口转发,不登录远程 Shell,不执行远程命令,只充当隧道。
- -f : 可选参数,将 SSH Client 放在后台运行,不添加该参数则 SSH Client 以前台方式运行,默认不输出任何信息。
若要停止该转发,可使用 kill -9 pid
命令终止 SSH Client 进程。
3. 远程转发
将本地服务器端口映射到远程服务器。 即:使远程服务器的 sshd 进程监听指定端口,所有访问该端口的流量都会通过 SSH 隧道发送至本地主机的特定端口。由于是通过远程 SSH 服务器访问本地计算机,故称为远程转发(Remote Port Forwarding)。
ssh -R remote_port:target_host:target_port -N user@remote_host
其中 target_host 和 target_port 为要映射到远程的本地服务器 IP / HostName 和端口,remote_port为映射到远程主机的端口。
- -R : 远程端口转发。
- -N : 该 SSH 连接只进行端口转发,不登录远程 Shell,不执行远程命令,只充当隧道。
4. 补充:监听地址问题
在动态转发和本地转发情况下,如上述截图所示,默认客户端 ssh 进程只监听回环网卡下的端口,若想让其监听0.0.0.0,需要在 ~/.ssh/config
下添加如下内容:
Host *
GatewayPorts yes
也可以使用如下命令直接添加:
echo "Host * \n GatewayPorts yes" >> ~/.ssh/config
同样,在远程转发情况下,默认服务端 sshd 进程也只监听回环网卡下的端口,若想让其监听 0.0.0.0,需要在配置文件 /etc/ssh/sshd_config
下添加如下内容,或者修改配置文件 105 行左右,将 #GatewayPorts no
注释取消并将值改为 yes
。
GatewayPorts yes
完成上述变更后,重启 sshd 服务。
systemctl restart sshd