宋子宪博客

SSH 端口转发与内网穿透技术

1. 概述 (Overview)

SSH 端口转发(Port Forwarding),俗称“SSH 隧道”,是 OpenSSH 协议提供的一种将 TCP 流量封装在加密的 SSH 连接中传输的技术。

核心价值

  1. 安全性:通过加密通道传输明文流量(如 HTTP, Telnet, 早期 MySQL 协议)。
  2. 穿透性:能够绕过防火墙限制,访问仅监听在内网(localhost/127.0.0.1)的服务。
  3. 双向性:既可以将远程服务映射到本地(Local),也可以将本地服务暴露给远程(Remote)。

2. 本地端口转发 (Local Port Forwarding)

方向:将远程服务器的端口“拉”到本地。

适用场景:访问生产环境数据库、访问内网运维后台(如 XXL-JOB, RabbitMQ Management)、绕过防火墙限制。

2.1 标准命令语法

Bash

ssh -N -L [本地监听IP:]本地端口:目标地址:目标端口 用户名@跳板机IP

2.2 典型实战案例

场景 A:连接生产环境 MySQL

生产数据库 (3306) 仅允许 localhost 访问,你需要用本地 IDEA/Navicat 连接。

Bash

# 将远程 3306 映射到本地 13306
ssh -N -L 13306:127.0.0.1:3306 root@192.168.1.232

场景 B:访问内网 XXL-JOB 调度中心

调度中心运行在远程服务器 8080 端口,且有防火墙拦截外部 HTTP 请求。

Bash

# 将远程 8080 映射到本地 18080
ssh -N -L 18080:127.0.0.1:8080 root@192.168.1.232

3. 远程端口转发 (Remote Port Forwarding)

方向:将本地端口“推”到远程服务器。

适用场景:内网穿透、本地开发环境演示(给异地同事看)、调试第三方 Webhook 回调(微信支付/GitHub)。

3.1 标准命令语法

Bash

ssh -N -R [远程监听IP:]远程端口:本地地址:本地端口 用户名@跳板机IP

3.2 典型实战案例

场景 C:让服务器访问我本地的 Java 服务

我在本地启动了 Spring Boot (8080),需要服务器上的脚本调用我的接口。

Bash

# 将本地 8080 映射到服务器的 9090
ssh -N -R 9090:127.0.0.1:8080 root@192.168.1.232

场景 D:公网演示 (需服务器配置支持)

我在本地开发了网页,想发个 URL 给异地产品经理体验。

Bash

# 假设服务器公网 IP 为 1.2.3.4,且已开启 GatewayPorts
ssh -N -R 0.0.0.0:80:127.0.0.1:8080 root@1.2.3.4

3.3 关键配置说明 (GatewayPorts)

默认情况下,使用 -R 映射的远程端口仅监听在 127.0.0.1。如果需要让其他人通过服务器 IP 访问该端口,必须修改服务器端的 /etc/ssh/sshd_config

Bash

# 1. 编辑配置
vim /etc/ssh/sshd_config

# 2. 修改或添加以下参数
GatewayPorts yes

# 3. 重启 SSHD
systemctl restart sshd

4. 生产环境高级技巧 (Pro Tips)

在日常高频使用中,为了保证隧道的稳定性和易用性,建议采用以下方案。

4.1 自动重连 (Autossh)

原生 ssh 命令在网络波动断开后不会自动重连。推荐使用 autossh 工具。

4.2 后台静默运行

如果不想占用一个终端窗口,可以添加 -f 参数。

Bash

ssh -N -f -L 3306:127.0.0.1:3306 root@server

4.3 多级跳板 (ProxyJump)

如果目标服务器在内网深处,需要经过跳板机(Bastion Host)才能访问。


5. 常见问题排查 (Troubleshooting)

现象可能原因检查步骤
Connection Refused1. 目标服务没启动 2. 目标端口写错在服务器执行 netstat -tulpn 确认目标端口处于 LISTEN 状态。
端口被占用本地端口已被其他程序使用本地执行 lsof -i :端口号 查看占用进程。
远程转发外部连不上服务器未开启 GatewayPorts检查 /etc/ssh/sshd_config,或只能在服务器本机通过 localhost 访问。
闲置一会就断开防火墙切断了空闲连接增加 SSH 心跳参数 -o ServerAliveInterval=60

6. 总结速查表 (Cheat Sheet)

需求采用模式命令口诀记忆法
我想访问服务器的服务本地转发 (-L)ssh -L 本地端口:目标IP:目标端口Local (拉过来)
我想让服务器访问我的服务远程转发 (-R)ssh -R 远程端口:本地IP:本地端口Remote (推过去)
后台运行不占终端后台模式加上 -N -fNo Shell, Fork

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »