feat: add Authelia SSO authentication service
- Add Authelia service to NET stack for centralized SSO - Create configuration.yml with PostgreSQL storage - Create users_database.yml for file-based user management - Add authelia database to PostgreSQL init script - Configure Traefik ForwardAuth middleware - Add environment variables to arty.yml - Supports TOTP and WebAuthn 2FA - Email notifications via Mailpit SMTP relay - Protected services: netdata, mailpit, scrapy, restic, traefik, dev, n8n, asciinema, coolify
This commit is contained in:
3
arty.yml
3
arty.yml
@@ -125,6 +125,9 @@ envs:
|
|||||||
# Mailpit SMTP Relay
|
# Mailpit SMTP Relay
|
||||||
NET_MAILPIT_IMAGE: axllent/mailpit:latest
|
NET_MAILPIT_IMAGE: axllent/mailpit:latest
|
||||||
NET_MAILPIT_TRAEFIK_HOST: mailpit.pivoine.art
|
NET_MAILPIT_TRAEFIK_HOST: mailpit.pivoine.art
|
||||||
|
# Authelia SSO
|
||||||
|
NET_AUTHELIA_IMAGE: authelia/authelia:latest
|
||||||
|
NET_AUTHELIA_TRAEFIK_HOST: auth.pivoine.art
|
||||||
# AI Stack
|
# AI Stack
|
||||||
AI_TRAEFIK_ENABLED: true
|
AI_TRAEFIK_ENABLED: true
|
||||||
AI_COMPOSE_PROJECT_NAME: ai
|
AI_COMPOSE_PROJECT_NAME: ai
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E
|
|||||||
SELECT 'CREATE DATABASE coolify'
|
SELECT 'CREATE DATABASE coolify'
|
||||||
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'coolify')\\gexec
|
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'coolify')\\gexec
|
||||||
|
|
||||||
|
-- Authelia SSO authentication database
|
||||||
|
SELECT 'CREATE DATABASE authelia'
|
||||||
|
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'authelia')\\gexec
|
||||||
|
|
||||||
-- Grant privileges to all databases
|
-- Grant privileges to all databases
|
||||||
GRANT ALL PRIVILEGES ON DATABASE directus TO $POSTGRES_USER;
|
GRANT ALL PRIVILEGES ON DATABASE directus TO $POSTGRES_USER;
|
||||||
GRANT ALL PRIVILEGES ON DATABASE umami TO $POSTGRES_USER;
|
GRANT ALL PRIVILEGES ON DATABASE umami TO $POSTGRES_USER;
|
||||||
@@ -60,11 +64,12 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E
|
|||||||
GRANT ALL PRIVILEGES ON DATABASE asciinema TO $POSTGRES_USER;
|
GRANT ALL PRIVILEGES ON DATABASE asciinema TO $POSTGRES_USER;
|
||||||
GRANT ALL PRIVILEGES ON DATABASE gitea TO $POSTGRES_USER;
|
GRANT ALL PRIVILEGES ON DATABASE gitea TO $POSTGRES_USER;
|
||||||
GRANT ALL PRIVILEGES ON DATABASE coolify TO $POSTGRES_USER;
|
GRANT ALL PRIVILEGES ON DATABASE coolify TO $POSTGRES_USER;
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE authelia TO $POSTGRES_USER;
|
||||||
|
|
||||||
-- Log success
|
-- Log success
|
||||||
SELECT 'Compose databases initialized:' AS status;
|
SELECT 'Compose databases initialized:' AS status;
|
||||||
SELECT datname FROM pg_database
|
SELECT datname FROM pg_database
|
||||||
WHERE datname IN ('directus', 'umami', 'n8n', 'linkwarden', 'joplin', 'mattermost', 'tandoor', 'asciinema', 'gitea', 'coolify')
|
WHERE datname IN ('directus', 'umami', 'n8n', 'linkwarden', 'joplin', 'mattermost', 'tandoor', 'asciinema', 'gitea', 'coolify', 'authelia')
|
||||||
ORDER BY datname;
|
ORDER BY datname;
|
||||||
EOSQL
|
EOSQL
|
||||||
|
|
||||||
@@ -83,4 +88,5 @@ echo " • tandoor - Recipe manager database"
|
|||||||
echo " • asciinema - Terminal recording server database"
|
echo " • asciinema - Terminal recording server database"
|
||||||
echo " • gitea - Self-hosted Git service database"
|
echo " • gitea - Self-hosted Git service database"
|
||||||
echo " • coolify - Deployment platform database"
|
echo " • coolify - Deployment platform database"
|
||||||
|
echo " • authelia - SSO authentication database"
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
116
net/authelia/configuration.yml
Normal file
116
net/authelia/configuration.yml
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
---
|
||||||
|
###############################################################
|
||||||
|
# Authelia Configuration #
|
||||||
|
###############################################################
|
||||||
|
|
||||||
|
theme: auto
|
||||||
|
|
||||||
|
server:
|
||||||
|
host: 0.0.0.0
|
||||||
|
port: 9091
|
||||||
|
path: ""
|
||||||
|
asset_path: /config/assets/
|
||||||
|
headers:
|
||||||
|
csp_template: ""
|
||||||
|
|
||||||
|
log:
|
||||||
|
level: info
|
||||||
|
format: text
|
||||||
|
|
||||||
|
totp:
|
||||||
|
issuer: pivoine.art
|
||||||
|
period: 30
|
||||||
|
skew: 1
|
||||||
|
|
||||||
|
webauthn:
|
||||||
|
disable: false
|
||||||
|
display_name: Pivoine Auth
|
||||||
|
attestation_conveyance_preference: indirect
|
||||||
|
user_verification: preferred
|
||||||
|
timeout: 60s
|
||||||
|
|
||||||
|
ntp:
|
||||||
|
address: "time.cloudflare.com:123"
|
||||||
|
version: 4
|
||||||
|
max_desync: 3s
|
||||||
|
disable_startup_check: false
|
||||||
|
disable_failure: false
|
||||||
|
|
||||||
|
authentication_backend:
|
||||||
|
password_reset:
|
||||||
|
disable: false
|
||||||
|
refresh_interval: 5m
|
||||||
|
file:
|
||||||
|
path: /etc/authelia/users_database.yml
|
||||||
|
password:
|
||||||
|
algorithm: argon2
|
||||||
|
argon2:
|
||||||
|
variant: argon2id
|
||||||
|
iterations: 3
|
||||||
|
memory: 65536
|
||||||
|
parallelism: 4
|
||||||
|
key_length: 32
|
||||||
|
salt_length: 16
|
||||||
|
|
||||||
|
access_control:
|
||||||
|
default_policy: deny
|
||||||
|
rules:
|
||||||
|
# Authelia portal itself
|
||||||
|
- domain: auth.pivoine.art
|
||||||
|
policy: bypass
|
||||||
|
|
||||||
|
# Services that should be publicly accessible
|
||||||
|
- domain:
|
||||||
|
- "pivoine.art"
|
||||||
|
- "www.pivoine.art"
|
||||||
|
policy: bypass
|
||||||
|
|
||||||
|
# Protected services - require authentication
|
||||||
|
- domain:
|
||||||
|
- "netdata.pivoine.art"
|
||||||
|
- "mailpit.pivoine.art"
|
||||||
|
- "scrapy.pivoine.art"
|
||||||
|
- "restic.pivoine.art"
|
||||||
|
- "traefik.pivoine.art"
|
||||||
|
policy: two_factor
|
||||||
|
|
||||||
|
# Development services
|
||||||
|
- domain:
|
||||||
|
- "dev.pivoine.art"
|
||||||
|
- "n8n.pivoine.art"
|
||||||
|
- "asciinema.pivoine.art"
|
||||||
|
- "coolify.pivoine.art"
|
||||||
|
policy: two_factor
|
||||||
|
|
||||||
|
session:
|
||||||
|
name: authelia_session
|
||||||
|
domain: pivoine.art
|
||||||
|
same_site: lax
|
||||||
|
expiration: 1h
|
||||||
|
inactivity: 5m
|
||||||
|
remember_me_duration: 1M
|
||||||
|
|
||||||
|
regulation:
|
||||||
|
max_retries: 3
|
||||||
|
find_time: 2m
|
||||||
|
ban_time: 5m
|
||||||
|
|
||||||
|
storage:
|
||||||
|
encryption_key: ${AUTHELIA_STORAGE_ENCRYPTION_KEY}
|
||||||
|
postgres:
|
||||||
|
host: postgres
|
||||||
|
port: 5432
|
||||||
|
database: authelia
|
||||||
|
username: valknar
|
||||||
|
password: ${DB_PASSWORD}
|
||||||
|
schema: public
|
||||||
|
|
||||||
|
notifier:
|
||||||
|
disable_startup_check: false
|
||||||
|
smtp:
|
||||||
|
host: net_mailpit
|
||||||
|
port: 1025
|
||||||
|
sender: auth@pivoine.art
|
||||||
|
identifier: auth.pivoine.art
|
||||||
|
disable_require_tls: true
|
||||||
|
disable_html_emails: false
|
||||||
16
net/authelia/users_database.yml
Normal file
16
net/authelia/users_database.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
###############################################################
|
||||||
|
# Users Database #
|
||||||
|
###############################################################
|
||||||
|
|
||||||
|
# This file can be used if you do not have an LDAP set up.
|
||||||
|
|
||||||
|
# List of users
|
||||||
|
users:
|
||||||
|
valknar:
|
||||||
|
displayname: "Valknar"
|
||||||
|
password: "$argon2id$v=19$m=65536,t=3,p=4$c2FsdHNhbHRzYWx0$4oCb4oCh4oCd4oCi4oCl4oCm" # CHANGE THIS - use: docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'yourpassword'
|
||||||
|
email: valknar@pivoine.art
|
||||||
|
groups:
|
||||||
|
- admins
|
||||||
|
- dev
|
||||||
@@ -265,6 +265,43 @@ services:
|
|||||||
# Watchtower
|
# Watchtower
|
||||||
- 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}'
|
- 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}'
|
||||||
|
|
||||||
|
# Authelia - SSO and authentication portal
|
||||||
|
authelia:
|
||||||
|
image: ${NET_AUTHELIA_IMAGE:-authelia/authelia:latest}
|
||||||
|
container_name: ${NET_COMPOSE_PROJECT_NAME}_authelia
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
TZ: ${TIMEZONE:-Europe/Berlin}
|
||||||
|
AUTHELIA_JWT_SECRET: ${AUTHELIA_JWT_SECRET}
|
||||||
|
AUTHELIA_SESSION_SECRET: ${AUTHELIA_SESSION_SECRET}
|
||||||
|
AUTHELIA_STORAGE_ENCRYPTION_KEY: ${AUTHELIA_STORAGE_ENCRYPTION_KEY}
|
||||||
|
volumes:
|
||||||
|
- authelia_config:/config
|
||||||
|
- ./authelia:/etc/authelia:ro
|
||||||
|
networks:
|
||||||
|
- compose_network
|
||||||
|
labels:
|
||||||
|
- 'traefik.enable=${NET_TRAEFIK_ENABLED}'
|
||||||
|
# HTTP to HTTPS redirect
|
||||||
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-authelia-redirect-web-secure.redirectscheme.scheme=https'
|
||||||
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-authelia-web.middlewares=${NET_COMPOSE_PROJECT_NAME}-authelia-redirect-web-secure'
|
||||||
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-authelia-web.rule=Host(`${NET_AUTHELIA_TRAEFIK_HOST}`)'
|
||||||
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-authelia-web.entrypoints=web'
|
||||||
|
# HTTPS router
|
||||||
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-authelia-web-secure.rule=Host(`${NET_AUTHELIA_TRAEFIK_HOST}`)'
|
||||||
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-authelia-web-secure.tls.certresolver=resolver'
|
||||||
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-authelia-web-secure.entrypoints=web-secure'
|
||||||
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-authelia-web-secure.middlewares=security-headers@file'
|
||||||
|
# Service
|
||||||
|
- 'traefik.http.services.${NET_COMPOSE_PROJECT_NAME}-authelia-web-secure.loadbalancer.server.port=9091'
|
||||||
|
- 'traefik.docker.network=${NETWORK_NAME}'
|
||||||
|
# ForwardAuth middleware for other services
|
||||||
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-authelia.forwardAuth.address=http://authelia:9091/api/verify?rd=https://${NET_AUTHELIA_TRAEFIK_HOST}'
|
||||||
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-authelia.forwardAuth.trustForwardHeader=true'
|
||||||
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'
|
||||||
|
# Watchtower
|
||||||
|
- 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}'
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
letsencrypt_data:
|
letsencrypt_data:
|
||||||
name: ${NET_COMPOSE_PROJECT_NAME}_letsencrypt_data
|
name: ${NET_COMPOSE_PROJECT_NAME}_letsencrypt_data
|
||||||
@@ -276,6 +313,8 @@ volumes:
|
|||||||
name: ${NET_COMPOSE_PROJECT_NAME}_netdata_cache
|
name: ${NET_COMPOSE_PROJECT_NAME}_netdata_cache
|
||||||
mailpit_data:
|
mailpit_data:
|
||||||
name: ${NET_COMPOSE_PROJECT_NAME}_mailpit_data
|
name: ${NET_COMPOSE_PROJECT_NAME}_mailpit_data
|
||||||
|
authelia_config:
|
||||||
|
name: ${NET_COMPOSE_PROJECT_NAME}_authelia_config
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
compose_network:
|
compose_network:
|
||||||
|
|||||||
Reference in New Issue
Block a user