富阳说:做 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 的安全基础设施。
不要把所有服务暴露到公网。
让服务隐藏起来。
通过身份建立访问通道。
这可能是个人开发者构建安全云基础设施最简单、性价比最高的一步。
文中的服务器地址、用户名、密钥名称均为示例,实际生产环境信息已脱敏。