api-relay-audit
toby-bridges
Local security audit for AI API relays and LLM proxies: detects prompt injection, model substitution, tool-call rewriting, SSE anomalies, error leakage, and Web3 wallet risks.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:slywalker2006/dsh-passwords
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
English | 简体中文
给 DeepSeek Harness 加一层服务器级认证网关,使其成为可公网部署的多租户平台
登录认证 · 自动 HTTPS · 多租户权限 · 会话授权 · 审计加密 · 中英双语
| 登录页 · 浅色 | 登录页 · 深色 | 登录页 · English |
|---|---|---|
![]() |
![]() |
![]() |
| dsh 主界面 · 登录后 | 聊天 / 留言 | 设置页卡片 · 账号管理 |
|---|---|---|
![]() |
![]() |
![]() |
| 设置页卡片 · 权限与配额 | ||
|---|---|---|
![]() |
宿主机安装需要 Node.js 22.19+ 或 24+、可正常运行的 dsh、git 与 pnpm(手动执行 node scripts/register-plugin.mjs 注册插件时需要;一键安装器会自动安装 pnpm)。兼容门禁只接受 DSH 0.2.1 patch 线,即 >=0.2.1-alpha.1 <0.2.2-0(alpha.1 起的预发布与稳定 0.2.1);当前开发树与 bundled Docker 默认运行时锁定 0.2.1-alpha.1。已退役的 0.1.x / 0.2.0 线、0.2.1-alpha.0 以及所有 0.2.2+ 身份都会被拒绝。Docker 安装只需要 Docker Engine 或 Docker Desktop 和一个 DeepSeek API key。
五种安装方式,任选其一。宿主机安装会自动完成装依赖、编译、生成 SETUP_KEY、注册 dsh 插件、应用远程设置补丁;已有 .env 时不覆盖,重复运行安全。
# 1. Linux / macOS 一键安装
curl -fsSL https://raw.githubusercontent.com/slywalker2006/dsh-passwords/main/install.sh | sudo bash
# 2. 先 clone 再安装
git clone https://github.com/slywalker2006/dsh-passwords && cd dsh-passwords
sudo bash install.sh
# 3. npm 全局安装,适用于任意平台
npm install -g dsh-passwords
dsh-passwords install
Windows 下载仓库里的 install.bat 双击运行。默认安装到 %USERPROFILE%\dsh-passwords。
# 4. Docker:一条命令完成安装并初始化
docker run -d \
--name dsh-passwords \
--restart unless-stopped \
-e DEEPSEEK_API_KEY=sk-你的key \
-e SETUP_KEY=自己设定的强随机串 \
-p 127.0.0.1:3088:3088 \
-v dsh-home:/data/dsh \
-v dsh-passwords-state:/data/dsh-passwords \
skywalker237234/dsh-passwords:2.7.7
启动后浏览器打开 http://127.0.0.1:3088,用你自己设置的 SETUP_KEY 完成首次配置。若省略 -e SETUP_KEY,容器会随机生成密钥并写入卷内 setup-key.txt,用 docker exec dsh-passwords cat /data/dsh-passwords/setup-key.txt 读取后再完成首次配置(首次配置成功后该文件自动删除)。-e SETUP_KEY 会在首次初始化时作为初始 SETUP_KEY 写入卷内 .env,不会与随机值分叉,去掉该 env 重启也不会因此锁死(首次配置成功后 .env 中的 SETUP_KEY 会按既有加固流程自动轮换,此后登录使用你创建的账号密码,不再需要它)。
如需自定义端口、域名、SSH 端点或第三方端点登记等高级配置,可复制 docker/.env.example 为 docker/.env 并追加 --env-file docker/.env(Docker Compose 则可 docker compose --env-file docker/.env -f docker/docker-compose.yml up -d);它是可选的进阶配置,不再是安装前置步骤。不要用仓库根目录的宿主机模板 .env.example:它会注入占位 SETUP_KEY(change-me-…)、MCP_GATEWAY_PORT=443 与空的 MCP_GATEWAY_AUTO_TLS=,覆盖镜像内置的 3088 端口和 MCP_GATEWAY_AUTO_TLS=0,导致容器不监听 3088、网关拒绝启动;其中相对的 MCP_DB_PATH=./data/platform.db 也会偏离容器默认的 /data/dsh-passwords/platform.db。
Docker 部署至少需要 DEEPSEEK_API_KEY。MCP_GATEWAY_PUBLIC_HOST 建议填实际访问的域名。宿主端口只发布在回环地址 127.0.0.1:3088,容器内监听 0.0.0.0:3088;公网访问由 nginx 或 Caddy 终结 TLS 后转发。镜像内置 DSH 0.2.1-alpha.1(DSH 0.2.1 patch 线当前锁定版本;该镜像尚未做运行验收);初始化完成以 healthz/readyz 均返回 ok:true 为准。
说明:
/opt/dsh-passwords,可用 DSH_PASSWORDS_DIR 更改;检测到已有 dsh-passwords 目录时就地幂等重跑,其他同名目录会报错退出setup-key.txt;Docker 用 -e SETUP_KEY 指定,省略则随机生成并写入卷内 setup-key.txt.env、数据库、证书;删除即丢数据docker compose down -v,而 docker run 部署需要先 docker rm -f dsh-passwords,再执行 docker volume rm dsh-home dsh-passwords-state(都会永久删除卷数据)MCP_DSH_PATCH_ALLOW_BIND_ALL=1,让网关容器能访问 dsh web;0.2.1-alpha.1 的 dsh-web-app 仍然在启动时拒绝 --host 0.0.0.0,所以该子补丁依旧需要保留sudo(自动 HTTPS 要监听 80/443);nvm / Homebrew 管理的 Node 常不在 root 或系统 PATH 中,可能找不到 dsh-passwords 命令;npm 全局目录会随包更新被替换,不适合长期保存 .env 与 data/,推荐 clone 后安装,或用 DSH_PASSWORDS_ENV_FILE 把配置与数据指向稳定目录dsh web。Docker 用户跳过此步,容器内自动启动。https://<服务器地址>,首次访问自动进入配置页。首次配置成功后 setup-key.txt 自动删除,.env 中的密钥自动固化并轮换。
Docker 用户一条命令启动后直接打开 http://127.0.0.1:3088 完成首次配置,公网访问再自行用 nginx 或 Caddy 把 80/443 反代到 http://127.0.0.1:3088;首次配置用的 SETUP_KEY 就是 -e SETUP_KEY 设置的值,省略时用 docker exec dsh-passwords cat /data/dsh-passwords/setup-key.txt 读取。
宿主机安装可在 dsh-passwords 安装目录执行:
node dist/cli.js uninstall
# 全局 npm 安装也可直接执行:
dsh-passwords uninstall
该命令只从 DSH web profile 移除 dsh-passwords 的 link 与 bundle,并回滚本插件管理的 dsh 补丁;其他插件和 bundle 会保留。完成后按提示重启 dsh-web。
卸载不会删除安装目录、.env、数据库、TLS/ACME 证书或其他插件。profile 依赖重建或补丁回滚失败时会恢复原 profile,避免留下半卸载状态。Docker 部署请按所用 Compose 或容器编排停止并移除容器;不要删除命名卷,除非也要永久清除数据。
默认探测公网 IP 并用 <IP>.sslip.io 向 Let's Encrypt 签发 90 天证书,到期前 30 天自动续期,新证书热加载。有自己的域名时在 .env 加 MCP_GATEWAY_DOMAIN。签发失败拒绝启动,不降级明文;续期失败但旧证书仍在有效期内时继续使用并后台重试。
| 错误码 | 含义 | 处理 |
|---|---|---|
| 30 | 证书签发失败 | 检查 80/443 放行与占用情况,确认能连通 Let's Encrypt |
| 31 | 拿不到公网 IP 或域名 | 设置 MCP_GATEWAY_DOMAIN,或使用 HTTP 模式 |
| 32 | 端口被占用 | 更换 MCP_GATEWAY_PORT 或释放端口 |
证书域名使用 <IP>.sslip.io 是因为 Let's Encrypt 不给纯 IP 签发证书。直接访问裸 IP 的 https 地址会提示主机名不匹配,从 80 端口入口进入会自动跳转到正确地址。
| 场景 | 做法 |
|---|---|
| 公网服务器,80/443 可用 | 默认配置即可,自动 HTTPS |
| 已有域名证书 | .env 填 MCP_GATEWAY_TLS_CERT / MCP_GATEWAY_TLS_KEY,无需 80 端口 |
| 已有 nginx / Caddy 反代 | 反代终结 TLS,.env 设 MCP_GATEWAY_AUTO_TLS=0 与高位端口,网关只监听回环 |
| Cloudflare | CF 边缘终结 TLS 转发源站,配置同反代 |
| 纯内网 / 裸 IP 无法开 80 | 使用 HTTP 模式 |
http-01 验证只在签发与续期时访问 80 端口,约每 60 天一次。
默认拒绝明文 HTTP。内网环境确需使用时:
node scripts/start-http.mjs [端口] # 默认 8080,需确认风险提示
或在 .env 写入 MCP_GATEWAY_AUTO_TLS=0 与 MCP_GATEWAY_PORT=8080,dsh 启动时插件以 HTTP 模式拉起网关。该模式不依赖公网 IP、DNS、ACME 或外部 CDN,可用于内网部署;首次安装仍需要 npm/GitHub 可访问,或提前准备项目 tarball、依赖缓存和本地 DSH 安装。模型对话仍需要配置上游模型提供方(例如 DEEPSEEK_API_KEY);没有外部模型服务时,登录、权限、文件与管理功能可运行,但不会产生模型回复。
登录后打开设置,能看到「dsh-passwords · 密码门」卡片。
| 功能 | 使用者 | 说明 |
|---|---|---|
| 重载补丁 | 仅主用户 | dsh 升级后设置页异常时一键重打补丁并重启网页服务 |
| 软件更新 | 状态所有人可见,操作仅主用户 | 自动检查、限速下载、空闲后安装重启,详见下节 |
| 修改密码 / 用户名 | 本人;主用户可操作任何人 | 改密后旧会话全部失效 |
| 子用户管理 | 仅主用户 | 创建、删除子用户 |
| 子用户权限 | 仅主用户 | 工作区白名单、逐会话授权、token 与时长上限、沙盒、上传下载开关、WebSocket 路径授权、封禁 |
| 聊天 / 留言 | 所有登录用户 | 支持标签;子用户消息默认私信主用户,仅主用户可广播 |
| 退出登录 | 所有登录用户 | 登出当前账号 |
密码要求:至少 12 位,含大写、小写、数字、符号。
dist.integrity 的 sha512 校验.env、data/、数据库、TLS 与 profile,失败自动回滚MCP_DSH_DOCKER_SELF_UPDATE=1 与 Compose 相关变量,未配置时只显示宿主机手动命令;Docker socket 等同授予容器宿主控制权限,仅在可信部署启用| 变量 | 默认 | 说明 |
|---|---|---|
SETUP_KEY |
安装脚本生成(Docker 可用 -e SETUP_KEY 指定) |
首次配置密钥,配置成功后自动轮换 |
MCP_JWT_SECRET |
从 SETUP_KEY 派生 | 会话签名密钥,生产环境建议 openssl rand -hex 32 独立设置 |
MCP_INTERNAL_SECRET |
从 SETUP_KEY 派生 | 网关内部管理接口密钥(dsh 插件通知网关用),与 JWT 域分离派生;显式设置后不要随意更换 |
MCP_DB_PATH |
宿主 ./data/platform.db;Docker /data/dsh-passwords/platform.db |
SQLite 数据库路径;相对路径锚定 .env 所在目录(DSH_PASSWORDS_ENV_FILE 指向的目录),而非进程工作目录 |
MCP_DB_ENC_KEY |
空 | 字段加密密钥,启用后不可更换;备份数据库必须连同 .env |
MCP_GATEWAY_HOST / MCP_GATEWAY_PORT |
0.0.0.0 / 宿主自动 HTTPS 443、HTTP 模式 8080、Docker 3088 |
网关监听地址与端口;Docker 镜像固定 0.0.0.0:3088,再由宿主机映射到 127.0.0.1:3088 |
MCP_GATEWAY_UPSTREAM |
http://127.0.0.1:3080 |
dsh 网页地址,插件自动指向 |
MCP_GATEWAY_UPSTREAM_TLS_VERIFY |
开 | 上游 dsh 为 HTTPS/WSS 时校验其证书;0 关闭(仅调试,勿用于生产) |
MCP_GATEWAY_SSH_ENDPOINTS |
空 | 传统、无法由 DSH 运行时登记的 HTTP/WS 端点表(逗号分隔)。规则为 [owner:][ws:\|http:]路径;owner: 仅主用户,普通规则也仅主用户可用,历史 allowSsh 值不能授予子用户 SSH 能力。已加载 DSH 普通扩展的 Remote/API 面按通用清单适配,不绑定 allow_ssh;工作区/会话对象权限以及 terminal、动态宿主执行、插件管理等敏感边界仍由网关统一控制。使用 DSH_PASSWORDS_ENV_FILE 启动时,登记表每 5 秒热更新;未显式指定该变量时请重启网关生效。 |
MCP_GATEWAY_REDIRECT_PORT |
自动 HTTPS 时 80;关闭自动 HTTPS 时不监听 |
ACME 验证与 301 跳转端口;显式 0 关闭 |
MCP_GATEWAY_DOMAIN |
空 | 自定义域名,留空用 <公网IP>.sslip.io |
MCP_GATEWAY_AUTO_TLS |
宿主机开;Docker 镜像固定 0 |
0 关闭自动 HTTPS(容器内默认明文,由外层反代终结 TLS) |
MCP_GATEWAY_TLS_CERT / MCP_GATEWAY_TLS_KEY |
空 | 自有证书,优先于自动 HTTPS |
MCP_GATEWAY_PUBLIC_HOST |
空 | 固定跳转地址,防 Host 伪造 |
MCP_GATEWAY_ACME_EMAIL / MCP_GATEWAY_ACME_STAGING |
空 / 关 | 证书提醒邮箱 / LE 测试环境 |
MCP_DSH_ROOT |
自动探测 | dsh 安装目录 |
MCP_DSH_SETTINGS_FILE |
自动探测 | dsh settings.yaml 路径,网关与 dsh 不在同一台机器时显式指定;留空按 DSH_HOME/settings.yaml 等候选位置探测 |
MCP_DSH_RESTART_SERVICE |
Linux dsh-web;Windows 空 |
重载补丁后的 systemd 服务名;Windows 自动更新安装后需手动重启 DeepSeek Harness |
MCP_DSH_AUTO_UPDATE |
开 | 部署级自动更新总开关 |
MCP_DSH_UPDATE_MAX_BPS |
1MiB/s | 自动下载限速,只能调低 |
MCP_DSH_DOCKER_SELF_UPDATE / _COMPOSE_DIR / _COMPOSE_FILE / _IMAGE / _SOCKET |
关 / 空 | Docker 应用内更新的启用开关与 Compose 配置 |
MCP_DSH_PATCH_ALLOW_BIND_ALL |
关 | 分容器拓扑允许 dsh web 绑定 0.0.0.0(0.2.1-alpha.1 的 dsh-web-app 仍未原生放行,仍需该子补丁) |
DSH_PASSWORDS_ENV_FILE |
空 | 手动指定 .env 路径 |
环境变量与 .env 的优先级按安装方式不同:Docker 内以容器环境变量(--env-file docker/.env)优先于卷内 .env;宿主安装相反,部署 .env 中的托管键优先于进程中继承的同名环境变量。
node dist/cli.js audit --limit 20 # 最近 20 条审计日志
node dist/cli.js patch status # 远程设置补丁状态
node dist/cli.js patch # 重载补丁并重启 dsh-web
node dist/cli.js serve-gateway --port 9000 # 手动启动网关
DSH_PASSWORDS_NO_AUTOSTART=1 dsh web # 禁止网关自动拉起
curl -s https://地址/gateway/healthz # 存活检查
curl -s https://地址/gateway/readyz # 就绪检查,含数据库
用户表为空,按提示输入 SETUP_KEY 重建主用户。
停服后删除 users 表并重启:
node -e "const {DatabaseSync}=require('node:sqlite');const db=new DatabaseSync('data/platform.db');db.exec('DELETE FROM users;')"
见「自动 HTTPS」一节的错误码表。
Linux 下 1024 以下端口需要 root,改用 MCP_GATEWAY_PORT 高位端口并自行做端口转发。
dsh plugin add 会把所有声明 bundle 的依赖加入 bundles 层导致冲突。卸载后改用 node scripts/register-plugin.mjs 精确注册。
放行安装脚本后重装:
npm config set allow-scripts=@deepseek-ai/dsh-subprocess-local,koffi,node-pty,@google/genai,protobufjs --location=user
没有。敏感字段全部加密或散列,密码仅存 bcrypt 哈希,无 .env 密钥无法解密。
不能,启用后更换将导致历史数据无法解密。
网关对内容哈希命中的静态资源强制一年期 immutable 缓存,升级后首次访问完整下载一次,之后秒进。访问慢时网关每请求开销约 1-2ms,先检查 TLS 握手:
curl -so /dev/null -w "TLS:%{time_appconnect}s\n" https://地址/gateway/login
通常瓶颈在到服务器的链路延迟。
当前发布版本 2.7.7 只支持 DSH
0.2.1patch 线(>=0.2.1-alpha.1 <0.2.2-0);开发与 bundled Docker 运行时锁定0.2.1-alpha.1。已退役的0.1.x/0.2.0线、0.2.1-alpha.0以及所有0.2.2+身份都会被版本门禁拒绝。宿主机安装器会检查 Node.js22.19+或24+,注册插件并应用兼容补丁。
git clone https://github.com/slywalker2006/dsh-passwords && cd dsh-passwordsnpm install && npm run buildcp .env.example .env,把 SETUP_KEY 改为 openssl rand -hex 24 生成的随机串node scripts/register-plugin.mjs 注册插件node dist/cli.js patch 应用补丁,找不到 dsh 目录时用 MCP_DSH_ROOT 指定之后启动 dsh,网关自动拉起,按「首次配置」完成初始化。
账号密码只存 bcrypt 哈希;用户名、IP 与审计记录加密落盘;证书签发失败拒绝启动。
%2f、双重编码等变体setup-key.txt 并固化独立密钥变量界面中英双语,跟随 dsh 语言设置。登录页右上角可手动切换并持久化,CLI 跟随 LANG / LC_ALL。
当前发布版本为 2.7.7,开发与 bundled Docker 默认运行时锁定 0.2.1-alpha.1:这是 npm 上 0.2.1 patch 线当前最新已发布的身份(alpha dist-tag),也是 9 个 @deepseek-ai/dsh* 开发依赖实际解析并锁定的版本。开发依赖声明范围 >=0.2.1-alpha.1 <0.2.2-0,即接受 alpha.1 起的 alpha/beta/rc 预发布与稳定 0.2.1,拒绝已退役的 0.1.x / 0.2.0 线、0.2.1-alpha.0 与所有 0.2.2+ 身份;但 npm 目前只发布了 0.2.1-alpha.1 一个 0.2.1 身份,因此后续预发布与稳定版的兼容仅由 SemVer 范围与版本身份门禁保证,未在实机运行、也未通过完整网关验收。
npm ci && npm run build && npm test,CI 会在 Node 22/24 上自动执行觉得有用就点个 Star。
报告问题 · 查看 Releases · npm 包 · Awesome 收录
GNU GPL v3.0 only,完整文本见 LICENSE。
本项目是 dsh 的独立扩展,与 DeepSeek 无隶属关系。
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: security。