SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-28

如何在VPS上私密运行DeepSeek Harness

在Linux VPS上安装DeepSeek Harness,固定npm版本并配置模型,了解插件权限风险,通过SSH隧道安全访问3080端口Web UI,避免公开无密码服务。

DeepSeek Harness 是什么

DeepSeek Harness(dsh)是一个 Node.js agent runtime,可运行在 VPS(virtual private server)上。安全的运行方式是将其绑定到 127.0.0.1,然后让浏览器通过 SSH(secure shell)隧道访问它。它会在 3080 端口提供 Web UI(user interface),而不是运行在终端中。该 Web 服务器本身不要求密码,因此公开 3080 端口后,任何找到它的人都可能获得一个能够读取您的文件并以 Linux 用户身份执行命令的 agent。

DeepSeek 于 13 August 2026 以 MIT licence 发布了该项目,npm package 为 @deepseek-ai/dsh。项目将自身描述为 developer preview,并说明预计会出现不兼容的变更。下面的每个版本号都基于 August 2026 的快照,因此在将这些内容复制到重要服务器之前,请先检查代码仓库。

整个设计始终围绕一个理念展开:一切都是插件。模型适配器、工具注册表、会话日志、沙箱、调度器以及代理循环本身,都是加载到同一共享上下文中的插件,任何一个都可以替换。不存在一个由插件进行装饰的特权核心。这正是该测试框架值得尝试的原因,也是真正的风险所在。是否值得接受这一取舍,取决于您将它与什么进行比较;它与 Claude Code 和 Omnigent 的对比将这种“一切皆插件”的设计,与另外两种关于模型耦合方式、许可证以及各自需要占用多少 VPS 资源的方案并列比较。

Harness 不是模型

Harness 负责运行代理循环。推理在其他位置的模型中进行,因此在为它提供 API(应用程序编程接口)密钥,或提供由您自行托管的模型端点地址之前,任何操作都无法正常工作。本文中的所有内容都属于 harness 配置,而不是模型行为;在花费一个下午排查问题来源之前,最好先理清这两者之间的界线

您可以在 UI 的 Settings,然后是 Models 中进行配置。目录为主要 API 提供商(DeepSeek、OpenAI、Anthropic)提供了现成卡片,您只需粘贴密钥。“Add a custom provider”是更值得关注的选项:它需要提供商 ID、显示名称、基础 URL、API 协议和凭据,并使用 OpenAI 兼容协议,因此任何实现该协议的网关或本地服务器都可以使用。自定义提供商还可以查询 OpenAI 兼容的 GET /models 端点,自动填充模型列表。

这样,您就可以让 harness 使用同一 VPS 上的模型。Ollama 在 http://127.0.0.1:11434/v1/ 提供 OpenAI 兼容 API。API key 字段需要填写任意字符串,按照惯例使用 ollama,因为该字段是必填项,之后会被忽略。选择一个足够小、能够运行在 VPS 上的模型并不难;难点在于它是否足以驱动代理,而Ollama 与 vLLM 作为本地模型服务器的区别决定了答案需要占用多少 RAM。

在 UI 中输入的密钥只能写入,不能读取。Harness 将密钥存储在 $DSH_HOME/.credentials.yaml 中,并仅在 settings.yaml 中保留凭据引用。$DSH_HOME 默认设置为 ~/.dsh。请将该文件当作密码文件处理,因为它本身就是密码文件:任何能读取它的人都可以消耗您的 API 配额。如果您希望直接编辑这些文件,而不是通过 Settings 页面操作,dsh 配置文件、密钥和模型端点的 walkthrough会说明每个键的作用,以及不同模式下哪些内容会离开您的服务器。

安装前的准备

  • 运行 Ubuntu 24.04 或其他当前版本 Linux 的 VPS,并可通过 SSH 访问
  • Node.js 22.19 或更高版本的 22.x 版本,或 Node.js 24 及更高版本。这是项目构建和测试所使用的版本
  • 普通用户账户,而不是 root,因为代理会以启动进程的用户身份运行 shell 命令
  • 如果计划安装插件,请确保 pnpm 位于 PATH 中,因为插件命令会调用它
  • 在防火墙和服务商单独提供的网络防火墙中关闭端口 3080

