Jailed terminal: per-session tmpfs /home so users see only their own folder
Deploy Ladill Hosting / deploy (push) Successful in 1m41s
Deploy Ladill Hosting / deploy (push) Successful in 1m41s
Inside the jail, 'cd ..' from the home landed in a non-listable /home (Permission denied). Mount a per-session tmpfs over the jail's /home containing only the user's own directory, so 'ls /home' shows just their folder — no other tenants leaked, confinement unchanged. (Live host launcher already updated.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
18d1e735d8
commit
f7bba4d453
@@ -1,24 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Ladill jailed shell for the hosting browser terminal. Confines a hosting
|
# Ladill jailed shell for the hosting browser terminal. Confines a hosting
|
||||||
# account to /home/jail with only its own home bind-mounted (private mount ns).
|
# account to /home/jail with ONLY its own home visible: a private mount namespace
|
||||||
|
# plus a per-session tmpfs /home that contains just this user's directory (so
|
||||||
|
# 'ls /home' shows their own folder and never other tenants).
|
||||||
# Usage: ladill-jailsh <username> [relpath]
|
# Usage: ladill-jailsh <username> [relpath]
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
JAIL=/home/jail
|
JAIL=/home/jail
|
||||||
U=${1:-}
|
U=${1:-}
|
||||||
REL=${2:-/public_html}
|
REL=${2:-/public_html}
|
||||||
[ -n "$U" ] || { echo 'usage: ladill-jailsh <user> [relpath]'; exit 2; }
|
[ -n "$U" ] || { echo 'usage: ladill-jailsh <user> [relpath]'; exit 2; }
|
||||||
# resolve + validate the target user (must be a real hosting account)
|
|
||||||
UID_=$(id -u "$U" 2>/dev/null || true)
|
UID_=$(id -u "$U" 2>/dev/null || true)
|
||||||
GID_=$(id -g "$U" 2>/dev/null || true)
|
GID_=$(id -g "$U" 2>/dev/null || true)
|
||||||
[ -n "$UID_" ] && [ "$UID_" -ge 1000 ] || { echo 'refusing: not a hosting user'; exit 1; }
|
[ -n "$UID_" ] && [ "$UID_" -ge 1000 ] || { echo 'refusing: not a hosting user'; exit 1; }
|
||||||
HOMEDIR=/home/$U
|
HOMEDIR=/home/$U
|
||||||
[ -d "$HOMEDIR" ] || { echo 'no home directory'; exit 1; }
|
[ -d "$HOMEDIR" ] || { echo 'no home directory'; exit 1; }
|
||||||
case "$REL" in *..*) REL=/public_html;; esac
|
case "$REL" in *..*) REL=/public_html;; esac
|
||||||
mkdir -p "$JAIL/home/$U"
|
# re-exec into a private mount namespace so all mounts are per-session
|
||||||
# re-exec into a private mount namespace so the bind is per-session
|
|
||||||
if [ -z "${LADILL_JAIL_NS:-}" ]; then
|
if [ -z "${LADILL_JAIL_NS:-}" ]; then
|
||||||
exec env LADILL_JAIL_NS=1 unshare --mount --propagation private -- "$0" "$U" "$REL"
|
exec env LADILL_JAIL_NS=1 unshare --mount --propagation private -- "$0" "$U" "$REL"
|
||||||
fi
|
fi
|
||||||
|
# Fresh, listable /home holding ONLY this user's directory (no tenant leak).
|
||||||
|
mount -t tmpfs -o mode=0755,nosuid,nodev tmpfs "$JAIL/home"
|
||||||
|
mkdir -p "$JAIL/home/$U"
|
||||||
mount --bind "$HOMEDIR" "$JAIL/home/$U"
|
mount --bind "$HOMEDIR" "$JAIL/home/$U"
|
||||||
export HOME="/home/$U" USER="$U" LOGNAME="$U" SHELL=/bin/bash PATH=/usr/bin:/bin
|
export HOME="/home/$U" USER="$U" LOGNAME="$U" SHELL=/bin/bash PATH=/usr/bin:/bin
|
||||||
export TERM="${TERM:-xterm-256color}"
|
export TERM="${TERM:-xterm-256color}"
|
||||||
|
|||||||
Reference in New Issue
Block a user