目录
SSH 隧道基础概念 什么是 SSH 隧道? SSH 隧道(SSH Tunnel)是一种通过 SSH 协议建立的安全网络连接通道。它允许你通过一个安全的 SSH 连接来传输其他协议的数据,就像建立了一条”地下通道”。
1 2 你的电脑 ←→ [SSH 隧道] ←→ 目标服务器 安全加密连接 各种服务(数据库、Web等)
为什么需要 SSH 隧道?
安全性 :所有数据都通过 SSH 加密传输
访问受限资源 :绕过防火墙或网络限制
跳板机访问 :通过中间服务器访问最终目标
本地化远程服务 :让远程服务看起来像本地服务
工作原理 1 2 3 应用程序 → 本地端口 → SSH 隧道 → 远程端口 → 目标服务 ↓ ↓ ↓ ↓ ↓ 数据库客户端 → 3306 → SSH加密传输 → 22 → 远程数据库:3306
SSH 隧道类型详解 1. 本地端口转发(Local Port Forwarding) 概念 :将本地端口的流量转发到远程服务器的指定端口。
流量走法 :本地–>远程 (端口本地监听,流量起点是本地服务器,流量终点是远程服务器。就和访问远程服务器一样,区别就是套了一层SSH加密,可以理解为本地转发就是把流量送出去。)
语法 :
1 2 # [本地IP:]可以不填,默认就是localhost ssh -L [本地IP:]本地端口:目标主机:目标端口 -p 端口 -i 密钥 SSH服务器
示例 :
1 2 3 4 5 6 7 8 # 将本地 3306 端口转发到远程服务器的 MySQL ssh -L 3306:localhost:3306 user@remote-server # 绑定到所有网卡(允许其他机器访问) ssh -L 0.0.0.0:3306:localhost:3306 user@remote-server # 通过跳板机访问第三方服务器,通过访问本地8080达到访问192.168.1.100:80的目的 ssh -L 8080:192.168.1.100:80 user@jumpserver
使用场景 :
访问远程数据库
访问内网 Web 服务
绕过防火墙限制
2. 远程端口转发(Remote Port Forwarding) 概念 :将远程服务器的端口转发到本地机器的指定端口。
流量走法 : **远程–>本地(**远程端口监听,流量起点是远程服务器,流量终点是本地服务器。,可以理解为找了个通往本地服务器的门。)
语法 :
1 ssh -R [远程IP:]远程端口:本地主机:本地端口 -p 端口 -i 密钥 SSH服务器
示例 :
1 2 3 4 5 # 让远程服务器的 8080 端口转发到本地的 80 端口 ssh -R 8080:localhost:80 user@remote-server # 让远程服务器可以访问本地的数据库 ssh -R 3306:localhost:3306 user@remote-server
使用场景 :
3. 动态端口转发(Dynamic Port Forwarding) 概念 :创建一个 SOCKS 代理,可以代理多种协议的流量。
语法 :
1 ssh -D [本地IP:]本地端口 SSH服务器
示例 :
1 2 3 4 5 # 创建 SOCKS 代理 ssh -D 1080 user@remote-server # 绑定到所有网卡 ssh -D 0.0.0.0:1080 user@remote-server
使用场景 :
实战案例 案例1:通过跳板机连接数据库 场景 :需要通过跳板机 192.168.25.88 连接到目标服务器 18.140.243.143 上的 MySQL 数据库。
1 2 3 4 5 6 7 8 # 方法1:一步建立隧道 ssh -L 3306:18.140.243.143:3306 ubuntu@192.168.25.88 -N # 方法2:使用已配置的 SSH alias ssh -L 3306:localhost:3306 testsgame-via-jump -N # 方法3:指定不同的本地端口避免冲突 ssh -L 13306:localhost:3306 testsgame-via-jump -N
连接数据库 :
1 2 3 4 5 # 使用命令行客户端 mysql -h 127.0.0.1 -P 3306 -u username -p # 或连接到不同端口 mysql -h 127.0.0.1 -P 13306 -u username -p
案例2:多端口转发 1 2 # 同时转发多个服务 ssh -L 3306:target:3306 -L 6379:target:6379 -L 5432:target:5432 user@jumpserver -N
案例3:Web 服务访问 1 2 3 4 # 访问内网 Web 服务 ssh -L 8080:internal-web:80 user@jumpserver -N # 然后在浏览器访问:http://localhost:8080
常用命令和参数 基本命令格式
重要参数详解
参数
说明
示例
-L
本地端口转发
-L 3306:target:3306
-R
远程端口转发
-R 8080:localhost:80
-D
动态端口转发
-D 1080
-N
不执行远程命令,只建立隧道
-N
-f
后台运行
-f
-C
启用压缩
-C
-v
详细输出(调试用)
-v
-T
禁用伪终端分配
-T
-o
指定选项
-o ConnectTimeout=10
实用技巧 1. 后台运行隧道 :
1 2 3 4 5 # 后台运行,不占用终端 ssh -L 3306:target:3306 user@server -N -f # 使用 nohup 防止意外断开 nohup ssh -L 3306:target:3306 user@server -N &
2. 自动重连 :
1 2 3 4 5 6 7 8 # 使用 autossh(需要安装) autossh -M 0 -N -L 3306:target:3306 user@server # 使用循环自动重连 while true; do ssh -L 3306:target:3306 user@server -N sleep 5 done
3. 查看和管理隧道 :
1 2 3 4 5 6 7 8 9 # 查看所有 SSH 进程 ps aux | grep ssh # 查看端口占用 lsof -i :3306 netstat -tulpn | grep 3306 # 终止隧道 kill $(lsof -t -i:3306)
SSH 配置文件 基本配置结构 SSH 配置文件位置:~/.ssh/config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 跳板机配置 Host jump-server HostName 192.168.25.88 User ubuntu Port 22 IdentitiesOnly yes # 通过跳板机访问目标服务器 Host target-via-jump HostName 18.140.243.143 User devx Port 22 IdentityFile ~/.ssh/id_rsa_target ProxyJump jump-server IdentitiesOnly yes
端口转发配置 1 2 3 4 5 6 7 8 # 自动建立端口转发 Host db-tunnel HostName 192.168.25.88 User ubuntu LocalForward 3306 18.140.243.143:3306 LocalForward 5432 18.140.243.143:5432 LocalForward 6379 18.140.243.143:6379 ExitOnForwardFailure yes
使用方式 :
1 2 # 连接时自动建立所有端口转发 ssh db-tunnel -N
高级配置选项 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Host * # 连接超时 ConnectTimeout 10 # 保持连接活跃 ServerAliveInterval 60 ServerAliveCountMax 3 # 压缩传输 Compression yes # 控制主连接 ControlMaster auto ControlPath ~/.ssh/control-%r@%h:%p ControlPersist 10m
故障排查 常见问题和解决方案 1. 端口已被占用
1 2 3 4 5 6 7 # 错误信息 bind: Address already in use # 解决方案 lsof -i :3306 # 查看占用进程 kill $(lsof -t -i:3306) # 终止占用进程 ssh -L 13306:target:3306 ... # 使用不同端口
2. 连接超时
1 2 3 4 5 6 7 8 # 调试连接 ssh -v user@server # 常见原因和解决方案 - 防火墙阻止:检查防火墙规则 - DNS 解析问题:使用 IP 地址 - SSH 服务未启动:检查目标服务器 SSH 服务 - 网络不通:使用 ping 和 telnet 测试
3. 认证失败
1 2 3 4 5 6 7 8 # 检查密钥权限 chmod 600 ~/.ssh/id_rsa chmod 644 ~/.ssh/id_rsa.pub chmod 700 ~/.ssh # 测试密钥 ssh-add -l # 查看已加载的密钥 ssh-add ~/.ssh/id_rsa # 手动添加密钥
4. 隧道建立但无法连接
1 2 3 4 5 6 7 8 # 检查隧道状态 netstat -tulpn | grep 端口号 # 检查目标服务是否运行 ssh user@server "netstat -tulpn | grep 3306" # 检查防火墙 ssh user@server "sudo ufw status"
调试技巧 1. 启用详细输出 :
1 2 3 4 ssh -v -L 3306:target:3306 user@server # -v: 详细模式 # -vv: 更详细 # -vvv: 最详细
2. 测试连接 :
1 2 3 4 5 6 # 测试 SSH 连接 ssh -T user@server # 测试端口连通性 telnet target-server 3306 nc -zv target-server 3306
3. 检查日志 :
1 2 3 4 5 # 客户端日志 journalctl -u ssh # 服务器日志 sudo tail -f /var/log/auth.log
工具集成 Navicat 数据库工具 配置方法 :
创建连接 → 选择数据库类型
常规设置 :
1 2 3 4 5 连接名:项目数据库 主机:127.0.0.1 端口:3306 用户名:数据库用户名 密码:数据库密码
SSH 设置 :
1 2 3 4 5 6 ✅ 使用 SSH 隧道 主机:192.168.25.88 端口:22 用户名:ubuntu 验证方法:公钥 私钥:选择密钥文件
VS Code SFTP 插件 配置文件 :.vscode/sftp.json
1 2 3 4 5 6 7 8 9 10 11 12 { "name": "production", "host": "192.168.25.88", "username": "ubuntu", "agent": "$SSH_AUTH_SOCK", "remotePath": "/home/devx/project", "hop": { "host": "18.140.243.143", "username": "devx", "privateKeyPath": "/home/ubuntu/.ssh/id_rsa_target" } }
DBeaver 配置
新建连接 → 选择数据库类型
主要设置 :填写数据库信息
SSH 设置 :配置跳板机信息
测试连接
命令行工具别名 在 ~/.bashrc 或 ~/.zshrc 中添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 快速建立常用隧道 alias mysql-tunnel='ssh -L 3306:target:3306 jumpserver -N' alias redis-tunnel='ssh -L 6379:target:6379 jumpserver -N' alias web-tunnel='ssh -L 8080:target:80 jumpserver -N' # 查看隧道状态 alias tunnels='ps aux | grep "ssh.*-L" | grep -v grep' # 关闭所有隧道 alias kill-tunnels='pkill -f "ssh.*-L"' # 端口检查 portcheck() { lsof -i :$1 && echo "Port $1 is in use" || echo "Port $1 is free" }
安全最佳实践 1. 密钥管理 1 2 3 4 5 6 7 8 9 10 # 生成强密钥 ssh-keygen -t ed25519 -C "your_email@example.com" # 设置正确权限 chmod 700 ~/.ssh chmod 600 ~/.ssh/id_* chmod 644 ~/.ssh/*.pub # 使用密钥代理 ssh-add ~/.ssh/id_ed25519
2. SSH 配置安全 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # ~/.ssh/config 安全配置 Host * # 只使用指定的密钥 IdentitiesOnly yes # 连接超时 ConnectTimeout 10 # 禁用某些认证方法 PasswordAuthentication no ChallengeResponseAuthentication no # 保持连接但有超时 ServerAliveInterval 60 ServerAliveCountMax 3
3. 服务器安全 1 2 3 4 5 6 7 8 # SSH 服务器配置 /etc/ssh/sshd_config Port 22 # 考虑更改默认端口 PermitRootLogin no # 禁止 root 登录 PasswordAuthentication no # 禁用密码认证 PubkeyAuthentication yes # 启用公钥认证 MaxAuthTries 3 # 限制认证尝试次数 ClientAliveInterval 300 # 客户端保活间隔 ClientAliveCountMax 2 # 最大保活次数
4. 隧道安全 1 2 3 4 5 6 7 8 # 只绑定到本地回环接口 ssh -L 127.0.0.1:3306:target:3306 server # 避免绑定到所有接口(除非必要) # 避免:ssh -L 0.0.0.0:3306:target:3306 server # 使用防火墙限制访问 sudo ufw allow from 192.168.1.0/24 to any port 3306
5. 监控和日志 1 2 3 4 5 6 7 8 # 定期检查连接 ss -tulpn | grep :22 # 监控日志 sudo tail -f /var/log/auth.log | grep ssh # 检查失败的登录尝试 sudo grep "Failed password" /var/log/auth.log
总结 SSH 隧道是一个强大的网络工具,可以帮助你:
✅ 安全地访问远程服务
✅ 绕过网络限制和防火墙
✅ 通过跳板机访问内网资源
✅ 保护敏感数据传输
记住关键要点:
-L 用于本地端口转发(最常用)
-N 只建立隧道,不执行命令
-f 后台运行
使用 SSH 配置文件简化操作
注意安全和权限设置
通过练习这些示例,你将能够熟练使用 SSH 隧道来解决各种网络访问问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 # ssh_config 多站点配置 Host myserver HostName 192.168.0.100 User dev IdentityFile ~/.ssh/id_rsa_dev Host githubdex.com HostName github.com User xxx@test.com IdentityFile ~/.ssh/id_rsa_dex #即使使用openssh key agent 这里填写的也是 ssh-add xxx 时的名称 Host github.com User username@aliyun.com IdentityFile ~/.ssh/id_rsa # WSL中配置一下,并执行下面的命令,宿主机可以连接 localhost:27018 ssh -L 0.0.0.0:27018:localhost:27017 testsgame-via-jump -N # # # # # Jump host configuration Host jump-server HostName 192.168.25.88 User ubuntu Port 22 # Target server via jump host Host testsgame-via-jump HostName 18.140.243.143 User devx Port 22 IdentityFile ~/.ssh/id_rsa_18-140-243-143 ProxyJump jump-server IdentitiesOnly yes #