Ubuntu 自带的 nodejs 软件包版本低于运行测试框架的要求,因此应从 NodeSource 或 nvm 安装 Node,不要使用 apt install nodejs。如果 VPS 是新建的,建议先加固 SSH,这只需十分钟。因为接下来要依赖的隧道,其安全性取决于后端的 SSH 服务器。

在 VPS 上安装 DeepSeek Harness,并固定到一个版本

node --version
npx @deepseek-ai/dsh@0.1.0-rc.6 web

npx 会下载软件包并运行其 dsh 二进制文件。web--profile web 的别名,后者会启动浏览器应用;进程会输出它正在监听的地址。默认值为 http://127.0.0.1:3080。这些数字是绑定配置,而不是外观上的默认值。为什么 dsh 会输出环回地址介绍了 Harness 在你从笔记本电脑查找它之前会响应和不会响应哪些请求。

固定版本。npx @deepseek-ai/dsh web 会解析 latest 标签在执行命令时所指向的版本,而项目已经发布了多个候选版本,并表示即将进行不兼容更改。0.1.0-rc.6 是 13 August 2026 当天 latest 所指向的版本。固定版本后,今天配置的服务器下个月仍会保持相同行为。这样,升级会成为你主动做出的决定,而不是事后才发现的意外。当固定版本的命令仍然启动了错误的构建,或完全拒绝安装时,常见的 dsh 安装和版本错误介绍了如何清理 npx 缓存,以及如何检查 Node 打包的 npm。

日常使用时,只安装一次,不要在每次启动时重新解析版本。

npm install -g @deepseek-ai/dsh@0.1.0-rc.6
dsh --profile web --help

第二行命令值得执行,因为启动器和 Web 应用使用的是两组独立的选项。dsh --help 显示启动器自身的选项。dsh --profile web --help 显示 Web 应用接受的标志,其中包括 --port--host 和可重复指定的 --trusted-host

现在确认它监听的地址。

ss -tlnp | grep 3080

本地地址列应显示 127.0.0.1:3080。如果显示 0.0.0.0:3080,则表示 UI 可从互联网访问。此时应先停止该进程,再进行其他操作。

为什么绝不能发布端口 3080

Web 服务器没有身份验证层。其配置只暴露监听主机和监听端口。这就是全部的攻击面。对于非回环部署,访问控制由单独的受信任主机设置负责,而不是登录界面。

现在再看该端口后面的内容。代理会编辑工作区中的文件并运行 shell 命令,而您的提供商凭据就存储在旁边的磁盘上。因此,开放的端口 3080 等同于一个带聊天界面的远程 shell。它以启动代理的用户身份运行,并附带您的 API 密钥。攻击者不需要利用漏洞。他们只需要知道端口号。主机上线后,扫描器通常会在数小时内发现端口。

CLI(命令行界面)也遵循这一原则。截至 0.1.0-rc.6,它明确不支持 --host 0.0.0.0,而是退出并显示用法错误,不会启动。这个拒绝行为是安全功能,因此不要尝试寻找删除该限制的补丁。

当隧道不适用时,以下两种部署方式也合理。将主机接入私有覆盖网络,使其只拥有您自己的设备能够路由到的地址;自托管 Headscale 控制服务器即可实现这一点。或者在端口 3080 前放置一个反向代理,在请求到达该端口之前完成身份验证,例如使用 Authentik 单点登录服务器执行 forward auth。前面没有身份验证的反向代理不是安全控制。它只是一个更长的 URL。

通过 SSH 隧道访问 Web UI

在笔记本电脑上运行此命令,不要在服务器上运行。

ssh -N -L 3080:127.0.0.1:3080 you@your-server

-L 会在笔记本电脑上打开 3080 端口,并通过加密的 SSH 会话转发所有连接到该端口的流量。127.0.0.1:3080 部分会在服务器上解析,因此连接会从回环地址到达 harness,效果与您直接坐在这台机器前操作完全相同。-N 表示不要启动远程 shell,因为您只需要端口转发。

然后在本地浏览器中打开 http://127.0.0.1:3080。如果笔记本电脑上的 3080 端口已被占用,请修改左侧的端口号:ssh -N -L 3180:127.0.0.1:3080 you@your-server,然后访问 http://127.0.0.1:3180。左侧的数字表示本地端口,右侧的数字表示服务器端口,因此只需修改左侧数字。

将其保存到 ~/.ssh/config,以后无需再次输入。

