visitor@wangyvdi.top:~$ cat posts/notes/01_ssh_端口转发.md

SSH 端口转发笔记

#ssh #linux #笔记 2 min

这是 posts/notes/ 下的第一篇。它存在的意义有两个:一是把三种端口转发的区别写清楚,二是验证子目录里的 .md 也能当正常文章看。

三个方向

类型 参数 谁连谁 典型用途
本地转发 -L 本地端口 → 经 SSH → 远端能访问的地址 连远端内网里的数据库
远程转发 -R 远端端口 → 经 SSH → 本地能访问的地址 把家里机器临时暴露到服务器
动态转发 -D 本地端口当 SOCKS5 代理 借远端出口上网

本地转发

把远端的 3306 拉到本地 13306:

ssh -N -L 13306:127.0.0.1:3306 user@example.com

-N 表示只开隧道、不执行命令。连上之后,本地程序连 127.0.0.1:13306 就等于连远端的 MySQL。

注意第一个地址是从远端视角看的。写成 127.0.0.1 是远端自己的环回;想连远端内网另一台机器,就写它的内网地址。

远程转发

反过来,把本地的 8080 推给远端:

ssh -N -R 18080:127.0.0.1:8080 user@example.com

之后访问 example.com:18080 就会落到你本地的 8080。默认情况下,远端的 sshd 只把这个端口绑在环回上,要让外部访问,还得在服务器的 sshd_config 里打开 GatewayPorts。

动态转发

ssh -N -D 1080 user@example.com

本地 1080 就成了一个 SOCKS5 代理。浏览器指过去,出口 IP 就变成远端那台机器。

几个常踩的坑

  • -N 忘了加,于是顺便开了个登录 shell,关窗口隧道就断。
  • -f 和 -N 一起用才能后台常驻,但失败时不容易看到报错,调试期先别加。
  • ExitOnForwardFailure:本地端口已被占用时,默认情况下 SSH 会继续登录、只把转发悄悄放弃。加上 -o ExitOnForwardFailure=yes 才会直接失败。
  • ServerAliveInterval:NAT 空闲超时会把隧道掐掉,设个心跳能少很多"昨天还好用"的困惑。
ssh -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \
    -L 13306:127.0.0.1:3306 user@example.com

和这篇博客的关系

这个站点自己的 SSH 前端也是同一个端口上的一条长连接,只不过它不给你 shell,而是给你一棵只读(对你的视图可写)的目录树。想确认它真的不支持转发以外的花样,可以试试:

visitor@localhost:~$ which ssh
visitor@localhost:~$ ls

没有 ssh 这条命令,也没有 bash、sh、python——它不 spawn 任何子进程,这也是部署时敢开 NoNewPrivileges 和 MemoryDenyWriteExecute 的原因。

在终端里读这篇:ssh -p 2022 wangyvdi.top cat posts/notes/01_ssh_端口转发.md (原文 是同样的纯文本)