fix(chv-muse-r11fix): authd 层 5 去掉 store helper,chv-sync 回落改 fail-closed

round-11 真机测试证实:镜像 /etc/gitconfig 的 [credential]
helper = store 把 authd 释放的长效 token 写进了客内
/home/chv/.git-credentials(0600)。改动:build.sh 不再设
store helper;chv-sync boot 在 authd socket/helper 缺失时直接
die,不再把 token 写进 .git-credentials(旧落盘回落废止);
authd helper 是唯一凭证 helper,且自身绝不落盘。旧镜像上 boot
现在会直接失败,须用含 authd 的新镜像。测试:无 authd 时 boot
失败且 .git-credentials 不产生、干跑不再含 store helper;P3
差距表 §3.5 更新为已关闭。
This commit is contained in:
host committed 2026-11-07 04:00:04 +00:00
1 parent 9f593d62ef
commit f093558c0d
5 files changed
+60 -27

No files matched your search

+5 -4
View File
@@ -19,9 +19,10 @@
#
# Gitea 双向同步(用户工作区口径,2026-11-06 追加):镜像里加
# git + gt 1.0.0(官方 install.sh + SHA256 校验,跟 170/172
# 同款),配好 git user 与 credential helper 占位,不含真实
# token;客机启动时 /usr/local/bin/chv-sync boot 按 seed 盘
# /etc/chv/guest-env(0600)把用户选定的仓 clone 到
# 同款),配好 git user,不含真实 token,不设 credential helper
#(round-11 真机修复层 5:store helper 已去掉,authd helper 是
# 唯一凭证 helper,且自身绝不落盘);客机启动时 chv-sync boot
# 按 seed 盘 /etc/chv/guest-env(0600)把用户选定的仓 clone 到
# ~/workspace,后续 pull/push 由用户显式同步,分叉/冲突时
# 失败关闭(不 --force、不自动 rebase)。token 绝不进镜像、
# 代码、日志。
@@ -309,7 +310,7 @@ VC_ARGS=(-a "$OUT/disk.raw"
--run-command 'mv /usr/local/bin/authd.py /usr/local/bin/chv-authd && chmod +x /usr/local/bin/chv-authd /usr/local/bin/git-credential-chv-authd'
--run-command 'systemctl enable chv-authd || true'
--run-command 'printf "runcmd:\n - systemctl restart ssh || service ssh restart || true\n - systemctl start chv-authd || true\n - test -f /etc/chv/guest-env && chown chv:chv /etc/chv/guest-env || true\n - /usr/local/bin/chv-sync boot >>/var/log/chv-sync.log 2>&1 || true\n" > /etc/cloud/cloud.cfg.d/99-chv-sync.cfg'
--run-command 'git config --system user.name chv && git config --system user.email chv@localhost && git config --system credential.helper store && git config --system init.defaultBranch main'
--run-command 'git config --system user.name chv && git config --system user.email chv@localhost && git config --system init.defaultBranch main'
--run-command "$GT_INSTALL_CMD"
--run-command '/usr/local/bin/gt version > /app/guest-versions-gt.txt'
--run-command 'printf "ssh_deletekeys: false\nbootcmd:\n - \"[ -f /etc/ssh/ssh_host_ed25519_key ] || ssh-keygen -A\"\n" > /etc/cloud/cloud.cfg.d/99-chv-hostkey.cfg; systemctl enable ssh || true'
+16 -19
View File
@@ -14,11 +14,12 @@
# 只给客内 authd 守护进程读)。
# boot(root,cloud-init runcmd 调)读 guest-env,authd 在时配
# git credential helper 走 authd 按次取凭证(只进 git 子进程
# 内存,不落盘);authd 不在时(旧镜像)才回落到把 token 写进
# /home/chv/.git-credentials(0600,chv 所有,git credential
# store 标准机制)并警告。pull/push/status 以 chv 身份跑,用
# helper 或已落盘的 credential,不再读 guest-env;token 不会
# 出现在 git remote URL 或镜像里。
# 内存,不落盘);authd 不在时直接失败(round-11 真机修复层 5:
# 旧镜像的落盘回落已废止——它在真机测试里把 authd 释放的长效
# token 写进了客内 ~/.git-credentials;authd helper 是唯一凭证
# helper,且自身绝不落盘)。pull/push/status 以 chv 身份跑,用
# helper,不再读 guest-env;token 不会出现在 git remote URL 或
# 镜像里。
#
# 用法:
# chv-sync boot # 启动时 clone(已 clone 则静默退出,不自动 pull)
@@ -65,19 +66,16 @@ cmd_boot() {
: "${GITEA_USER:?guest-env 缺 GITEA_USER}"
: "${SYNC_REPO:?guest-env 缺 SYNC_REPO}"
[ "$(id -u)" = "0" ] || die "boot 须以 root 运行(cloud-init runcmd)"
local host="${GITEA_URL#https://}"
host="${host#http://}"
host="${host%%/*}"
local name="${SYNC_REPO##*/}"
local dir="$WORKSPACE/$name"
mkdir -p "$WORKSPACE"
chown "$SYNC_USER:$SYNC_USER" "$WORKSPACE"
# feat-chv-muse-p3:authd 路径——socket 存在时凭证走 helper,
# 不再把真 token 写进 .git-credentials 落盘;helper 按次向
# authd 取凭证,只进 git 子进程内存。socket 不存在(旧镜像)
# 时走旧路径 + 警告(过渡兼容,旧镜像退役后改为 fail-closed)。
# authd 取凭证,只进 git 子进程内存。socket 不存在时直接失败
#(round-11 真机修复层 5:落盘回落已废止,见下)。
# 注意:authd 路径下 GITEA_TOKEN 不在 guest-env 里(它只进
# authd-seed 给守护进程),所以这里不要求它;旧路径才要求。
# authd-seed 给守护进程),所以这里不要求它。
local authd_socket="${CHV_AUTHD_SOCKET:-/run/chv-authd/authd.sock}"
local helper="/usr/local/bin/git-credential-chv-authd"
if [ -S "$authd_socket" ] && [ -x "$helper" ]; then
@@ -88,14 +86,13 @@ cmd_boot() {
runuser -u "$SYNC_USER" -- env HOME="$USER_HOME" git config --global credential.useHttpPath true
info "凭证走 chv-authd(不落盘)"
else
: "${GITEA_TOKEN:?guest-env 缺 GITEA_TOKEN(旧路径)}"
echo "chv-sync: 警告:chv-authd 未运行,凭证走旧落盘路径(须用含 authd 的新镜像)" >&2
# token 只落盘进用户家目录的 credential store(0600),
# 不进 git remote URL、不进镜像、不进日志(此处不打印 token)。
local creds="$USER_HOME/.git-credentials"
printf 'https://%s:%s@%s\n' "$GITEA_USER" "$GITEA_TOKEN" "$host" > "$creds"
chmod 0600 "$creds"
chown "$SYNC_USER:$SYNC_USER" "$creds"
# round-11 真机修复(层 5):authd 不在时直接失败,不再
# 把真 token 写进 ~/.git-credentials 落盘——旧路径在
# round-11 真机测试里把 authd 释放的长效 token 写进了
# 客内磁盘(/home/chv/.git-credentials,0600)。authd
# helper 是唯一凭证 helper,且自身绝不落盘;旧镜像退役
# 后过渡兼容即废止,不再留落盘逃生口。
die "chv-authd 未运行(socket 或 helper 缺失),拒绝同步:凭证绝不落盘,请用含 authd 的镜像"
fi
if [ -d "$dir/.git" ]; then
info "已 clone:$dir(不自动 pull,改动由用户显式同步)"
+25
View File
@@ -732,6 +732,31 @@ class ChvSyncTest(unittest.TestCase):
r = self._sync("boot", env_extra={"CHV_GUEST_ENV": env_file})
self.assertNotEqual(r.returncode, 0)
def test_boot_without_authd_fails_closed_no_credentials_file(self):
# round-11 真机修复(层 5):authd 不在时 boot 直接失败,
# 绝不把 token 写进 ~/.git-credentials(旧落盘回落已废止;
# 即使 guest-env 里有 token 也不写)。
if os.getuid() != 0:
self.skipTest("boot 须以 root 运行")
env_file = os.path.join(self.dir, "guest-env")
with open(env_file, "w") as fh:
fh.write("GITEA_URL=https://gitea.tose.top\n"
"GITEA_USER=admin\n"
"SYNC_REPO=admin/chv-sync-test\n"
"GITEA_TOKEN=fake-token-for-test\n")
home = os.path.join(self.dir, "home")
os.makedirs(home, exist_ok=True)
r = self._sync("boot", env_extra={
"CHV_GUEST_ENV": env_file,
"CHV_USER_HOME": home,
"CHV_USER": "root",
"CHV_AUTHD_SOCKET": os.path.join(self.dir, "no-authd.sock"),
})
self.assertNotEqual(r.returncode, 0)
self.assertIn("chv-authd 未运行", r.stderr)
self.assertFalse(
os.path.exists(os.path.join(home, ".git-credentials")))
# -- (6) 中途死亡 → interrupted → 断点续跑闭环 ---------------------------
class MidDeathLoopTest(ChvGapCase):
+4
View File
@@ -632,6 +632,10 @@ class BuildDryRunTest(unittest.TestCase):
self.assertIn(needle, out, needle)
# P1 文件不在本分支:干跑只警告、不失败。
self.assertIn("vsock_notify.py 不在仓库里", out)
# round-11 真机修复(层 5):镜像不再设 store helper
#(authd helper 是唯一凭证 helper),git user 仍配。
self.assertNotIn("credential.helper store", out)
self.assertIn("git config --system user.name chv", out)
if __name__ == "__main__":
+10 -4
View File
@@ -106,10 +106,16 @@ authd 保管、代理只见替身令牌;所有连接器动作与网络出口
凭证前评估),不是网络层强制。客内任意进程的直连仍由 Tinyproxy
白名单 + 宿主防火墙(第三棒)兜底;eBPF cgroup 拦截 + LSM 污点传播
是后续工作,不得写成“出口已全部经 Sentinel”。
5. **过渡兼容留了旧路径**:`chv-sync boot` 在 authd socket 不存在时仍走
旧的 `.git-credentials` 落盘(只多一句 stderr 警告),为的是 lite9/
lite10 旧镜像不被一次改断。旧镜像退役后应删掉该回落,改为无 socket
即 fail-closed;删除前不得声称“旧路径已关闭”。
5. **过渡兼容已关闭(round-11 真机修复,层 5)**:此前 `chv-sync
boot` 在 authd socket 不存在时仍走旧的 `.git-credentials` 落盘
(只多一句 stderr 警告),为的是 lite9/lite10 旧镜像不被一次
改断。round-11 真机测试证实该回落把 authd 释放的长效 token 写
进了客内磁盘,修复轮已改为无 socket 即 fail-closed(`die`),
同时镜像 `/etc/gitconfig` 的 `credential.helper store` 也已删
除——authd helper 是唯一凭证 helper,且自身绝不落盘。旧镜像
(lite10 及更早)上 boot 现在会直接失败,须用含 authd 的新
镜像;真机复测须验证跑完一次完整 Gitea 链后客内
`~/.git-credentials` 不存在。
6. **无真机验证**:本轮全部是代码 + 本地单测(含真 git helper 端到端,
但 authd 守护进程本身未在真 VM 里跑过)。真机待验证清单:authd 在
lite11 镜像里启动时序(须在 `chv-sync boot` 之前就绪)、SO_PEERCRED