Host dsh
  HostName 203.0.113.10
  User deploy
  IdentityFile ~/.ssh/id_ed25519
  LocalForward 3080 127.0.0.1:3080

之后,ssh -N dsh 会启动隧道。浏览器报告连接被拒绝,通常表示隧道已建立,但远端没有进程监听该端口,因为无论 harness 是否运行,SSH 都会转发该端口。使用上面的 ss 命令检查服务器。

在退出登录后保持 harness 运行

npx 命令会随 shell 一起退出。systemd 用户服务可以持续运行,并在 harness 崩溃或系统重启后将其重新启动。这里的单元配置有意保持精简;如果您希望 harness 使用单独的受限账户运行,在单元中固定版本,并生成便于检索的日志,请参阅dsh 的无头 systemd 配置,其中提供了完整说明。

loginctl enable-linger $USER
mkdir -p ~/.config/systemd/user
command -v dsh

enable-linger 很重要,因为用户服务通常会在最后一个会话结束时停止。如果未启用它,关闭隧道后 harness 会立即退出。使用 command -v dsh 输出的绝对路径,并将其填入单元配置,因为 systemd 不会搜索登录 shell 构建的 PATH。

[Unit]
Description=DeepSeek Harness web UI
After=network-online.target

[Service]
Type=simple
WorkingDirectory=%h/projects/site
ExecStart=/usr/local/bin/dsh web
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target

WorkingDirectory 不是装饰性配置。dsh 进程会将启动目录作为默认文件系统位置,因此服务在错误目录中启动时,代理会使用错误的默认工作区。您仍然可以在 UI 中选择工作区。

systemctl --user daemon-reload
systemctl --user enable --now dsh
systemctl --user status dsh

拒绝启动的单元几乎总是使用了错误的 ExecStart 路径,或者二进制文件不接受当前的 Node 版本;journalctl --user -u dsh -n 50 会指出具体原因。同样的模式也适用于让 VPS 上的任意编码代理持续运行,失败模式也相同。

插件允许执行的操作

