跳转至

SSH 端口转发与配置

结论

不开公网端口,用本地转发把远程服务映射到本机:

ssh -N -L 8080:127.0.0.1:8080 user@server

-N 表示不执行远程命令、只做转发。然后浏览器访问 http://127.0.0.1:8080。

写进配置文件,省得每次敲

~/.ssh/config:

Host notes
    HostName 203.0.113.10
    User ubuntu
    Port 22
    IdentityFile ~/.ssh/notes_ed25519
    IdentitiesOnly yes
    LocalForward 8080 127.0.0.1:8080
    ServerAliveInterval 30
    ServerAliveCountMax 3

之后 ssh -N notes 就是一条隧道。ServerAliveInterval 能避免长时间空闲被 NAT 断开。

三种转发方向

参数 方向 典型用途
-L 8080:127.0.0.1:80 本地 → 远程 访问远程内网服务
-R 9000:127.0.0.1:3000 远程 → 本地 把本机开发服务暴露给服务器
-D 1080 动态 SOCKS 临时代理

经跳板机访问

Host target
    HostName 10.0.0.5
    User ubuntu
    ProxyJump bastion

ssh target 会自动先连 bastion,不需要手工开两条隧道。等价于 ssh -J bastion ubuntu@10.0.0.5。

排错顺序

  1. 本地端口是否在听:Test-NetConnection 127.0.0.1 -Port 8080(Windows)/ ss -lnt | grep 8080
  2. 隧道是否真建立:ssh -v -N -L ...,看到 Local connections to LOCALHOST:8080 forwarded 才算成功
  3. 远程服务是否绑定正确:只绑 127.0.0.1 的服务,从公网直连必然失败,这是设计如此
  4. 地址用 127.0.0.1 不用 localhost:Windows 可能把 localhost 解析成 IPv6 ::1,而隧道只转了 IPv4

自动化场景

脚本里跑 ssh 一定要加 BatchMode,否则会卡在交互提示:

ssh -o BatchMode=yes -o ConnectTimeout=8 host 'uptime'

首次连接加上 -o StrictHostKeyChecking=accept-new,避免 known_hosts 交互阻塞。