diff --git a/deploy/nas/README.md b/deploy/nas/README.md index 561f3f02..264aaf16 100644 --- a/deploy/nas/README.md +++ b/deploy/nas/README.md @@ -48,7 +48,10 @@ SSH 或 `sudo` 密码。安装时要完成以下动作: `edge`。更新服务只读取该目录,个人账号不能修改 root 更新流程。 2. 将 `update-plainleaf.sh` 安装为 `/usr/local/sbin/plainleaf-update`。 3. 将 systemd 单元安装到 `/etc/systemd/system/plainleaf-update.service`。 -4. 安装本机 SSH 公钥,让发布脚本可用 `BatchMode` 连接 NAS。 +4. 生成专用的 `~/.ssh/plainleaf_zspace_ed25519`,将公钥安装到 NAS。授权行使用 + forced-command,并禁用端口转发、Agent 转发、PTY 和 X11;这把密钥只能触发 + Plainleaf 更新,不能登录 Shell。发布脚本还会开启 `BatchMode` 和 + `IdentitiesOnly`,不会回退到密码或其他密钥。 5. 安装 `plainleaf-update.sudoers`,其中只有一条受限规则,只允许 NAS 账号免密启动 `plainleaf-update.service`,不能免密执行其他 root 命令。 6. 执行 `systemctl daemon-reload`,再手动启动一次服务,确认拉取、重建和健康检查 diff --git a/deploy/nas/deployment.test.ts b/deploy/nas/deployment.test.ts index 988a6250..221aa095 100644 --- a/deploy/nas/deployment.test.ts +++ b/deploy/nas/deployment.test.ts @@ -39,6 +39,9 @@ test("NAS deployment follows the Gitea edge image", () => { expect(publisher).toContain('--tag "${IMAGE_REPOSITORY}:edge"'); expect(publisher).toContain("--push"); expect(publisher).toContain("-o BatchMode=yes"); + expect(publisher).toContain("-o IdentitiesOnly=yes"); + expect(publisher).toContain('-i "$NAS_IDENTITY_FILE"'); + expect(publisher).toContain("plainleaf_zspace_ed25519"); expect(publisher).toContain( "sudo -n /usr/bin/systemctl start plainleaf-update.service", ); diff --git a/scripts/publish-nas-image.sh b/scripts/publish-nas-image.sh index 665dfe9b..d0d9846c 100755 --- a/scripts/publish-nas-image.sh +++ b/scripts/publish-nas-image.sh @@ -6,6 +6,7 @@ readonly IMAGE_REPOSITORY="gitea.aichickenfarm.cn/wushenghua/plainleaf" readonly NAS_HOST="${PLAINLEAF_NAS_HOST:-192.168.31.68}" readonly NAS_PORT="${PLAINLEAF_NAS_PORT:-10000}" readonly NAS_USER="${PLAINLEAF_NAS_USER:-13616066635}" +readonly NAS_IDENTITY_FILE="${PLAINLEAF_NAS_IDENTITY_FILE:-${HOME}/.ssh/plainleaf_zspace_ed25519}" repo_root="$(git rev-parse --show-toplevel)" cd "$repo_root" @@ -20,6 +21,12 @@ if ! docker buildx version >/dev/null 2>&1; then exit 1 fi +if [[ ! -r "$NAS_IDENTITY_FILE" ]]; then + echo "发布已取消:缺少 Plainleaf 专用 SSH 密钥 ${NAS_IDENTITY_FILE}。" >&2 + echo "请先完成 NAS 主动更新的一次性安装。" >&2 + exit 1 +fi + git_sha="$(git rev-parse HEAD)" short_sha="$(git rev-parse --short=8 HEAD)" @@ -41,6 +48,8 @@ echo "镜像推送完成,正在触发 NAS 更新。" ssh \ -o BatchMode=yes \ -o ConnectTimeout=8 \ + -o IdentitiesOnly=yes \ + -i "$NAS_IDENTITY_FILE" \ -p "$NAS_PORT" \ "${NAS_USER}@${NAS_HOST}" \ "sudo -n /usr/bin/systemctl start plainleaf-update.service"