ChatGPTClaudeGrok / X / CursorGemini

DeepSeek Harness 公网访问怎么配?public-url、trusted-host 与 TLS 三件套

配置与使用发布于 2026-10-21作者: DeepSeek Plugin 插件市场
DeepSeek Harness公网部署反向代理trusted-hostTLS
DeepSeek Harness 对外发布要同时配三样:--public-url 公告外部地址,--trusted-host 放行浏览器 authority,TLS 负责加密与 Secure cookie。三者缺一,常见结果是页面能开但所有 API 都 403。

DeepSeek Harness 的公网访问要同时配三样:--public-url 负责公告外部地址,--trusted-host 负责放行浏览器 authority,TLS 负责加密与 Secure cookie。 三者不是替代关系。只配 public-url,所有 API 会 403;只配 trusted-host,打印出来的地址还是错的;只配 TLS,子路径部署仍会在 cookie 上翻车。这篇按“公告 → 放行 → 代理配合”讲清顺序。

DeepSeek Harness:--public-url 公告什么、不公告什么

--public-url 只影响对外展示,不改变监听器实际提供的路由。 官方给的范围很具体:(来源)

被公告的位置用途
启动时打印与自动打开的 URL让你直接复制到浏览器
DSH_WEB_URL给外部脚本与集成读取
agent 运行时上下文中的 Web GUI URL让 Agent 知道外部入口

它接受 http:// 或 https:// 根,可以带挂载前缀,并会归一化成以 / 结尾。监听器仍然只提供 origin-root 路由,从不理解 /ui 这类挂载段。换句话说:public-url 是“告诉别人我在哪”,不是“让监听器搬到那个路径下”。

最常见的错误是把 --public-url 当成信任授权。官方写得很清楚:公告 URL 与栅栏是两件事,公告不等于接纳。

DeepSeek Harness:--trusted-host 放行哪个 authority

浏览器使用的 authority 只要不在栅栏名单里,每个 /api 调用都会 403,代理配得再正确也没用。 栅栏默认接受三类来源:(来源)

  1. loopback — 本机直接访问 127.0.0.1 或 localhost。
  2. 监听器自身的绑定地址 — 监听在哪个地址,就接受哪个地址。
  3. --trusted-host 列出的条目 — 可重复传入,不带端口时匹配任意端口,适合每次绑定不同端口的隧道。

配置时按下面做:

sh
dsh web \
  --public-url https://app.example/ui/ \
  --trusted-host app.example
  1. 先确认浏览器地址栏的 authority — 是 app.example 还是 app.example:8443。预期:填进 --trusted-host 的值与实际访问完全一致。
  2. 不带端口就匹配任意端口 — 隧道场景可以只写主机名。预期:端口变化后不必改参数。
  3. 重启后复验 — 打开带令牌的地址,再打开开发者工具看 /api 请求。预期:不再出现 403;若仍是 403,检查是不是代理改写了 Host。

栅栏只负责放行请求,真正的认证仍由启动令牌与签名会话 cookie 完成。TLS 在哪里终止都不改变这套判断。

DeepSeek Harness:反向代理必须配合的五件事

代理不是“转发一下”就完了;官方列了五项硬要求,漏任何一项都会表现成登录失败或接口 403。 逐项核对:(来源)

  1. 保留浏览器可见的 Host — 栅栏拿收到的 Host 与 authority 比对,代理不要改写成监听器地址。预期:后端日志里看到的 Host 是外部域名。
  2. 剥离挂载前缀 — 监听器应答 origin-root 路由,/ui/api/... 必须以 /api/... 抵达。预期:代理规则里只有转发前 rewrite,不在后端加前缀。
  3. 转发升级请求 — 页面发出的每个请求与 WebSocket 升级都要带 Upgrade 与 Connection 头抵达监听器。预期:实时连接不断开。
  4. 改写 cookie 作用域 — 后端签发的是 Path=/ 的 host-only cookie;代理要把 Path 改成 /ui/,并只在 HTTPS 链路上补 Secure。预期:浏览器只在该子路径回传 cookie。
  5. 重定向裸挂载 — /ui 要以 /ui/ 抵达;只有 /ui/ 会把启动 token 换成会话 cookie,持有 cookie 后 /ui/index.html 也能取文档。预期:访问 /ui 不会 404。

这五项里,第 1 项和第 4 项最容易漏。前者导致 403,后者导致“登录成功但下一页又回登录页”。

这三处最容易在“页面能开”之后才暴露,且都不属于 TLS 握手问题。 逐项看:(来源)

  1. Host 必须原样保留 — 栅栏拿收到的 Host 与 authority 比对;代理改写成监听器地址后,外部域名就不在名单里。预期:后端看到的是浏览器地址栏里的 authority。
  2. /ui 必须变成 /ui/ — 只有 /ui/ 会把启动 token 换成会话 cookie;已持有 cookie 的浏览器也能用 /ui/index.html。预期:访问裸挂载不会 404。
  3. cookie 的 Path 与 Secure 分开处理 — 后端签发 Path=/ 的 host-only cookie;代理改 Path 为挂载路径,并只在 HTTPS 链路上补 Secure。预期:浏览器只在子路径回传 cookie,且不会通过 HTTP 泄露。

还有一个边界:公告 URL 与栅栏都不保护监听端口。端口必须限制在可信代理或内网内,不能因为“有 TLS”就认为可以裸奔。

TLS 可以终止在代理、终止在监听器,或两者都终止;区别在于 Secure 由谁加、cookie 的 Path 由谁改。 三种组合:(来源)

