chore(deploy): drop bubblewrap apt dep + tighten left4me.db mode

bubblewrap is no longer used now that left4me-script-sandbox runs as a
systemd service unit. Remove it from the apt-get and dnf install lines.

Also tighten the application database file mode after the alembic
upgrade step: chown root:left4me, chmod 0640. The DB had been created
at default 0644 by SQLite's open() call inside the web service, which
made it world-readable on the host — i.e. readable by any uid that can
traverse /var/lib/left4me, including the sandbox's l4d2-sandbox uid.
Smoke-testing the v2 sandbox prototype on ckn@10.0.4.128 surfaced this:
the sandbox could read "SQLite format 3" from the DB until the parent
dir was masked with TemporaryFileSystem=. Tightening the file mode is
the host-level fix; the sandbox-level mask is defense in depth.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mwiegand 2026-05-08 16:48:26 +02:00
parent 4ee8f6af44
commit ae443299c8
No known key found for this signature in database
2 changed files with 21 additions and 4 deletions

View file

@ -85,9 +85,9 @@ fi
if command -v apt-get >/dev/null 2>&1; then if command -v apt-get >/dev/null 2>&1; then
$sudo_cmd apt-get update $sudo_cmd apt-get update
$sudo_cmd apt-get install -y python3 python3-venv python3-pip curl ca-certificates tar gzip util-linux sudo bubblewrap $sudo_cmd apt-get install -y python3 python3-venv python3-pip curl ca-certificates tar gzip util-linux sudo
elif command -v dnf >/dev/null 2>&1; then elif command -v dnf >/dev/null 2>&1; then
$sudo_cmd dnf install -y python3 python3-pip curl ca-certificates tar gzip util-linux sudo bubblewrap $sudo_cmd dnf install -y python3 python3-pip curl ca-certificates tar gzip util-linux sudo
else else
printf 'Unsupported package manager: expected apt-get or dnf\n' >&2 printf 'Unsupported package manager: expected apt-get or dnf\n' >&2
exit 1 exit 1
@ -171,6 +171,16 @@ run_as_left4me sh -c "cd /opt/left4me/l4d2web && set -a; . /etc/left4me/host.env
PYTHONPATH=/opt/left4me \ PYTHONPATH=/opt/left4me \
/opt/left4me/.venv/bin/alembic -c /opt/left4me/l4d2web/alembic.ini upgrade head" /opt/left4me/.venv/bin/alembic -c /opt/left4me/l4d2web/alembic.ini upgrade head"
# Tighten the application database to root:left4me 0640. The DB is created
# by the web app at first start with the default 0644 umask, which makes it
# world-readable on the host. The script-overlay sandbox runs as a separate
# system uid (l4d2-sandbox) — without this clamp, a sandboxed script could
# read the entire app DB. Idempotent on rerun.
if [ -f /var/lib/left4me/left4me.db ]; then
$sudo_cmd chown root:left4me /var/lib/left4me/left4me.db
$sudo_cmd chmod 0640 /var/lib/left4me/left4me.db
fi
if [ -f "$remote_tmp/admin_username" ] && [ -f "$remote_tmp/admin_password" ]; then if [ -f "$remote_tmp/admin_username" ] && [ -f "$remote_tmp/admin_password" ]; then
LEFT4ME_ADMIN_USERNAME=$(cat "$remote_tmp/admin_username") LEFT4ME_ADMIN_USERNAME=$(cat "$remote_tmp/admin_username")
LEFT4ME_ADMIN_PASSWORD=$(cat "$remote_tmp/admin_password") LEFT4ME_ADMIN_PASSWORD=$(cat "$remote_tmp/admin_password")

View file

@ -294,14 +294,21 @@ def test_deploy_script_provisions_sandbox_user():
assert "useradd --system --no-create-home --shell /usr/sbin/nologin l4d2-sandbox" in script assert "useradd --system --no-create-home --shell /usr/sbin/nologin l4d2-sandbox" in script
def test_deploy_script_installs_bubblewrap(): def test_deploy_script_does_not_install_bubblewrap():
install_lines = [ install_lines = [
line for line in DEPLOY_SCRIPT.read_text().splitlines() line for line in DEPLOY_SCRIPT.read_text().splitlines()
if ("apt-get install" in line or "dnf install" in line) if ("apt-get install" in line or "dnf install" in line)
] ]
assert install_lines, "expected at least one apt/dnf install line" assert install_lines, "expected at least one apt/dnf install line"
for line in install_lines: for line in install_lines:
assert "bubblewrap" in line, f"missing bubblewrap in install line: {line}" assert "bubblewrap" not in line, line
assert "bwrap" not in line, line
def test_deploy_script_tightens_left4me_db_permissions():
script = DEPLOY_SCRIPT.read_text()
assert "chown root:left4me /var/lib/left4me/left4me.db" in script
assert "chmod 0640 /var/lib/left4me/left4me.db" in script
def test_deploy_script_installs_script_sandbox_helper(): def test_deploy_script_installs_script_sandbox_helper():