From c4204017ebb8d2196bbc2c9765258ecbd8320c7b Mon Sep 17 00:00:00 2001 From: okxlin <61420215+okxlin@users.noreply.github.com> Date: Tue, 18 Aug 2026 09:38:07 +0800 Subject: [PATCH] Update deepseek-harness-workstation app (#5965) Expose trusted-proxy parsing with a private_ranges fallback so existing installs without the new environment key upgrade safely. Refresh the bilingual authentication, rate-limit, persistence, and workspace documentation. --- .../0.1.0-rc.6/.env.sample | 1 + .../0.1.0-rc.6/data.yml | 19 +++++++++++++++++++ .../0.1.0-rc.6/docker-compose.yml | 1 + apps/deepseek-harness-workstation/README.md | 19 ++++++++++++++----- .../latest/.env.sample | 1 + .../latest/data.yml | 19 +++++++++++++++++++ .../latest/docker-compose.yml | 1 + 7 files changed, 56 insertions(+), 5 deletions(-) diff --git a/apps/deepseek-harness-workstation/0.1.0-rc.6/.env.sample b/apps/deepseek-harness-workstation/0.1.0-rc.6/.env.sample index 9c1883d2d..5a841ad09 100644 --- a/apps/deepseek-harness-workstation/0.1.0-rc.6/.env.sample +++ b/apps/deepseek-harness-workstation/0.1.0-rc.6/.env.sample @@ -5,5 +5,6 @@ DSH_PUBLIC_URL=https://dsh.example.com DSH_AUTH_USERNAME=admin DSH_AUTH_PASSWORD=replace-with-a-unique-password-at-least-12-characters DSH_AUTH_TOKEN_LIFETIME=604800 +CADDY_TRUSTED_PROXIES=private_ranges DSH_TRUSTED_HOSTS= DOCKER_SOCK_PATH=/dev/null diff --git a/apps/deepseek-harness-workstation/0.1.0-rc.6/data.yml b/apps/deepseek-harness-workstation/0.1.0-rc.6/data.yml index f46114010..493a4cfdb 100644 --- a/apps/deepseek-harness-workstation/0.1.0-rc.6/data.yml +++ b/apps/deepseek-harness-workstation/0.1.0-rc.6/data.yml @@ -117,6 +117,25 @@ additionalProperties: value: "604800" - label: 30 days value: "2592000" + - envKey: CADDY_TRUSTED_PROXIES + type: text + required: true + default: private_ranges + edit: true + labelZh: 可信代理范围 + labelEn: Trusted Proxy Ranges + label: + en: Trusted Proxy Ranges + zh: 可信代理范围 + zh-Hant: 受信任代理範圍 + ja: 信頼済みプロキシ範囲 + ko: 신뢰할 수 있는 프록시 범위 + ru: Диапазоны доверенных прокси + ms: Julat Proksi Dipercayai + pt-br: Faixas de proxies confiáveis + description: + en: Use space-separated CIDRs or private_ranges. Keep private_ranges behind 1Panel/OpenResty; use none only when clients connect directly to Caddy. + zh: 使用空格分隔的 CIDR 或 private_ranges。通过 1Panel/OpenResty 反向代理时保留 private_ranges;仅在客户端直连 Caddy 时使用 none。 - envKey: DSH_TRUSTED_HOSTS type: text required: false diff --git a/apps/deepseek-harness-workstation/0.1.0-rc.6/docker-compose.yml b/apps/deepseek-harness-workstation/0.1.0-rc.6/docker-compose.yml index 025ace5d1..176a10495 100644 --- a/apps/deepseek-harness-workstation/0.1.0-rc.6/docker-compose.yml +++ b/apps/deepseek-harness-workstation/0.1.0-rc.6/docker-compose.yml @@ -14,6 +14,7 @@ services: - AUTH_USERNAME=${DSH_AUTH_USERNAME:-admin} - AUTH_PASSWORD=${DSH_AUTH_PASSWORD} - AUTH_TOKEN_LIFETIME=${DSH_AUTH_TOKEN_LIFETIME:-604800} + - CADDY_TRUSTED_PROXIES=${CADDY_TRUSTED_PROXIES:-private_ranges} - AUTH_COOKIE_INSECURE=false - DSH_TRUSTED_HOSTS=${DSH_TRUSTED_HOSTS:-} - PORT=8080 diff --git a/apps/deepseek-harness-workstation/README.md b/apps/deepseek-harness-workstation/README.md index f20a93805..c501a7615 100644 --- a/apps/deepseek-harness-workstation/README.md +++ b/apps/deepseek-harness-workstation/README.md @@ -2,24 +2,26 @@ ## 产品介绍 -DeepSeek Harness Workstation 是带网页登录、持久化开发目录和完整开发工具链的 DeepSeek Harness 工作站。镜像封装 DeepSeek Harness,由 Caddy Security 提供表单登录,适合部署在 1Panel OpenResty HTTPS 反向代理之后。 +DeepSeek Harness Workstation 是带网页登录、持久化开发目录和完整开发工具链的 DeepSeek Harness 工作站。镜像封装 DeepSeek Harness,由 [caddy-security](https://github.com/greenpau/caddy-security) 提供表单登录,并通过 [caddy-ratelimit](https://github.com/mholt/caddy-ratelimit) 在源站侧限制认证请求,适合部署在 1Panel OpenResty HTTPS 反向代理之后。 工作站包含 Node.js、pnpm、Python、Go、Rust、C/C++ 工具链,以及 Docker CLI、Compose 和 Buildx,支持 `amd64` 与 `arm64`。 ## 主要功能 - 支持浏览器密码管理器的表单登录 +- 按客户端 IP 的内置登录限速和可信代理链解析 - DeepSeek Harness Web UI、终端、会话、工具与 WebSocket - 持久化状态、用户 HOME 和工作区 - Docker CLI、Compose 与 Buildx,宿主 Docker 访问默认禁用 ## Introduction -DeepSeek Harness Workstation combines DeepSeek Harness, browser-based form authentication, persistent development directories, and a complete multi-language toolchain for deployment behind a 1Panel OpenResty HTTPS reverse proxy. +DeepSeek Harness Workstation combines DeepSeek Harness, browser-based form authentication, proxy-aware origin-side login rate limiting, persistent development directories, and a complete multi-language toolchain for deployment behind a 1Panel OpenResty HTTPS reverse proxy. ## Features - Password-manager-compatible browser login +- Built-in per-client login limits with trusted-proxy parsing - DeepSeek Harness Web UI, terminals, sessions, tools, and WebSockets - Persistent state, user home, and workspace directories - Docker CLI, Compose, and Buildx with host daemon access disabled by default @@ -54,10 +56,11 @@ http://127.0.0.1:56789 | `DSH_AUTH_USERNAME` | `admin` | 网页登录用户名 | | `DSH_AUTH_PASSWORD` | 无(必填) | 至少 12 个字符;请使用密码管理器生成并保存 | | `DSH_AUTH_TOKEN_LIFETIME` | `604800` | 登录令牌和 Cookie 的有效期,默认 7 天,可选最长 30 天;到期后需要重新登录 | +| `CADDY_TRUSTED_PROXIES` | `private_ranges` | Caddy 解析客户端 IP 时信任的代理 CIDR;空格分隔,客户端直连时可设为 `none` | | `DSH_TRUSTED_HOSTS` | 空 | 可选的附加可信主机 authority,逗号分隔 | | `DOCKER_SOCK_PATH` | `/dev/null` | Docker Socket 开关;选择 `/var/run/docker.sock` 后授予宿主 Docker 控制权 | -`AUTH_MODE=caddy-security`、`AUTH_COOKIE_INSECURE=false`、容器入口端口 `8080` 和遥测关闭开关由应用包固定。`AUTH_COOKIE_INSECURE` 不开放为表单选项,因为当前 Caddy Security 实现启用该值时会同时移除 Cookie 的 `Secure` 与 `HttpOnly` 属性,容易造成不必要的会话暴露。 +`AUTH_MODE=caddy-security`、`AUTH_COOKIE_INSECURE=false`、容器入口端口 `8080` 和遥测关闭开关由应用包固定。认证限流次数也由镜像固定,不作为安装表单参数。`AUTH_COOKIE_INSECURE` 不开放为表单选项,因为当前 caddy-security 实现启用该值时会同时移除 Cookie 的 `Secure` 与 `HttpOnly` 属性,容易造成不必要的会话暴露。 ## 数据持久化 @@ -71,12 +74,16 @@ http://127.0.0.1:56789 鉴权状态位于 `/data/auth`,Caddy 状态位于 `/data/caddy`,DeepSeek Harness 状态位于 `/data/dsh`。`/data`、`/home/node` 与 `/workspace` 都是直接挂载的真实目录,不使用符号链接。 +镜像工作目录和 `DSH_WORKSPACE` 都默认是 `/workspace`。网页的 **Add workspace** 对话框会从 `/workspace` 打开,其中的 `Home` 快捷入口也指向 `/workspace`;`/home/node` 仅作为用户 HOME 和工具持久卷,不是默认项目目录。 + 镜像以 root 启动,用于准备挂载目录权限、执行旧状态迁移和设置可选 Docker Socket 组,然后以 UID/GID `1000:1000` 运行 DeepSeek Harness 与 Caddy。首次启动时入口会把 HOME 和 workspace 准备为该用户可写,因此通常不需要手工执行 `chmod` 或 `chown`。 首次安装不需要预先创建 `./data/data`、`./data/workspace` 或 `dsh-home`。当前 Compose 使用的短语法 bind mount 会在源目录不存在时由 Docker 自动创建目录,`dsh-home` named volume 也会自动创建;镜像入口随后会规范化 bind 根目录和应用子目录的权限。因此不需要在 `init.sh` 中额外添加 `mkdir` 或递归 `chown`。 从旧版工作站布局升级时,如果 `/data/auth` 为空,镜像入口会在首次启动时把 `dsh-home:/home/node/.local/share/deepseek-harness` 中的旧鉴权、Caddy 和 DSH 状态复制到 `/data`。迁移不会删除旧 HOME 数据;请先备份 `./data/data` 和 `dsh-home`,确认新版本启动正常后再自行清理旧副本。 +从旧版 AppStore 包升级时,已有 `.env` 通常不包含 `CADDY_TRUSTED_PROXIES`。新 Compose 会自动使用 `private_ranges`,因此标准 1Panel/OpenResty 部署无需手工补写该变量,也不会改变 `/data`、`/home/node` 或 `/workspace` 的挂载和数据。升级后可在应用参数中按实际代理链调整该值。 + 1Panel 的应用备份覆盖应用安装目录,因此会包含 `./data/data` 和 `./data/workspace`。独立的 HOME named volume 不在应用目录内,升级、卸载或迁移前如需保留用户安装的工具和缓存,请停止应用并单独备份 `dsh-home`: ```bash @@ -113,9 +120,11 @@ Caddy Security 当前不会自动刷新访问令牌。默认登录有效期为 7 The local Caddy account database stores a bcrypt password hash and keeps its JWT signing key under `/data/auth`. To support the 1Panel password form, the submitted plaintext password remains in the panel-generated `.env` and Docker container configuration, where host root, 1Panel, and Docker administrators can read it; the image removes the value from the DSH and Caddy child-process environments after startup. -镜像不额外内置登录限速插件。公网部署请在 Cloudflare、1Panel WAF 或外层 OpenResty 对 `/auth/login` 和 `/auth/sandbox/*` 设置限速;使用基于客户端 IP 的规则前,请先正确配置可信真实客户端 IP 转发链。 +镜像会按解析后的客户端 IP 对用户名阶段 POST 限制为每分钟 30 次,对密码阶段 POST 限制为每 10 分钟 10 次;被拒绝的请求返回 HTTP 429 和 `Retry-After`。这些额度是镜像固定值,修改它们需要自定义构建镜像。仍建议在 Cloudflare、1Panel WAF 或外层 OpenResty 保留同类限速,作为纵深防御。 -The image does not add a separate login rate-limit plugin. For public deployments, rate-limit `/auth/login` and `/auth/sandbox/*` in Cloudflare, the 1Panel WAF, or the outer OpenResty layer, and configure the trusted real-client-IP chain before applying IP-based limits. +`CADDY_TRUSTED_PROXIES` 控制 Caddy 从右向左解析 `X-Forwarded-For` 时可以信任的代理节点。默认 `private_ranges` 适用于 1Panel/OpenResty 通过 loopback 或私网转发的部署;客户端直接连接 Caddy 时使用 `none`。如果 Cloudflare 或其他 CDN 位于 OpenResty 前,应在外层代理规范化真实客户端 IP,或在该参数中列出所有可信 CDN 和直接上游代理 CIDR。镜像会拒绝不受限制的 `/0` 范围。 + +The image limits username-stage POSTs to 30 per minute and password-stage POSTs to 10 per 10 minutes for each resolved client IP, returning HTTP 429 with `Retry-After` when blocked. `CADDY_TRUSTED_PROXIES` defaults to `private_ranges` for the documented 1Panel/OpenResty path; use `none` only for direct client connections, and configure every trusted hop or normalize the client IP when a CDN is present. Keep matching limits in the outer WAF or reverse proxy as defense in depth. 如果 DeepSeek Harness 后续加入原生密码鉴权,镜像保留的 `dsh` 模式会继续 fail-closed,待包装契约明确后再切换,不会自动叠加两套鉴权。 diff --git a/apps/deepseek-harness-workstation/latest/.env.sample b/apps/deepseek-harness-workstation/latest/.env.sample index 9c1883d2d..5a841ad09 100644 --- a/apps/deepseek-harness-workstation/latest/.env.sample +++ b/apps/deepseek-harness-workstation/latest/.env.sample @@ -5,5 +5,6 @@ DSH_PUBLIC_URL=https://dsh.example.com DSH_AUTH_USERNAME=admin DSH_AUTH_PASSWORD=replace-with-a-unique-password-at-least-12-characters DSH_AUTH_TOKEN_LIFETIME=604800 +CADDY_TRUSTED_PROXIES=private_ranges DSH_TRUSTED_HOSTS= DOCKER_SOCK_PATH=/dev/null diff --git a/apps/deepseek-harness-workstation/latest/data.yml b/apps/deepseek-harness-workstation/latest/data.yml index f46114010..493a4cfdb 100644 --- a/apps/deepseek-harness-workstation/latest/data.yml +++ b/apps/deepseek-harness-workstation/latest/data.yml @@ -117,6 +117,25 @@ additionalProperties: value: "604800" - label: 30 days value: "2592000" + - envKey: CADDY_TRUSTED_PROXIES + type: text + required: true + default: private_ranges + edit: true + labelZh: 可信代理范围 + labelEn: Trusted Proxy Ranges + label: + en: Trusted Proxy Ranges + zh: 可信代理范围 + zh-Hant: 受信任代理範圍 + ja: 信頼済みプロキシ範囲 + ko: 신뢰할 수 있는 프록시 범위 + ru: Диапазоны доверенных прокси + ms: Julat Proksi Dipercayai + pt-br: Faixas de proxies confiáveis + description: + en: Use space-separated CIDRs or private_ranges. Keep private_ranges behind 1Panel/OpenResty; use none only when clients connect directly to Caddy. + zh: 使用空格分隔的 CIDR 或 private_ranges。通过 1Panel/OpenResty 反向代理时保留 private_ranges;仅在客户端直连 Caddy 时使用 none。 - envKey: DSH_TRUSTED_HOSTS type: text required: false diff --git a/apps/deepseek-harness-workstation/latest/docker-compose.yml b/apps/deepseek-harness-workstation/latest/docker-compose.yml index 0efaca90b..0c7b91cd2 100644 --- a/apps/deepseek-harness-workstation/latest/docker-compose.yml +++ b/apps/deepseek-harness-workstation/latest/docker-compose.yml @@ -14,6 +14,7 @@ services: - AUTH_USERNAME=${DSH_AUTH_USERNAME:-admin} - AUTH_PASSWORD=${DSH_AUTH_PASSWORD} - AUTH_TOKEN_LIFETIME=${DSH_AUTH_TOKEN_LIFETIME:-604800} + - CADDY_TRUSTED_PROXIES=${CADDY_TRUSTED_PROXIES:-private_ranges} - AUTH_COOKIE_INSECURE=false - DSH_TRUSTED_HOSTS=${DSH_TRUSTED_HOSTS:-} - PORT=8080