个板马,喵莫比喵?

SSH的端口转发能力

SSH支持三种端口转发方式,分别是:

  • 本地转发(-L 参数)
  • 远程转发(-R 参数)
  • 动态转发(-D 参数)

简单介绍一下每种用法:


本地转发(Local Forwarding)

可以将远程主机的指定端口映射到本地主机的指定端口,指令格式如下:

ssh -L [本地主机host:]本地主机port:远程主机host:远程主机port username@远程主机host

举个例子,现在我远程主机 123.123.123.123 上有一个 MySQL 服务,端口为 3306。因为防火墙端口限制,我无法直接访问到该远程主机的 3306 端口,但我还是想连接这个 MySQL 服务,所以需要通过 SSH 把它的 3306 端口映射到我本地的某个端口上。

比如我执行下面这个指令:

ssh -L 0.0.0.0:3306:123.123.123.123:3306 user@123.123.123.123

然后我就可以像访问本地服务一样,直接连接 localhost:3306 来访问远程主机的 MySQL 服务了(前提是本地没有其他服务占用这个端口)。

注意:这里使用的本地主机host是 0.0.0.0,而不是 127.0.0.1
0.0.0.0 表示本机上的所有IPv4地址,也就是监听所有网络接口。

远程转发(Remote Forwarding)

可以将本地主机的指定端口映射到远程主机的指定端口,指令格式如下:

ssh -R [远程主机host:]远程主机port:本地主机host:本地主机port username@远程主机host

还是举个例子:现在我有一台网络访问受限的远程主机 123.123.123.123,也就是这台服务器访问不了公网,我就可以用 SSH 把我本地的代理端口映射过去,让这台远程主机通过我的网络上网。这在一些无法直接连网的服务器很有用。


我遇到的一个实际场景:

因为工作原因,现在有一台非涉密纯内网服务器(不能访问公网,公网也无法访问该服务器)。但系统中有一个模块需要在线更新,所以用了 SSH 的远程端口转发功能来解决这个问题。

注意:如果不想包吃包住的话,就千万不要在任何涉密机器上执行这种操作!!!

我使用的是 FlClash(因为我最常用,而且界面最好看 XD),当然你也可以使用其他 Clash 客户端比如 Clash Verge 或者直接用内核 clash-core

首先,配置代理端口7890,然后开启 局域网代理,如下图:

然后设置出站模式为“直连”,点击右下角启动:

接着打开 Terminal,执行如下 SSH 指令:

ssh -R 0.0.0.0:7891:127.0.0.1:7890 user1@172.1.2.3

意思是连接服务器172.1.2.3,并且把我本地 Clash 的 7890 端口,通过 SSH 映射到服务器上的 7891 端口。

连接上去之后,在服务器上设置一下代理环境变量:

export https_proxy=http://127.0.0.1:7891
export http_proxy=http://127.0.0.1:7891
export all_proxy=socks5://127.0.0.1:7891

这样大部分 Linux 工具(比如 curl、apt、wget)就能走代理上网了。

但是,有些程序是不走系统代理的,比如 Java 程序(当然了,还取决于程序的代码逻辑),这个时候就得手动设置参数:

需要在启动 Java 程序的脚本里加上这个参数:

-Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=7891

就可以让 Java 程序也走代理了。


动态转发(Dynamic Forwarding)

这是一种更加灵活的端口转发方式,它不像本地/远程转发那样指定固定的目标地址和端口,相当于在本地启动了一个 SOCKS 代理服务器,可以让任意支持 SOCKS5 协议的软件通过它来访问远程主机网络。

指令格式如下:

ssh -D 本地主机port username@远程主机host

举个例子,比如我执行:

ssh -D 1080 user@123.123.123.123

那么就相当于在我本地的 1080 端口上开了一个 SOCKS5 代理服务。只要保持这个 SSH 连接,那么我电脑上所有支持 SOCKS5 的程序(比如浏览器、Git、curl等等)都可以通过 127.0.0.1:1080 去远程访问到远程主机的网络。

我觉得你应该也想到了,动态转发是不是可以用来搭建“那种服务”?但很可惜并不行。

原因很简单,SSH 协议的特征太明显了,非常容易被识别。而且开启动态转发后,你本机上的各种客户端会发起大量像 DNS、HTTP、TLS 这样的请求,这种流量行为和正常的 SSH 使用完全不一样。

正常的 SSH 流量其实蛮轻的,毕竟咱们大多数时候只是间歇性地输入命令,哪怕是传文件,流量特征也是稳定连续的。但浏览网页、看视频这类操作的流量波动就很大,和 SSH 的流量特征完全对不上,一眼就能被识别出来。

所以呢,并不适合用来做“那种事”。

SSH的端口转发能力

https://blog.mapotofu.cn/archives/using_ssh_port_forwarding.html

作者

麻婆豆腐

发布时间

2025-05-15

添加新评论