commit 91c5eb1d9df1aa83a5b9ad4bcef0658d83608dac Author: Philip Henning Date: Mon Nov 18 18:36:30 2024 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ed9326 --- /dev/null +++ b/.gitignore @@ -0,0 +1,70 @@ +# Project +.env +data + +# VScode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk diff --git a/README.md b/README.md new file mode 100644 index 0000000..8c39b03 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# `sso.base23.de` - Base23 SSO for all services + +[Authentik](https://goauthentik.io/) based sso for us. + +## Prerequisites - Server Setup + +```shell +apt update \ + && apt upgrade -y \ + && for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt remove $pkg; done \ + && apt install ca-certificates curl \ + && install -m 0755 -d /etc/apt/keyrings \ + && curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \ + && chmod a+r /etc/apt/keyrings/docker.asc \ + && echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null \ + && apt update \ + && apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin \ + && mkdir -p /var/lib/apps \ + && ln -s /var/lib/apps \ + && apt install -y git +``` + +## Installation + +Clone & configure initially: +```shell +cd /root/apps \ + && git clone ssh://git@git.base23.de:222/base23/sso.base23.de.git \ + && cd sso.base23.de \ + && ./init.sh \ + && docker compose up -d; docker compose logs -f +``` + +## Upgrade + +1. Update `AUTHENTIK_TAG` to the desired tag in `env.template`, as well as +in the deployed `.env` file. +2. `docker-compose down` +3. `docker compose up -d; docker compose logs -f` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..139c140 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,125 @@ +--- + +services: + postgresql: + image: docker.io/library/postgres:16-alpine + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 5s + volumes: + - database:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: ${PG_PASS:?database password required} + POSTGRES_USER: ${PG_USER:-authentik} + POSTGRES_DB: ${PG_DB:-authentik} + env_file: + - .env + networks: + - net + + redis: + image: docker.io/library/redis:alpine + command: --save 60 1 --loglevel warning + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 3s + volumes: + - redis:/data + networks: + - net + + server: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.0} + restart: unless-stopped + command: server + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} + volumes: + - ./data/media:/media + - ./data/custom-templates:/templates + - geoip:/geoip + env_file: + - .env + # ports: + # - "${COMPOSE_PORT_HTTP:-9000}:9000" + # - "${COMPOSE_PORT_HTTPS:-9443}:9443" + depends_on: + - postgresql + - redis + networks: + - net + - web + labels: + - "traefik.enable=true" + - traefik.docker.network=web + - traefik.port=9443 + - traefik.frontend.rule=Host:${PUBLIC_DOMAIN} + - traefik.protocol=https + + worker: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.0} + restart: unless-stopped + command: worker + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} + # `user: root` and the docker socket volume are optional. + # See more for the docker socket integration here: + # https://goauthentik.io/docs/outposts/integrations/docker + # Removing `user: root` also prevents the worker from fixing the permissions + # on the mounted folders, so when removing this make sure the folders have the correct UID/GID + # (1000:1000 by default) + user: root + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./data/media:/media + - ./data/certs:/certs + - ./data/custom-templates:/templates + - geoip:/geoip + env_file: + - .env + depends_on: + - postgresql + - redis + networks: + - net + + geoipupdate: + image: "maxmindinc/geoipupdate:latest" + volumes: + - "geoip:/usr/share/GeoIP" + environment: + GEOIPUPDATE_EDITION_IDS: "GeoLite2-City GeoLite2-ASN" + GEOIPUPDATE_FREQUENCY: "8" + GEOIPUPDATE_ACCOUNT_ID: "${GEOIPUPDATE_ACCOUNT_ID:?MaxMind GeoIP account ID required}" + GEOIPUPDATE_LICENSE_KEY: "${GEOIPUPDATE_LICENSE_KEY:?MaxMind GeoIP license key required}" + + +volumes: + database: + driver: local + redis: + driver: local + geoip: + driver: local + + +networks: + net: + web: + external: true diff --git a/env.template b/env.template new file mode 100644 index 0000000..b47cae4 --- /dev/null +++ b/env.template @@ -0,0 +1,40 @@ +# SETTINGS from env.template +# Misc configuration +PUBLIC_DOMAIN=sso.base23.de +COMPOSE_PROJECT_NAME=sso-base23-de + +# Auhtentik version +AUTHENTIK_TAG=2024.10.2 + +# Error reporting & Logging +AUTHENTIK_ERROR_REPORTING__ENABLED=true +AUTHENTIK_LOG_LEVEL=warning + +# Email configuration +# SMTP Host Emails are sent to +AUTHENTIK_EMAIL__HOST=mail.base23.de +AUTHENTIK_EMAIL__PORT=25 +AUTHENTIK_EMAIL__USERNAME=sso@base23.de +# Use StartTLS +AUTHENTIK_EMAIL__USE_TLS=true +# Use SSL +AUTHENTIK_EMAIL__USE_SSL=false +AUTHENTIK_EMAIL__TIMEOUT=10 +# Email address authentik will send from, should have a correct @domain +AUTHENTIK_EMAIL__FROM=sso@base23.de + +# Exposed ports for Authentik -- Ports are note exposed due to traefik setup +# COMPOSE_PORT_HTTP=80 +# COMPOSE_PORT_HTTPS=443 + +# Liste settings +AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS="172.18.0.0/16" + + +# MaxMind GeoIP +GEOIPUPDATE_ACCOUNT_ID=765001 + +# PostgreSQL configuration +PG_USER=authentik +POSTGRES_DB=authentik + diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..7b54fc4 --- /dev/null +++ b/init.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -euf -o pipefail + +# Function to securely query user for a password, verify it, and return it for further use +prompt_password() { + local purpose="$1" + local password password_confirm + + while true; do + printf "Enter password for %s: " "$purpose" + read -rs password + printf "\nConfirm password for %s: " "$purpose" + read -rs password_confirm + printf "\n" + + # Check if passwords match + if [[ "$password" == "$password_confirm" ]]; then + RETURNED_PASSWORD="$password" + printf "Password verified for %s.\n" "$purpose" + return 0 + else + printf "Error: Passwords do not match. Please try again.\n" >&2 + fi + done +} + +# Trap SIGINT to exit gracefully if the user aborts with CTRL+C +trap 'printf "\nOperation aborted by user.\n" >&2; rm .env; exit 1' SIGINT + + +cd "$(dirname "$(realpath "$0")")" + +# Check if .env exists and exit if it is +[[ -f ./.env ]] && echo ".env already exists. Exiting!" && exit 1 || true + +cat ./env.template >> .env +echo "# SECRETS" >> .env +echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env +echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env +prompt_password "AUTHENTIK_EMAIL__PASSWORD"; echo "AUTHENTIK_EMAIL__PASSWORD=${RETURNED_PASSWORD}" >> .env; unset RETURNED_PASSWORD +prompt_password "GEOIPUPDATE_LICENSE_KEY"; echo "GEOIPUPDATE_LICENSE_KEY=${RETURNED_PASSWORD}" >> .env; unset RETURNED_PASSWORD +echo "" >> .env