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