组合证书在哪cookie 处理
代理终止 TLS代理代理改 Path,并在 HTTPS 链路补 Secure
dsh web 原生 TLS监听器监听器直接签发带 Secure 的 cookie,代理只改 Path
两端都终止代理与监听器两段都加密,按各自链路分别处理

原生 TLS 用 --tls-cert 与 --tls-key,证书要带完整链、私钥不带口令,文件只在启动时读一次。它不会自动续期,也不会监视文件变化;换证书要重启或重新加载监听器。

无论哪种组合,面向浏览器的外部链路都应是 HTTPS。用 http:// 根会明文暴露启动令牌,而令牌就是进程凭据。

DeepSeek Harness:上线前的检查清单

把“能打开”与“能正常用”分开验证,才不会把 403 误判成 TLS 问题。 按下面顺序过一遍:(来源)

  1. 本机直连 — curl -vk https://127.0.0.1:3080/。预期:TLS 握手成功。
  2. 代理转发 — curl -v https://app.example/ui/。预期:返回页面,不出现 502。
  3. 检查响应头 — 看 Set-Cookie 的 Path 与 Secure。预期:Path 是 /ui/,HTTPS 下有 Secure。
  4. 看 API — 浏览器开发者工具里挑一个 /api 请求。预期:200,不是 403。
  5. 看 WebSocket — 观察实时输出是否持续刷新。预期:连接保持,不反复重连。

如果第 1 步通过、第 2 步通过、第 4 步 403,基本就是 --trusted-host 或 Host 改写;如果第 3 步 cookie 不对,就是代理的 Path/Secure 改写漏了。

DeepSeek Harness 常见问题

Q:--public-url 能不能只写域名不写协议? 不能。官方要求 http:// 或 https:// 根;缺协议时无法归一化,也无法正确生成外部 URL。

Q:能不能用 IP 访问? 可以,但 --trusted-host 要写浏览器实际使用的 IP authority,证书也要覆盖该 IP,否则名称校验会失败。

Q:栅栏会不会保护监听端口? 不会。官方明确说,公告 URL 与栅栏都不保护监听端口本身;端口应限制在可信代理或内网内,不要直接暴露到公网。

一句话收束: 公网访问不是“加个反代”就完事,而是公告地址、信任名单、TLS 与 cookie 路径四件事对齐;403 先查 authority,登录循环先查 cookie Path。

ChatGPTClaudeGrok / X / CursorGemini

常见问题

DeepSeek Harness 的 --public-url 和 --trusted-host 到底有什么区别?

DeepSeek Harness 里,--public-url 只公告外部访问地址,影响打印的启动 URL、DSH_WEB_URL 与 agent 运行时上下文;--trusted-host 才决定 /api 信任栅栏放行哪个浏览器 authority。只配 public-url 不会让请求通过栅栏,未列入 trusted-host 的域名仍会收到 403。

dsh web 挂在反向代理子路径 /ui/ 下,代理必须做哪几件事?

DeepSeek Harness 里,代理要原样保留浏览器可见的 Host,剥离 /ui 前缀后再转发到监听器,转发 Upgrade 与 Connection 头,把 cookie 的 Path 从 / 改写为 /ui/ 并在 HTTPS 链路上补 Secure,还要把 /ui 重定向到 /ui/,否则启动令牌无法换成会话 cookie。

为什么 DeepSeek Harness 公网部署后页面能打开,但每个 API 都返回 403?

DeepSeek Harness 里,这是信任栅栏在拦,不是认证失败。栅栏只接受 loopback、监听器绑定地址和 --trusted-host 列出的 authority;浏览器通过其他域名访问时,即使代理与 TLS 都正常,每个 API 调用也会 403。把地址栏里的 authority 原样加进 --trusted-host 再重启。

公网部署时 TLS 应该由 dsh web 终止还是交给反向代理?

DeepSeek Harness 里,两种都支持。交给代理适合统一域名、WAF 与多后端;让 dsh web 用 --tls-cert/--tls-key 自己终止适合单入口部署。无论谁终止,TLS 监听一侧都会给会话 cookie 加 Secure,浏览器侧链路应保持 HTTPS。

--public-url 配成 http:// 会有什么风险?

DeepSeek Harness 里,面向浏览器的 http:// 根会明文暴露启动令牌。启动令牌能换取会话 cookie,等于进程凭据;应使用 https:// 的外部根,并且不要把带 token 的打印地址转发给非预期用户。

相关术语

--public-url
--public-url 是 dsh web 的公告参数,接受可带挂载前缀的 http:// 或 https:// 根并归一化为以 / 结尾;它只影响对外展示与运行时上下文,不改变监听器提供的 origin-root 路由。— DeepSeek Harness 官方文档 - 在反向代理之后发布 Web UI
信任栅栏
信任栅栏是 dsh web 对 /api 请求做的 Host 与 authority 校验,只接受 loopback、监听器绑定地址以及 --trusted-host 列出的条目;不匹配时所有 API 调用返回 403。— DeepSeek Harness 官方文档 - 在反向代理之后发布 Web UI
挂载前缀
挂载前缀是反向代理把 Web UI 暴露在子路径(例如 /ui/)时使用的路径段。监听器只提供 origin-root 路由,因此代理必须在转发前剥离该前缀。— DeepSeek Harness 官方文档 - 在反向代理之后发布 Web UI
启动令牌
启动令牌是 dsh 进程每次启动生成、只打印一次的凭据,访问带 token 的根地址会把它换成签名会话 cookie;令牌不持久化,也不应转发给非预期用户。— DeepSeek Harness 官方文档 - 在反向代理之后发布 Web UI

来源