SSH 端口转发与跳板机配置:安全访问内网服务的常用姿势

SSH 端口转发与跳板机安全访问内网服务的封面图

数据库、Redis、管理面板这类服务为什么不该直接暴露在公网?因为每一次暴露都是一个可被扫描、可被爆破的入口。更稳妥的做法是把它们留在内网,用 SSH(Secure Shell,一种加密的远程登录协议)的加密通道按需访问。这篇文章会用一套可复制的配置,带你走通本地转发、远程转发、动态转发与跳板机四个场景,帮助你把内网服务的公网暴露面收缩到只剩一个 SSH 端口。在动手之前,你也可以先读一读这篇 WordPress 网站被黑清理与服务器加固实录,看看真实的入侵案例里入口防线是怎么被突破的,再回来做本章的转发实验会更有方向感。

一、场景准备:一台有公网 IP 的入口服务器

为了让你可以直接照抄命令,我们先约定一套贯穿全文的示例环境:一台带公网 IP 的入口服务器(下称跳板机),IP 为 203.0.113.10,SSH 端口 22;两台内网服务器 10.0.0.5(跑 MySQL,监听 3306)和 10.0.0.6(跑管理面板,监听 8080);你的本地电脑通过 SSH 密钥登录跳板机。你可以在 Hostease 的 VPS 主机VPS,即虚拟专用服务器,是把一台物理服务器划分出的多个独立运行环境)上快速准备这样一台入口机,选最低配置即可,因为它只承载 SSH 连接,几乎不消耗 CPU 与内存。

动手前先做一次基线检查,确认服务确实只在内网监听、跳板机可以连通它们:

ss -tlnp | grep -E '3306|8080'
ssh root@203.0.113.10 "nc -zv 10.0.0.5 3306"

如果第一条命令显示 127.0.0.1:3306 或内网地址,说明数据库没有暴露公网,这正是我们想要的状态;如果显示 0.0.0.0:3306,应该先修改 my.cnf 中的 bind-address 或用防火墙封掉公网访问,再做后面的转发配置。想系统学习防火墙规则,可以参考这篇 Linux 服务器安全基线自查,把端口最小化作为第一条基线来执行。

二、本地转发:在家访问内网数据库

本地转发(local forwarding)解决最常见的需求:你在本地电脑上想用图形工具连接内网里的 MySQL,但数据库根本没有任何公网地址。命令是:

ssh -N -L 13306:10.0.0.5:3306 root@203.0.113.10

拆开看这条命令:-L 声明本地转发;13306 是开在你本地电脑上的端口;10.0.0.5:3306 是目标服务,注意它是以跳板机为起点去连接的;-N 表示只建立隧道、不打开远程 shell。执行后,本地 13306 端口的流量会经 SSH 加密送到跳板机,再由跳板机访问 10.0.0.5:3306。此时在你的数据库工具里连接 127.0.0.1:13306,输入的却是内网 MySQL 的账号密码,效果等同于把数据库“拉”到了你面前。

命令行验证连通性可以用:

mysql -h 127.0.0.1 -P 13306 -u dbuser -p

有个细节容易踩坑:连接工具里必须填 127.0.0.1 而不是 localhost。很多 MySQL 客户端遇到 localhost 会改用 Unix socket,根本不走 TCP 端口,于是出现“隧道明明通了却连不上”的假故障。另外,如果你希望这条隧道在后台常驻,可以加上 -f 参数让它建立后自动转入后台,配合 ServerAliveInterval 保持长连接,具体写法见第五节的配置文件。

三、远程转发与动态转发:两个补充场景

远程转发(remote forwarding)的方向正好相反:服务器上的服务需要被外部访问。典型例子是内网管理面板 10.0.0.6:8080 需要临时给同事看一眼,你不想为它开公网端口,于是登录时执行:

ssh -N -R 18080:10.0.0.6:8080 root@203.0.113.10

这条命令让跳板机监听 18080,任何人访问 http://203.0.113.10:18080 时,流量会反向穿过 SSH 隧道到达你这边,再由你的机器转发到 10.0.0.6:8080。如果想让这个端口对跳板机之外的人也可访问,需要在跳板机的 /etc/ssh/sshd_config 中设置 GatewayPorts yes 并重启 sshd,用完务必关闭,避免临时通道变成常驻暴露面。

动态转发(dynamic forwarding)则适合“一堆内网地址都想临时访问”的场景:

ssh -N -D 1080 root@203.0.113.10

