feat: единая админка runtime-конфигов и indpic (#22)
deploy-preland / deploy zoomstage.online (push) Successful in 1m1s

This commit is contained in:
Panfilov Konstantin committed 2026-10-25 11:33:56 +03:00
1 parent 5b6b2d2053
commit 9515c1c62b
52 files changed
+2459 -34

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
# Запуск только в одноразовом Docker-контейнере от root, без host state/socket.
set -eu
test "$(id -u)" = 0
test ! -e /srv/preland-admin
test ! -e /usr/bin/docker
base=/srv/preland-admin
install -d -m 700 "$base" "$base/secrets" "$base/deploy" /tmp/catalog-victim
install -d -m 700 -o 997 -g 987 "$base/state"
printf 'unchanged\n' > /tmp/catalog-victim/original
printf 'not executed\n' > "$base/deploy/export-catalog.php"
cat > /usr/bin/docker <<'SH'
#!/bin/sh
printf '%s\n' '{"host":"zoomzilla.ru","generated_at":"2026-10-25T00:00:00Z","groups":{"degr":[],"tp":[],"cons":[]}}'
SH
chmod 755 /usr/bin/docker
# Унаследованный cwd моделирует доступ к корню bind mount внутри приложения,
# минуя закрытый host-parent /srv/preland-admin.
(cd "$base/state" && setpriv --reuid=997 --regid=987 --clear-groups ln -s /tmp/catalog-victim catalog.json)
sed 's/\r$//' /work/admin/deploy/refresh-catalog.sh > /tmp/catalog-refresh.sh
bash /tmp/catalog-refresh.sh
test ! -L "$base/state/catalog.json"
test -f "$base/state/catalog.json"
test "$(stat -c %u /tmp/catalog-victim/original)" = 0
test "$(cat /tmp/catalog-victim/original)" = unchanged
test "$(find /tmp/catalog-victim -type f | wc -l)" = 1
test "$(stat -c '%u:%g:%a' "$base/state/catalog.json")" = 997:987:600
if setpriv --reuid=997 --regid=987 --clear-groups ls "$base/secrets" >/dev/null 2>&1; then
echo 'FAIL: app UID can inspect root preparation directory' >&2
exit 1
fi
echo 'PASS root catalog publisher replaces destination symlink without following it; victim and owner intact; preparation inaccessible to app UID'