deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
给 dsh web 面板加一层原生 HTTP 认证(自绘登录页 + Basic + 签名 Cookie),
挂载在 /root/.dsh/profiles/web/cordis.patch.yml 的用户补丁层,升级 DSH 不会丢。
Accept: text/html):匿名时返回内置登录页(无 JS、CSP 收紧),
表单 POST 到 /panel-auth/login,成功后签发 Cookie 并跳回原目标地址。401 + WWW-Authenticate: Basic 契约,
仍可用 Basic 凭据直接调用,成功后同样签发 Cookie。401,带 Cookie 放行(浏览器对 WS 不保证携带
Authorization 头,因此依赖 Cookie)。/panel-auth/logout:清除 Cookie 并回到登录页。cookieTtlSeconds),HttpOnly + SameSite=Lax。users 为空或 secret 缺失/过短时不拦截任何请求,
配置写错不会把面板锁死。配置每次请求实时读取,改密码热生效。/root/.dsh/panel-auth-audit.jsonl(可用 auditLogPath 配置修改)。login-ok | 登录成功(含用户名、IP、User-Agent) |
| login-fail | 登录失败(含用户名、IP、UA、reason:bad-credentials / missing-fields / cross-origin / body-too-large) |
| logout | 主动登出 |
| challenge | 匿名浏览器导航被重定向到登录页 |
| reject | 匿名 API / WebSocket 请求被拒绝(含方法、路径) |ts(ISO 时间)、ip(优先 X-Forwarded-For,见下)、ua。<path>.1。tail -f /root/.dsh/panel-auth-audit.jsonl | jq .IP 说明:面板经 Caddy 反代时,直连 socket 是回环地址;插件在检测到回环 来源时会取
X-Forwarded-For的首个值作为真实 IP(Caddy 默认会带上该头)。
failureWindowSeconds(默认 300 秒)窗口内连续
maxFailures(默认 5)次密码错误后进入锁定期。lockoutBaseSeconds(默认 30 秒),再次触发翻倍,
上限 lockoutMaxSeconds(默认 3600 秒)。429 + Retry-After("尝试次数过多"),API 返回
429 {"error":"too many attempts"},且不再执行 scrypt 校验(不消耗 CPU)。failedLoginDelayMs(默认 300ms),
拖慢单连接暴力尝试。X-Forwarded-For 的最后一跳
(Caddy 会覆写伪造值,见下)。cordis.patch.yml 的 config 中可调):bruteProtection: true # 关闭设为 false
maxFailures: 5
lockoutBaseSeconds: 30
lockoutMaxSeconds: 3600
failureWindowSeconds: 300
failedLoginDelayMs: 300
局限:分布式攻击(每尝试换一个 IP)不受单 IP 锁定约束;这由 300ms 失败延迟 + scrypt 慢哈希兜底。公网反代场景建议再配合 Caddy 层的 IP 白名单/云防火墙(如 Cloudflare)使用。
DSH 上游将 settings.*、credentials.*、agentPreset.*、host.pickDirectory
等特权 /api 方法锁定为仅回环(loopback)Host 可访问(浏览器信任围栏的
设计:面板预期经 SSH 隧道访问)。用反向代理(如 Caddy)前置面板时,需把
Host 以回环形式转发给面板,否则这些方法返回 403 forbidden:
dsh.example.com {
reverse_proxy 127.0.0.1:3080 {
header_up Host 127.0.0.1
header_up -Origin
}
}
Origin:围栏同时校验 Origin == Host;Host 呈回环时浏览器
携带的对外 Origin 必然不相等(全部 403)。删除后围栏改走
Sec-Fetch-Site: cross-site 检查(现代浏览器都发)拦截跨站,且所有请求
仍有 panel-auth 的密码/Cookie 层把关(跨站请求带不上 SameSite=Lax Cookie)。非法请求来源)。配套客户端插件 panel-auth-ui(本仓库 ui/ 目录)在面板设置里注册
"账号与安全"区块,包含:
/panel-auth/change-password:patchFilePath(cordis.patch.yml,永续);live-updated,无需重启面板);password-change 事件(含结果明细)。/panel-auth/logout,清除 Cookie 并回到登录页。部署要求(客户端包按裸包名解析):
# 1. 把 ui/ 目录复制为 profile 内的独立包(host 存根 + client bundle)
cp -r ui /root/.dsh/profiles/web/panel-auth-ui
# 2. 建立裸包名解析符号链接(profiles 级 node_modules 为 pnpm 布局)
ln -sfn ../web/panel-auth-ui /root/.dsh/profiles/node_modules/panel-auth-ui
# 3. cordis.patch.yml 增加行(dsh.client 由 package.json 声明驱动)
# - id: panel-auth-ui
# name: 'panel-auth-ui'
相关配置项:
changePasswordPath: '/panel-auth/change-password'
patchFilePath: '/root/.dsh/profiles/web/cordis.patch.yml'
cd /root/.dsh/profiles/web/panel-auth
node hash.js admin 新密码 # 输出新 passwordHash
把输出的 passwordHash 替换进 ../cordis.patch.yml 后(loader HMR 热应用;
如未生效则 systemctl restart dsh-web)。
在 cordis.patch.yml 的 users 列表里再加一组 username/passwordHash。
node hash.js --secret # 生成新 secret
替换 cordis.patch.yml 的 secret 后重启。注意:更换密钥会使所有已签发
Cookie 立即失效,所有人需重新登录。
编辑 /root/.dsh/profiles/web/cordis.patch.yml:
users 置为 [](fail-open,面板恢复无密码状态),或index.js — 插件本体(登录页、认证守卫、审计日志、webServer 包装)crypto.js — scrypt 哈希 / HMAC Cookie 签名(无依赖,纯 node:crypto)hash.js — 生成密码哈希与随机密钥的 CLItest.mjs — 单元测试(node test.mjs,覆盖 15 组流程)CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。