我关闭了服务器所有端口,只通过 SSH 隧道访问服务:一个被低估的安全神器

2026年8月22日·富阳说
已发布

富阳说:做 1000 个 AI 工具,让每个人享受 AI 便利。

从部署 DeepSeek Harness(DSH)到数据库迁移,我重新认识了 SSH Tunnel。

最近在服务器上折腾一个东西。

起因很简单:

我想把 DeepSeek Harness(DSH)部署到服务器上,让 AI Agent 可以在后台长期运行任务。

理想状态:

本地电脑
  |
  |
服务器
  |
  |
AI Agent 持续执行任务

服务器负责运行任务,我本地负责管理。

但是部署过程中遇到了一个问题:

服务到底应该如何访问?

一个常见问题:是否应该开放公网端口?

DSH 部署完成后:

服务器

  DSH
  |
  127.0.0.1:3080

服务正常运行。

按照传统思路:

开放端口。

例如:

服务器公网IP:3080

浏览器直接访问。

看起来很简单。

但是很快发现问题:

管理服务不应该暴露公网

DSH 本质是 AI Agent 管理工具。

它涉及:

  • 任务执行
  • 工具调用
  • 文件操作
  • 项目访问

这类服务并不是给互联网用户访问的。

如果直接暴露:

Internet

  ↓

  3080

  ↓

  DSH

意味着:

任何人都可以探测这个入口。

很多内部服务其实都不应该公网开放

类似:

  • Jenkins
  • Grafana
  • Adminer
  • 数据库管理后台
  • Redis
  • 内部 API
  • AI Agent 控制面板

它们真正的定位应该是:

内部服务。

而不是公网服务。

于是我问 AI:

有没有一种方式:

服务继续运行在服务器,但是不开放公网端口,我自己还能访问?

答案:

SSH Tunnel(SSH 隧道)。

这也是这篇文章的起点。

SSH 不只是登录服务器

很多人理解 SSH:

ssh user@server

就是:

登录服务器。

但是 SSH 还有一个非常强大的能力:

端口转发。

SSH 可以建立一个加密通道,把服务器内部服务安全映射到本地。

案例一:SSH 隧道访问 DSH

服务器:

ECS

  SSH:
  22

  DSH:
  127.0.0.1:3080

安全组:

22     开放
3080   关闭

公网无法访问:

http://服务器IP:3080

但是本地执行:

ssh \
  -i ~/keys/demo-server.pem \
  -fN \
  -o ServerAliveInterval=60 \
  -o ServerAliveCountMax=3 \
  -o ExitOnForwardFailure=yes \
  -L 3080:127.0.0.1:3080 \
  ubuntu@example-server

然后浏览器访问:

http://localhost:3080

即可访问服务器上的 DSH。

它到底发生了什么?

很多人第一次都会疑惑:

3080 没开放,为什么还能访问?

因为实际链路不是:

浏览器

  ↓

  服务器:3080

而是:

浏览器

  ↓

  本地:3080

  ↓

  SSH 客户端

  ↓

  服务器:22

  ↓

  SSH 隧道

  ↓

  服务器127.0.0.1:3080

公网看到的只有:

SSH 22

并不知道服务器内部还有:

3080
3306
6379
8080

为什么安全组关闭端口依然可以?

安全组控制:

公网 → 服务器网卡

SSH 隧道:

第一段:

公网 → SSH 22

通过安全组。

第二段:

服务器内部 → localhost 服务

属于服务器内部通信。

所以:

22      开放
3080    关闭
3306    关闭
6379    关闭

依然可以访问。

SSH Key:为什么生产环境不用密码?

SSH 隧道依赖 SSH,而 SSH 最推荐的认证方式是:

密钥认证。

很多人刚开始使用:

ssh root@server

然后输入密码。

但是生产环境不推荐。

密码登录的问题

1. 容易被暴力破解

公网服务器每天都会收到大量扫描:

攻击者

  ↓

  SSH 22 端口

  ↓

  尝试用户名密码

2. 自动化困难

CI/CD、数据库迁移、自动化部署都需要无人值守执行。

密码无法很好支持自动化。

SSH Key 是什么?