执行后本地 1080 端口变成一个 SOCKS5 代理,浏览器或支持代理的工具把流量交给它,SSH 会按目标地址动态决定经跳板机转发到哪个内网服务。配合浏览器的代理插件(如 SwitchyOmega 指向 127.0.0.1:1080),你可以直接用域名访问只对内网 DNS(Domain Name System,域名解析服务,负责把域名翻译成 IP 地址)生效的系统,不用为每个服务单独建隧道。

三种 SSH 端口转发方向对比示意图

四、跳板机:多台内网服务器的统一入口

当内网机器不止一两台时,逐台配置转发不如直接把 203.0.113.10 当作跳板机(jump host),一次登录直达任意内网主机。原生命令是 ssh -J

ssh -J root@203.0.113.10 root@10.0.0.5

这条命令会先连跳板机,再由它转发到 10.0.0.5,全程一条加密链路。更优雅的做法是把拓扑写进 ~/.ssh/config,之后你只需要敲 ssh db

Host jump
    HostName 203.0.113.10
    User root
    IdentityFile ~/.ssh/id_ed25519

Host db
    HostName 10.0.0.5
    User root
    ProxyJump jump

Host panel
    HostName 10.0.0.6
    User root
    ProxyJump jump

跳板机自身的加固同样重要,因为它现在是整个内网唯一的公网入口。推荐三步走:第一,禁用密码登录,sshd_config 中设置 PasswordAuthentication no,只允许密钥;第二,把 AllowTcpForwarding 保持为 yes(否则转发失效),但用 AllowUsers 限定可登录账号;第三,在防火墙层面只放行 SSH 端口,并用 fail2ban 自动封禁爆破 IP。这套入口加固与 Ansible 批量初始化服务器 的流程可以组合使用:新机器上架时先由 Ansible 统一部署密钥与基线配置,再纳入跳板机管理,入口策略就不会因为机器变多而失控。

跳板机统一入口连接多台内网服务器的示意图

五、让隧道更稳:常用参数与排障

临时敲命令建立的隧道一旦断线就消失了,日常使用建议把参数固化到 ~/.ssh/config

Host tunnel-db
    HostName 203.0.113.10
    User root
    LocalForward 13306 10.0.0.5:3306
    ServerAliveInterval 30
    ServerAliveCountMax 3
    ExitOnForwardFailure yes

四个参数各司其职:ServerAliveInterval 30 每 30 秒发一次心跳,防止中间设备掐掉空闲连接;ServerAliveCountMax 3 表示连续 3 次心跳无响应即判定断线退出,避免半死连接占着端口;ExitOnForwardFailure yes 则保证端口被占用、转发建立失败时直接退出,你能在第一时间发现而不是等到连接数据库时才报错。之后执行 ssh -N tunnel-db 即可得到一条可观测的长隧道;若要开机自动重连,可以用 autossh -M 0 -N tunnel-db 交给 systemd 或 cron 托管。

排障时按链路顺序检查三处即可定位绝大多数问题。第一处看本地:ss -tlnp | grep 13306 确认本地端口已在监听;第二处看跳板机:ssh root@203.0.113.10 "nc -zv 10.0.0.5 3306" 确认跳板机到目标服务可达;第三处加 -v 参数重连:ssh -v -N -L 13306:10.0.0.5:3306 root@203.0.113.10,从 verbose 输出里找 channel : open failedadministratively prohibited 字样——后者通常意味着跳板机的 AllowTcpForwarding 被设成了 no,改回 yes 并重启 sshd 即可。

六、总结与行动建议

回顾全文的配置思路:内网服务一律不暴露公网,数据库用本地转发按需访问,临时演示用远程转发且用完即关,批量浏览用动态转发,多机管理交给 ProxyJump 跳板机。这套组合的关键在于收敛——所有访问都汇聚到一个 SSH 端口上,安全边界清晰,审计也只需盯住一台机器的 /var/log/auth.log

如果你准备动手落地,建议按这个顺序推进:

  • 先给入口机配好密钥登录并禁用密码,这是所有后续操作的地基
  • 再验证一条本地转发到数据库的隧道,跑通最小闭环
  • 然后把内网机器全部写入 ~/.ssh/configProxyJump 拓扑
  • 最后用 autossh 或 systemd 固化常用隧道,并用 rsync 与 crontab 异地备份 给跳板机自身的配置文件做定期备份

入口机的选择上,一台低配但网络质量稳定的 Hostease VPS 就足够承担跳板机角色;如果内网规模较大、需要更高并发的转发吞吐,再考虑独立服务器。配置完成后,建议每季度复查一次 sshd_config 与防火墙规则,确认没有多余的端口悄悄打开。

SSH 安全访问内网服务的完整配置流程清单图

发表评论