Skip to content

feat(guest-agent): rootless 支援 chown/gosu image(/etc/subuid + newuidmap 委派)#84

Merged
TimLai666 merged 2 commits into
mainfrom
rootless-subuid-delegation
Jul 2, 2026
Merged

feat(guest-agent): rootless 支援 chown/gosu image(/etc/subuid + newuidmap 委派)#84
TimLai666 merged 2 commits into
mainfrom
rootless-subuid-delegation

Conversation

@TimLai666

Copy link
Copy Markdown
Owner

摘要

Roadmap 項目「Rootless Linux support for chown/gosu images」。原生 Linux rootless 路徑(以非 root 使用者跑單檔)改用 newuidmap/newgidmap + /etc/subuid 委派做範圍 uid/gid 映射(同 rootless podman),官方 redis/postgres 這類 entrypoint 會 chown+gosu 到專用 uid 的映像因此免 root 也能跑。無委派環境(無 uidmap 工具或無 subuid 範圍)自動退回既有單一 uid 映射,不致命;root 後端行為完全不變。

設計

  • 新模組 guest-agent/src/subid.rs:偵測(解析 /etc/subuid、/etc/subgid,PATH 找 newuidmap/newgidmap,process 級快取 + 一次性診斷訊息)+ 套用(0 <uid> 1 + 容器 uid 1 起依序接上各委派範圍)+ 握手協定(子行程 unshare(NEWUSER) 後通知,supervisor 代寫映射後回 verdict,失敗 fallback 自寫)。
  • 套用兩點:shared 模式的中繼行程(exec.rs,unshare 拆成 USER → 映射 → MNT|PID);internal/bridge 的 netns holder(netns.rs,服務加入 holder user ns 自動繼承)。
  • 代寫路徑不寫 setgroups deny(那是無特權自寫的前置),gosu 的 setgroups 才可用。

驗證

  • 單元測試 3 個(subuid 解析、範圍鏈接);guest-agent 41 tests 全過(WSL)。
  • 實測(WSL Ubuntu、非 root、tingzhen:100000:65536):
    • 預設 bridge 與 shared:容器內 chown 999:999 成功、exit 0、委派 banner 正確。
    • 官方 redis:7.2-alpine:非 root 起服務,host 側觀察 redis-server 跑在 uid 100998(=容器 999 的 subuid 映射)、宣告埠 PING→+PONG、未強制委派時 fallback 路徑(移除 PATH 的 newuidmap)不 crash。
  • 新增 linux-e2e.sh run_subid_e2e(bridge+shared 各驗 chown,斷言委派 banner;無委派環境跳過);e2e workflow 安裝 uidmap
  • musl clippy/fmt 乾淨。

文件

README(能力表、chown/gosu 段落、Roadmap 打勾)、DESIGN §6(服務 namespace 流程)、skills/write-appcipe(rootless 陷阱段改寫;順帶修掉兩處早已過時的「只吃 tar」描述)、CLAUDE.md。

TimLai666 added 2 commits July 2, 2026 16:01
原生 Linux rootless 路徑新增 newuidmap/newgidmap 範圍映射(同 rootless podman):
host 有 uidmap 工具且使用者有 subuid/subgid 委派範圍時,unshare(NEWUSER) 後由
supervisor 經握手管線以 newuidmap 代寫「0 <uid> 1 + 容器 uid 1 起接上委派範圍」,
chown/gosu 到服務專用 uid(官方 redis/postgres 的 999…)不再失敗;代寫路徑不寫
setgroups deny,gosu 的 setgroups 才可用。無委派或代寫失敗退回既有單一 uid 自寫
映射(不致命)。root 後端(WSL2/VM/native-root)行為完全不變。

兩個套用點:shared 模式的中繼行程(exec.rs);internal/bridge 的 netns holder
(netns.rs)——服務加入 holder user ns 自動繼承。

實測(WSL Ubuntu 非 root):bridge/shared 模式容器內 chown 999 都成功;官方
redis:7.2-alpine 以非 root 起服務(host 側觀察到 redis-server 跑在 subuid
100998 = 容器 999)、宣告埠 PING→+PONG。新增 linux-e2e run_subid_e2e(bridge+
shared 各驗一次 chown,無委派環境自動跳過)與 CI 安裝 uidmap。
quick-xml <0.41 的 O(n^2) DoS 公告;self_update 上游也還在 0.38、無 >=0.41 可升。
該依賴只用於 self_update 的 S3/GCS XML backend,chefer upgrade 走 GitHub JSON backend
不觸發。附解除條件於 audit.toml 註解。
@TimLai666 TimLai666 merged commit 12ba6d7 into main Jul 2, 2026
17 checks passed
@TimLai666 TimLai666 deleted the rootless-subuid-delegation branch July 2, 2026 08:21
@TimLai666 TimLai666 mentioned this pull request Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant