From 074bd1783c223e3ee3b1f1b0fc76658e8f722724 Mon Sep 17 00:00:00 2001 From: Lemon-miaow Date: Fri, 25 Sep 2026 03:46:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(install):=20=E9=87=8D=E8=B7=91=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E6=97=B6=E6=92=A4=E9=94=80=E6=97=A7=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E4=B8=BA=E4=B8=96=E7=95=8C=E6=A0=B9=E7=9B=AE=E5=BD=95=E6=8E=88?= =?UTF-8?q?=E4=BA=88=20uid=201000=20=E7=9A=84=20ACL=20=E4=B8=8E=20o+x=20?= =?UTF-8?q?=E9=81=8D=E5=8E=86=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/bootstrap.sh | 30 ++++++++++++++++++++++++++++++ deploy/bootstrap_test.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/deploy/bootstrap.sh b/deploy/bootstrap.sh index 8074204..ff4a30d 100644 --- a/deploy/bootstrap.sh +++ b/deploy/bootstrap.sh @@ -3401,6 +3401,34 @@ EOF ok "off-site copy: secrets in ${OFFSITE_ENV}" } +# Releases before the reaper ran as root granted uid 1000 traverse on the worlds root: an +# ACL entry, or o+x where the host had no setfacl. uid 1000 is now the game servers' uid, +# and the per-volume directories below that root are 0777, so the grant let a game process +# (and, for o+x, every local account) reach any world by its directory name. Every run +# takes it back: the ACL entry from any worlds root, the other-bits only from k3s's storage +# root, which k3s ships 0700 root:root. A custom root keeps its mode, which may be the +# operator's own. +revoke_worlds_root_grant() { + local dir + for dir in "$K3S_STORAGE_ROOT" "$FELIS_WORLDS_HOST_PATH"; do + [ -n "$dir" ] && [ -d "$dir" ] || continue + if command -v getfacl >/dev/null 2>&1 && getfacl -cpn "$dir" 2>/dev/null | grep -q '^user:1000:'; then + if setfacl -x u:1000 "$dir"; then + log "revoked the old uid-1000 traverse grant on ${dir}" + else + warn "could not revoke the old uid-1000 traverse grant on ${dir}; remove it with: setfacl -x u:1000 ${dir}" + fi + fi + done + if [ -d "$K3S_STORAGE_ROOT" ] && [ -n "$(find "$K3S_STORAGE_ROOT" -maxdepth 0 -perm -o=x)" ]; then + if chmod o-rwx "$K3S_STORAGE_ROOT"; then + log "revoked the old world-traversable mode on ${K3S_STORAGE_ROOT} (back to k3s's 0700)" + else + warn "could not restore ${K3S_STORAGE_ROOT} to 0700; any local account can reach the world volumes below it: chmod o-rwx ${K3S_STORAGE_ROOT}" + fi + fi +} + deploy_bundle() { local prev_api prev_operator prev_gate export KUBECONFIG=/etc/rancher/k3s/k3s.yaml @@ -3445,6 +3473,8 @@ deploy_bundle() { --key="$PANEL_TLS_KEY" \ --dry-run=client -o yaml | kube apply -f - + revoke_worlds_root_grant + log "rendering + applying the control-plane bundle" local -a manifest_args=( --felis-image "$FELIS_IMAGE" diff --git a/deploy/bootstrap_test.sh b/deploy/bootstrap_test.sh index 7a1ae62..7c74c6c 100644 --- a/deploy/bootstrap_test.sh +++ b/deploy/bootstrap_test.sh @@ -1022,6 +1022,34 @@ case "$out" in *SETFACL*|*CHMOD*|*WARN*) echo "FAIL: an existing worlds root must get no grant and no warning: $out"; fails=$((fails + 1)) ;; esac +# data-durability-18: an older release's traverse grant on the worlds root is taken back on +# every run -- the ACL entry from any root, the other-bits only from k3s's own storage root. +rvblock="$(awk '/^revoke_worlds_root_grant\(\) \{/,/^}/' "$BS")" +[ -n "$rvblock" ] || { echo "FAIL: no revoke_worlds_root_grant found in $BS"; exit 1; } +run_revoke() { # k3s-root worlds-root acl-dir + K3S_STORAGE_ROOT="$1" FELIS_WORLDS_HOST_PATH="$2" ACL_DIR="$3" bash -c ' + log() { printf "LOG %s\n" "$*"; } + warn() { printf "WARN %s\n" "$*"; } + getfacl() { case "$*" in *"$ACL_DIR") printf "user::rwx\nuser:1000:--x\ngroup::---\n" ;; *) printf "user::rwx\ngroup::---\n" ;; esac; } + setfacl() { printf "SETFACL %s\n" "$*"; } + '"$rvblock"' + revoke_worlds_root_grant' 2>&1 +} +k3sroot="$(mktemp -d)"; custom="$(mktemp -d)" +command chmod 0701 "$k3sroot"; command chmod 0755 "$custom" +out="$(run_revoke "$k3sroot" "$custom" "$custom")" +expect "the old ACL grant is revoked from a custom worlds root" "SETFACL -x u:1000 $custom" "$out" +expect "the old o+x on k3s's storage root is revoked" "LOG revoked the old world-traversable mode on $k3sroot" "$out" +mode_of() { stat -c %a "$1" 2>/dev/null || stat -f %Lp "$1"; } +if [ "$(mode_of "$k3sroot")" = 700 ]; then echo "PASS k3s's storage root is back to 0700"; else echo "FAIL k3s's storage root is $(mode_of "$k3sroot"), want 700"; fails=$((fails + 1)); fi +if [ "$(mode_of "$custom")" = 755 ]; then echo "PASS a custom worlds root keeps its own mode"; else echo "FAIL a custom worlds root was changed to $(mode_of "$custom")"; fails=$((fails + 1)); fi +out="$(run_revoke "$k3sroot" "" "/nowhere")" +case "$out" in + *SETFACL*|*LOG*|*WARN*) echo "FAIL: a root with no old grant must be left alone: $out"; fails=$((fails + 1)) ;; + *) echo "PASS a root with no old grant is left alone" ;; +esac +command rm -rf "$k3sroot" "$custom" + # --- the registry mirror writer ----------------------------------------------------------- # k3s only consults registries.yaml at agent start, so a CONTENT change must restart k3s and # an identical file (every re-run) must restart nothing. The k3s restart is the expensive,