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