目标服务在跳板机本地时填 localhost 或 127.0.0.1;在其他内网机器时填该机器对跳板机可达的IP(如192.168.1.100),且须确保目标服务监听0.0.0.0或该IP而非仅127.0.0.1。

ssh -L 就能完成本地端口转发,不需要改服务器配置、不依赖额外工具,只要能 SSH 登录跳板机且它能访问目标服务,5 分钟内就能通。失败主因不是网络或权限,而是 -L 后面的目标主机地址写错。
ssh -L 命令里目标主机地址怎么填?
目标主机地址是「对跳板机而言」能访问到的地址,不是对你本机而言的。填错就转不过去,连通性测试全绿也没用。
- 如果目标服务(如 MySQL)和跳板机在同一台机器上:
-L 3306:localhost:3306或-L 3306:127.0.0.1:3306——不能写跳板机的局域网 IP(如192.168.1.10)或公网 IP - 如果目标服务在另一台内网机器(如
192.168.1.100):-L 3306:192.168.1.100:3306,但前提是跳板机能ping 192.168.1.100且该服务监听的是0.0.0.0或192.168.1.100,而不是仅127.0.0.1 - 验证跳板机能否访问目标:
ssh user@jump-host 'nc -zv 192.168.1.100 3306',不通就得先查目标服务监听配置或防火墙
后台常驻运行必须加 -fN,否则隧道一关就断
只跑 ssh -L 8080:web.internal:80 user@jump,终端退出或 Ctrl+C 就断;想让它一直跑着,必须加参数让 SSH 进入后台且不执行命令。
-
-f:fork 到后台,释放终端 -
-N:明确禁止执行远程命令,只做端口转发(没这个会卡在 shell 里) -
-T:可选,禁用伪终端,减少日志干扰,适合脚本中使用 - 正确写法:
ssh -fNT -L 8080:web.internal:80 user@jump-host
本地端口被占用或权限不足时怎么办?
Linux 下绑定 1–1023 端口需要 root 权限;普通用户默认只能绑 ≥1024 的端口。报错不是配置问题,是系统限制。
-
bind: Permission denied→ 换端口,比如用8080代替80,或加sudo(不推荐用于日常开发) -
Address already in use→ 先查谁占着:lsof -i :3306或ss -tlnp | grep 3306,再kill或换端口 - 想让同事也能连你机器上的转发端口(如
http://your-ip:8080)?得写成-L *:8080:target:80,但要求跳板机/etc/ssh/sshd_config中GatewayPorts设为clientspecified或yes,且你有权限改——一般生产环境禁用,安全风险高
真正容易被忽略的是目标服务的监听地址
很多内网服务(Docker 容器、python -m http.server、redis-server 默认配置)只监听 127.0.0.1。跳板机从外部 IP 访问不到,ssh -L 再对也白搭。
必须确认目标服务监听的是 0.0.0.0 或对应内网 IP。例如:
- Docker 启动时加
-p 192.168.1.100:3306:3306不够,还得确保 MySQL 配置里bind-address = 0.0.0.0 - Python 开发服务器:
python3 -m http.server 8000 --bind 0.0.0.0:8000 - 检查监听状态:
netstat -tlnp | grep :3306,看到0.0.0.0:3306才算合格


















