SSH 隧道与端口转发:远程开发调试利器
David Ng | 2026-08-27T20:55:29 | DevOps, Security
详解 SSH 本地转发、远程转发和动态转发三种模式,解决远程数据库访问、内网穿透等常见开发问题。
# SSH 隧道与端口转发 ## 为什么需要 SSH 隧道? 在开发中经常遇到以下场景: - 数据库在远程服务器,不对外开放端口 - 需要访问内网的测试环境 - 在公共网络下安全地访问服务 SSH 隧道可以加密转发流量,无需 VPN。 ## 一、本地端口转发(Local Forwarding) 将本地端口转发到远程服务器可达的目标地址。 ```bash # 语法:ssh -L 本地端口:目标地址:目标端口 跳板机 # 场景:通过跳板机访问内网数据库 ssh -L 3307:db-server:3306 user@jump-server # 现在可以用 localhost:3307 连接远程数据库 mysql -h 127.0.0.1 -P 3307 -u root -p ``` ``` 本地 :3307 ----SSH加密隧道----> jump-server -----> db-server:3306 ``` ### 实用参数 ```bash # -f: 后台运行 # -N: 不执行远程命令 # -C: 压缩数据 ssh -fNL 3307:db-server:3306 user@jump-server # 多个端口转发 ssh -L 3307:db:3306 -L 6380:redis:6379 user@jump-server ``` ## 二、远程端口转发(Remote Forwarding) 将远程服务器的端口转发到本地,实现内网穿透。 ```bash # 语法:ssh -R 远程端口:本地地址:本地端口 远程服务器 # 场景:让远程服务器能访问本地开发环境 ssh -R 8080:localhost:3000 user@public-server # 现在 public-server:8080 的流量会转发到本地 :3000 ``` ``` public-server:8080 ----SSH加密隧道----> 本地 :3000 ``` ### 需要配置远程服务器 ```bash # /etc/ssh/sshd_config GatewayPorts yes # 允许绑定到 0.0.0.0(默认只绑定 127.0.0.1) ``` ## 三、动态端口转发(SOCKS 代理) ```bash # 创建本地 SOCKS5 代理 ssh -D 1080 user@proxy-server # 配置浏览器或系统代理为 localhost:1080 # 所有流量通过 SSH 隧道转发 ``` ### 配合 curl 使用 ```bash # 通过 SOCKS 代理访问 curl --socks5 localhost:1080 http://internal-api:8080/health # 或者配合 proxychains proxychains curl http://internal-api:8080/health ``` ## 四、SSH 配置文件简化 ```bash # ~/.ssh/config Host jump HostName jump-server.example.com User deploy IdentityFile ~/.ssh/deploy_key Host db-tunnel HostName jump-server.example.com User deploy LocalForward 3307 db-server:3306 LocalForward 6380 redis-server:6379 Host dev-expose HostName public-server.example.com User deploy RemoteForward 8080 localhost:3000 ``` 使用时只需: ```bash ssh db-tunnel # 自动建立数据库隧道 ssh dev-expose # 自动暴露本地服务 ``` ## 五、保持连接 ```bash # ~/.ssh/config 全局配置 Host * ServerAliveInterval 60 ServerAliveCountMax 3 TCPKeepAlive yes ``` ## 六、安全注意事项 1. 使用密钥认证,禁用密码登录 2. 限制端口转发权限:`AllowTcpForwarding local` 3. 远程转发时注意不要暴露敏感服务 4. 使用 `autossh` 保证隧道自动重连 ```bash # autossh 自动重连 autossh -M 0 -fNL 3307:db-server:3306 user@jump-server ``` ## 常见问题 - **连接断开**:配置 ServerAliveInterval 或使用 autossh - **端口被占用**:换一个本地端口 - **权限拒绝**:检查服务器 sshd_config 中的 AllowTcpForwarding 配置