SSH 使用非对称加密:

本地保存:

私钥 Private Key

服务器保存:

公钥 Public Key

关系:

你的电脑

  private key

  ↓

  服务器

  public key

登录时:

服务器验证:

你是否拥有对应私钥。

验证成功:

建立连接。

生成密钥:

ssh-keygen -t ed25519

生成:

id_ed25519

私钥:

不要泄露。

以及:

id_ed25519.pub

公钥:

上传服务器。

PEM 文件是什么?

云服务器创建时经常会看到:

xxx.pem

例如:

demo-server.pem

它本质就是 SSH 私钥文件。

登录:

ssh -i demo-server.pem ubuntu@example-server

即可完成身份认证。

为什么 PEM 比密码更适合生产?

因为:

1. 不需要输入密码

自动化流程:

代码提交

  ↓

  CI/CD

  ↓

  SSH Key

  ↓

  服务器部署

无需人工输入。

2. 更容易权限管理

可以为不同用途创建不同 Key:

deploy.pem

  应用部署


  migration.pem

  数据库迁移


  backup.pem

  备份任务

案例二:数据库迁移同步

最近做 CI/CD 部署时,遇到了另一个实际场景。

数据库运行在另一台云服务器。

传统方式:

为了迁移方便,开放数据库端口:

公网

  ↓

  3306

  ↓

  MySQL

看起来方便。

但是数据库直接暴露公网。

更安全的方式:

数据库服务器:

MySQL

  127.0.0.1:3306

安全组:

3306 关闭

创建专用 SSH Key:

migration.pem

只用于建立隧道。

建立:

ssh \
  -i migration.pem \
  -N \
  -L 13306:127.0.0.1:3306 \
  deploy@example-server

迁移工具连接:

127.0.0.1:13306

实际上访问:

服务器 MySQL

安全提升在哪里?

以前:

公网

  ↓

  3306

  ↓

  MySQL

数据库暴露。

现在:

公网

  ↓

  SSH 22

  ↓

  身份认证

  ↓

  SSH Tunnel

  ↓

  MySQL

数据库:

  • 不暴露公网
  • 不接受公网连接
  • 只有拥有 SSH Key 的机器可以访问

更进一步:限制 SSH Key 权限

不要所有操作共用一个:

admin.pem

更推荐:

deploy.pem

  部署

migration.pem

  数据库迁移

backup.pem

  备份任务

每个 Key 负责不同事情。

例如:

数据库迁移账号:

允许:

SSH Port Forwarding

禁止:

Shell 登录

即使密钥泄漏:

攻击者也不能直接登录服务器操作。

SSH Tunnel 的三个常见模式

1. Local Forward (-L)

最常用:

本地 → 服务器内部

例如:

localhost:13306

  ↓

  服务器 MySQL:3306

2. Remote Forward (-R)

反向隧道:

服务器 → 本地

类似内网穿透。

3. Dynamic Proxy (-D)

SOCKS 代理:

本地应用

  ↓

  SSH

  ↓

  服务器出口

对 AI Agent 时代的意义

未来个人开发者会运行越来越多:

  • AI Agent
  • 自动化任务
  • 私有知识库
  • 数据处理服务
  • 自动部署系统

这些服务:

需要访问。

但是不应该暴露公网。

更合理的模型:

Internet

  ↓

  SSH Key 身份认证

  ↓

  服务器

  ↓

  内部服务

  ↓

  最小权限账号

总结

这次部署 DSH 最大的收获,不只是安装了一个 AI 工具。

而是重新认识了 SSH。

以前:

SSH = 登录服务器

现在:

SSH = 一个轻量级安全访问网关

SSH Tunnel 结合:

  • SSH Key 身份认证
  • 端口隐藏
  • 加密传输
  • 最小权限账号

可以构建一套非常适合个人开发者、小团队、OPC 的安全基础设施。

不要把所有服务暴露到公网。

让服务隐藏起来。

通过身份建立访问通道。

这可能是个人开发者构建安全云基础设施最简单、性价比最高的一步。

文中的服务器地址、用户名、密钥名称均为示例,实际生产环境信息已脱敏。