插件是一个向共享上下文提供服务、类型化事件和可逆效果的模块。以下扩展点需要重点了解:

  • ctx.llm 上注册模型提供程序
  • ctx.tools 上添加面向模型的工具
  • 提供 ctx.shell 背后的 shell 后端
  • 提供文件系统访问或 ctx.fs 背后的策略
  • ctx.commands 上注册用户命令
  • 通过 ctx.jobs 执行后台任务
  • 使用 ctx.sandbox 后端封装所生成的进程
  • 通过 agent/*tools/* 事件拦截请求和工具调用
  • 扩展持久化会话状态
  • 通过 ctx.agents 驱动用户界面

请从攻击者的角度理解这份列表。插件可以提供文件系统层和 shell 层,也可以介入模型发起的每一次工具调用。插件与这些接口之间没有权限确认对话框,因为插件就是普通的 Node 代码,会与其他所有代码加载到同一进程中。安装插件就等于以代理的权限运行陌生人的代码,而代理的权限就是您的 Unix 用户权限。

这与将 MCP 服务器连接到 VPS 上的代理时所做的是同一个信任决策,其中 MCP 是模型上下文协议。正因如此,在 VPS 上安全运行编码代理时,首先要关注它运行所用的账户,而不是模型本身;这也解释了为什么 npm 供应链攻击会严重影响服务器:安装步骤就是遭到入侵的环节,而且不会弹出任何提示。

插件从哪里获取

插件存放在配置集中。配置集是在 $DSH_HOME 下保存的命名组合,默认路径为 ~/.dsh。每个配置集目录都包含该配置集安装的非树内插件。CLI 会将您的参数直接转发给 pnpm,并以配置集目录作为工作目录。

dsh plugin --profile web add github:deepseek-harness/turtle-ui
dsh plugin --profile web remove turtle-ui

由于参数会原样传递给 pnpmaddremoveupdatewhy 的行为与任何 pnpm 项目中的行为相同,插件可以是 npm 软件包,也可以是 GitHub 引用。必须先确保 pnpm 位于 PATH 中。在 Node 22 及更高版本中,corepack enable pnpm 会将其放入 PATH。

插件通过 GitHub 主题进行发现。插件作者会将 dsh-plugin 主题添加到自己的仓库,您可以浏览该主题来查找现有插件。主题是作者为自己的仓库设置的标签。没有人审核主题,也没有人为其签名;主题页面按星标数排序,而星标数反映的是受欢迎程度,不是安全性。

以下 4 个习惯可以让管理过程更可控。安装前先阅读源代码,因为大多数插件都很小,十分钟内即可读完。固定使用确切版本或提交,不要跟踪分支。在您愿意重建的 VPS 上,使用不拥有其他资源的用户运行测试框架。为代理单独创建 API 密钥并设置独立的消费限额,不要使用生产服务所用的密钥。阅读插件并想了解哪些文件存在风险时,dsh 插件审核指南会逐一介绍清单、入口点以及插件注册的扩展点。

如果您希望在确定方案前先比较不同设计,Omnigent 多代理 harness 通过不同的结构解决同一问题;一旦启用插件,各方案的取舍就会很明显。如果您最终没有选出唯一方案,而是在同一台主机上保留其中两个或三个,将所有 harness 放在一个自托管 API 后面 可以省去为每个端口分别建立隧道,但需要额外运行一个服务,并在第一天就让它绑定到 loopback,同时设置真正的密码。

首先会出现什么问题

Node 版本过旧。 项目要求 Node 22.19 以及 22.x 系列中的更高版本,或 Node 24 及更高版本,CI 也会使用这些版本进行测试。旧版运行时会在启动时失败,因为代码使用了该版本不支持的语法和 API。先运行 node --version

3080 端口已被占用。 占用者可能是第二个 harness、残留进程,或同样使用 3080 端口的其他应用。使用 ss -tlnp | grep 3080 查找占用进程,然后停止该进程,或使用 dsh web --port 3180 在其他端口启动 harness。--port 属于 Web 应用,因此应在 web 之后执行。

浏览器无法通过隧道连接。 确认访问的是 127.0.0.1,而不是服务器的公网地址,因为转发端口只存在于您的笔记本电脑上。然后确认 harness 正在服务器上监听,因为无论远端是否有服务响应,SSH 都会建立端口转发。

dsh plugin 立即失败。 该命令是 pnpm 的封装,因此如果找不到 pnpm 二进制文件,它会在任何插件工作开始前停止。

agent 无法看到您的项目。 工作区默认使用进程启动时所在的目录,因此,如果单元的 WorkingDirectory 是您的主目录,agent 获取到的就是您的主目录。在 UI 中选择工作区,或修复该单元后重新加载。

FAQ

将 DeepSeek Harness Web UI 暴露在端口 3080 上是否安全?

不安全。Web 服务器没有内置登录功能,其背后的代理会以启动进程的用户身份编辑文件并运行 shell 命令,而您的提供商 API 密钥也存储在同一磁盘上。将监听器保持在 127.0.0.1,并通过 SSH 隧道访问。私有覆盖网络,或在请求到达该端口前对每个请求进行身份验证的反向代理,也可以使用。截至版本 0.1.0-rc.6,CLI 会拒绝 --host 0.0.0.0,并以用法错误退出;这说明作者如何看待这种做法。

我需要 DeepSeek API 密钥,还是可以使用本地模型?

两者都可以,因为 harness 是运行时,而不是模型。在 Settings 中进入 Models,您可以将密钥粘贴到目录提供商卡片中,也可以选择 "Add a custom provider",并为其提供一个使用 OpenAI 兼容协议的 base URL。本地 Ollama 服务器在 http://127.0.0.1:11434/v1/ 上响应,并接受 API key 字段中的任意字符串。密钥会写入 $DSH_HOME/.credentials.yaml,其默认值为 ~/.dsh/.credentials.yaml

安装 DeepSeek Harness 插件后,插件实际获得了什么权限?

运行 harness 的账户所拥有的权限。插件是加载到同一进程中的 Node 代码,其扩展点包括 shell 后端、文件系统层、工具注册表,以及包装每次工具调用的事件。除非插件自行提供沙箱,否则没有任何机制能将插件与这些接口隔离。安装前先阅读源代码,并以一个不拥有任何重要资源的用户运行 harness。

我应该安装哪个版本?它能持续正常工作吗?

安装精确版本,例如 npx @deepseek-ai/dsh@0.1.0-rc.6 web。13 August 2026,latest 标签指向的就是该版本。该项目将自身称为开发者预览版,并表示预计会发生破坏兼容性的变更,因此未固定版本的命令可能每天表现不同。升级前检查代码仓库,并预计在版本仍以 0 开头期间,配置键和插件接口可能发生变化。