feat(authentik): LXC-Vorlage — Nesting, Agent-SSH-Key, automatisierungsfreundlich (nexus ADR-0003/K-102)
This commit is contained in:
+105
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env bash
|
||||
# Authentik — zentraler Homelab-IdP (nexus ADR-0003)
|
||||
#
|
||||
# Creates an unprivileged Debian 12 LXC with nesting enabled that runs the
|
||||
# official Authentik docker-compose stack (server, worker, postgres, redis).
|
||||
#
|
||||
# Automation-friendly by design (nexus-hub K-102):
|
||||
# - bootstrap admin password AND API token are generated headlessly
|
||||
# (-> /root/authentik.credentials) so an agent can apply blueprints via
|
||||
# API without ever touching the UI
|
||||
# - optional dedicated SSH public key for agent access (Claude Code)
|
||||
# - blueprints dir mounted at /opt/authentik/blueprints (compose override)
|
||||
#
|
||||
# Manual steps that remain AFTER this script (by design):
|
||||
# 1. NPMplus: proxy host auth.<domain> -> http://<LXC-IP>:9000
|
||||
# (WebSockets ON; the auth domain is PERMANENT — WebAuthn RP-ID!)
|
||||
# 2. Passkey enrollment of the human admin account
|
||||
#
|
||||
# Run on a Proxmox VE host:
|
||||
# bash -c "$(curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/ct/authentik.sh)"
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APP="authentik"
|
||||
APP_DESCRIPTION="Authentik IdP (Docker-Compose) — Passkeys, TOTP, OIDC für nexus & Homelab"
|
||||
APP_PORT="${APP_PORT:-9000}"
|
||||
|
||||
LIB_URL="${LIB_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/lib}"
|
||||
INSTALL_SCRIPT_URL="${INSTALL_SCRIPT_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/install/authentik-install.sh}"
|
||||
|
||||
# LXC defaults (server+worker+postgres+redis brauchen Luft)
|
||||
DEFAULT_HOSTNAME="authentik"
|
||||
DEFAULT_DISK="20"
|
||||
DEFAULT_CORES="2"
|
||||
DEFAULT_RAM="4096"
|
||||
|
||||
prompt_app_config() {
|
||||
echo
|
||||
echo "── Authentik configuration ─────────────────────────────────"
|
||||
if [[ -z "${AUTH_DOMAIN:-}" ]]; then
|
||||
read -rp "Auth-Domain (dauerhaft! WebAuthn-RP-ID), z. B. auth.luki-net.org: " AUTH_DOMAIN
|
||||
fi
|
||||
[[ -n "${AUTH_DOMAIN:-}" ]] || { msg_err "AUTH_DOMAIN ist Pflicht"; exit 1; }
|
||||
if [[ -z "${CLAUDE_SSH_PUBKEY:-}" ]]; then
|
||||
read -rp "SSH-Public-Key für Agent-Zugang (leer = überspringen): " CLAUDE_SSH_PUBKEY || true
|
||||
fi
|
||||
# Authentik-Version: leer = Default des offiziellen Compose-Files
|
||||
AUTHENTIK_TAG="${AUTHENTIK_TAG:-}"
|
||||
echo " → domain: $AUTH_DOMAIN port: $APP_PORT tag: ${AUTHENTIK_TAG:-compose-default}"
|
||||
}
|
||||
|
||||
push_app_config() {
|
||||
msg_info "Pushing config into container..."
|
||||
local tmpf; tmpf=$(mktemp)
|
||||
cat >"$tmpf" <<EOF
|
||||
AUTH_DOMAIN='$AUTH_DOMAIN'
|
||||
APP_PORT='$APP_PORT'
|
||||
AUTHENTIK_TAG='$AUTHENTIK_TAG'
|
||||
CLAUDE_SSH_PUBKEY='${CLAUDE_SSH_PUBKEY:-}'
|
||||
EOF
|
||||
pct push "$CTID" "$tmpf" /root/authentik.deploy.env --perms 600
|
||||
rm -f "$tmpf"
|
||||
}
|
||||
|
||||
# Docker im unprivilegierten LXC braucht nesting+keyctl — vor dem Bootstrap setzen.
|
||||
enable_nesting() {
|
||||
msg_info "Enabling nesting+keyctl features (Docker in unprivileged LXC)..."
|
||||
pct set "$CTID" --features nesting=1,keyctl=1
|
||||
pct reboot "$CTID"
|
||||
# warten bis der Container wieder antwortet
|
||||
for _ in $(seq 1 30); do
|
||||
pct exec "$CTID" -- true >/dev/null 2>&1 && break
|
||||
sleep 2
|
||||
done
|
||||
msg_ok "Container restarted with nesting enabled"
|
||||
}
|
||||
|
||||
print_app_summary() {
|
||||
cat <<EOF
|
||||
Authentik: http://$IP_CT:$APP_PORT (UI nach erstem Start, dauert 1–2 min)
|
||||
Credentials/API-Token: /root/authentik.credentials (im LXC; akadmin + Bootstrap-Token)
|
||||
Blueprints: /opt/authentik/blueprints (gemountet; Agent legt YAMLs ab,
|
||||
Quelle versioniert in nexus-hub infra/authentik/)
|
||||
|
||||
⚠️ JETZT MANUELL (dauerhaft — WebAuthn-RP-ID):
|
||||
NPMplus: Proxy Host $AUTH_DOMAIN → http://$IP_CT:$APP_PORT (WebSockets: ON)
|
||||
|
||||
Danach: Agent (Claude Code) per SSH übernimmt Blueprints/OIDC-Provider;
|
||||
zuletzt Passkey-Enrollment des menschlichen Admin-Accounts über $AUTH_DOMAIN.
|
||||
|
||||
Logs: pct exec $CTID -- docker compose -f /opt/authentik/docker-compose.yml logs -f
|
||||
EOF
|
||||
}
|
||||
|
||||
trap _on_error ERR
|
||||
preflight_pve
|
||||
show_header "$APP" "$APP_DESCRIPTION"
|
||||
prompt_lxc_config
|
||||
prompt_app_config
|
||||
resolve_debian_template
|
||||
create_lxc
|
||||
enable_nesting
|
||||
push_app_config
|
||||
bootstrap_install_script "$INSTALL_SCRIPT_URL"
|
||||
print_summary
|
||||
Reference in New Issue
Block a user