Restores the kernel-level isolation the pre-cutover ttyd-session.sh had, but keeps the multi-session lobby UX: - ttyd.service gets `-H X-authentik-username` back. `tmux-attach.sh` reads $TTYD_USER, looks up the local part in /etc/ttyd-user-map, denies the connection (no fallback to wizard) if there's no mapping, otherwise `sudo -n -H -u <os_user> tmux …`. Each Authentik identity → its own Unix user → its own `/tmp/tmux-<uid>/default` socket. - tmux-api scopes every request to the same OS user via the same header. Adds /whoami so the lobby HTML can preflight access and render "logged in as <os_user> (<authentik>)" instead of leaving the user to discover the deny via a reconnect loop. - Commits /etc/ttyd-user-map and the matching /etc/sudoers.d/ttyd-users fragment under files/devvm/ so future operators see one canonical source of truth. Current mappings: vbarzin → wizard, emil.barzin → emo. Adding a user is now: append a line to ttyd-user-map + a NOPASSWD sudoers line + `useradd -m`. README walks through it. No Terraform changes — this is all DevVM-side + lobby JS.
53 lines
1.6 KiB
Bash
53 lines
1.6 KiB
Bash
#!/usr/bin/env bash
|
|
# Invoked by ttyd.service per WebSocket connection. ttyd's `-a` flag
|
|
# forwards `?arg=<value>` as $1; `-H X-authentik-username` sets
|
|
# $TTYD_USER to the Authentik identity.
|
|
#
|
|
# We map TTYD_USER → OS user via /etc/ttyd-user-map and sudo into that
|
|
# user before running tmux, so each Authentik identity gets its own
|
|
# kernel-isolated tmux server (one socket per uid). Authentik users
|
|
# without a mapping are denied — no fallback to a shared account.
|
|
set -euo pipefail
|
|
|
|
MAP=/etc/ttyd-user-map
|
|
NAME_RE='^[a-zA-Z0-9_-]{1,32}$'
|
|
|
|
auth_user="${TTYD_USER:-}"
|
|
auth_local="${auth_user%%@*}"
|
|
|
|
os_user=""
|
|
if [[ -n "$auth_local" && -r "$MAP" ]]; then
|
|
os_user=$(awk -F= -v k="$auth_local" '
|
|
/^[[:space:]]*(#|$)/ {next}
|
|
$1==k {sub(/:.*$/, "", $2); print $2; exit}
|
|
' "$MAP")
|
|
fi
|
|
|
|
if [[ -z "$os_user" ]] || ! id "$os_user" >/dev/null 2>&1; then
|
|
cat <<EOF
|
|
|
|
Access denied
|
|
─────────────
|
|
No terminal account for Authentik user '${auth_user:-<missing header>}'.
|
|
|
|
This DevVM maps Authentik identities to OS users via
|
|
/etc/ttyd-user-map. Ask Viktor to add a mapping (and a matching
|
|
/etc/sudoers.d/ttyd-users entry) if you should have access.
|
|
|
|
EOF
|
|
sleep 10
|
|
exit 1
|
|
fi
|
|
|
|
# Session name from URL ?arg=<name>; default to the OS user's own name.
|
|
name="${1:-$os_user}"
|
|
[[ "$name" =~ $NAME_RE ]] || name="$os_user"
|
|
|
|
home_dir=$(getent passwd "$os_user" | cut -d: -f6)
|
|
home_dir="${home_dir:-/}"
|
|
|
|
if [[ "$os_user" == "$(id -un)" ]]; then
|
|
exec tmux new-session -A -s "$name" -c "$home_dir"
|
|
else
|
|
exec sudo -n -H -u "$os_user" tmux new-session -A -s "$name" -c "$home_dir"
|
|
fi
|