在日常开发中,我们经常会遇到这样的需求:

  1. 想连接线上数据库,但服务器为了安全只开放了 SSH 端口,数据库端口被防火墙挡住。
  2. 在本地开发了一个 Web 应用,想发给异地同事或客户体验,但没有公网 IP。

只要你有一台能 SSH 登录的服务器(或使用一些公共隧道服务),用一条 SSH 命令就能解决。

SSH 端口转发本质上是“隧道”(Tunneling)。最常用的两个参数是 -L-R

  • -L(Local):把远程的服务“拉回本地”(我想访问别人)。
  • -R(Remote):把本地的服务“推出远程”(我想让别人访问我)。

# 1. SSH -L:本地端口转发(Local Port Forwarding)

适用场景:安全地连接远程服务器上的服务(如 MySQL、Redis)。

假设你有一台服务器 1.2.3.4,上面运行着 MySQL(3306 端口),但防火墙只允许本机 127.0.0.1 访问。你在本地 Windows/macOS 上想用 Navicat 或 DBeaver 管理它。

# 命令格式

ssh -L <本地端>:<目标IP>:<目标端> <>@<跳板机IP>

# 实战示例

ssh -L 3307:localhost:3306 root@1.2.3.4

执行后:

  • SSH 客户端会在你本地监听 3307
  • 你连接 localhost:3307,请求会通过 SSH 隧道转发到远程的 localhost:3306

# 2. SSH -R:远程端口转发(Remote Port Forwarding)

适用场景:内网穿透,把本地服务暴露给公网访问。

假设你在本地开发了一个 FastAPI 服务,监听 8001 端口。现在你需要让外部人员访问(演示/联调)。

# 命令格式

ssh -R <远程端>:<本地IP>:<本地端> <>@<远程服务器IP>

# 实战示例

如果你有自己的服务器 1.2.3.4,可以把远程 8080 映射到本地 8001

ssh -R 8080:localhost:8001 root@1.2.3.4

执行后,访问远程服务器的 8080 端口,就会被转发到你本机的 8001


# 3. 小提示

  • -L 常用于“我访问远程内网服务”。
  • -R 常用于“别人访问我本地服务”。
  • 生产环境下建议配合 ~/.ssh/config、最小权限账号、以及必要的防火墙策略使用。