Initial Authelia + fail2ban stack
Self-hosted SSO portal with file-based users, SQLite storage, filesystem notifier, and an iptables-banning fail2ban sidecar. Designed to drop into a DotheEvo-style ~/docker layout next to a dockerized Caddy on the main server, joining the same external caddy_net so Caddy reaches Authelia by container name. fail2ban runs in host network mode with NET_ADMIN/NET_RAW caps so its bans hit DOCKER-USER and actually drop packets at the edge. Includes a Caddy snippet (caddy/snippet.example.caddyfile) to merge into the user's real Caddyfile -- this repo doesn't manage Caddy itself. https://claude.ai/code/session_013XZ1vmgk78k2PEQ5DmJhF3
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
---
|
||||
###############################################################################
|
||||
# Authelia configuration
|
||||
#
|
||||
# - File-based user database (no LDAP)
|
||||
# - SQLite local storage (no Redis, no MySQL/Postgres)
|
||||
# - Filesystem notifier (writes "emails" to /config/notifications/...)
|
||||
# - Argon2id password hashing
|
||||
# - Per-domain access policies under access_control.rules
|
||||
#
|
||||
# Secrets are NOT in this file. They are loaded from files mounted at
|
||||
# /secrets via the AUTHELIA_*_FILE env vars in docker-compose.yml.
|
||||
#
|
||||
# After editing, validate before restarting:
|
||||
# docker compose run --rm authelia authelia validate-config --config /config/configuration.yml
|
||||
###############################################################################
|
||||
|
||||
theme: 'dark'
|
||||
|
||||
server:
|
||||
address: 'tcp://0.0.0.0:9091'
|
||||
buffers:
|
||||
read: 8192
|
||||
write: 8192
|
||||
|
||||
log:
|
||||
level: 'info'
|
||||
format: 'text' # fail2ban filter expects text format
|
||||
file_path: '/config/authelia.log'
|
||||
keep_stdout: true # also log to stdout for `docker logs`
|
||||
|
||||
identity_validation:
|
||||
reset_password:
|
||||
jwt_lifespan: '5 minutes'
|
||||
jwt_algorithm: 'HS256'
|
||||
# jwt_secret loaded via AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE
|
||||
|
||||
totp:
|
||||
disable: false
|
||||
issuer: 'example.com' # CHANGE: your root domain (shown in authenticator app)
|
||||
algorithm: 'sha1'
|
||||
digits: 6
|
||||
period: 30
|
||||
|
||||
authentication_backend:
|
||||
password_change:
|
||||
disable: false
|
||||
password_reset:
|
||||
disable: false
|
||||
refresh_interval: '5 minutes'
|
||||
file:
|
||||
path: '/config/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 means every domain Authelia sees must have an
|
||||
# explicit allow rule. Caddy only sends a domain to Authelia when its site
|
||||
# block has `import authelia`, so domains you don't proxy through Authelia
|
||||
# aren't affected.
|
||||
#
|
||||
# Policies:
|
||||
# bypass no auth (Authelia portal itself)
|
||||
# one_factor password only
|
||||
# two_factor password + TOTP
|
||||
# ---------------------------------------------------------------------------
|
||||
access_control:
|
||||
default_policy: 'deny'
|
||||
rules:
|
||||
- domain: 'auth.example.com' # CHANGE
|
||||
policy: 'bypass'
|
||||
|
||||
# Examples -- uncomment / change to your subdomains:
|
||||
# - domain: 'cam.example.com'
|
||||
# policy: 'one_factor'
|
||||
# - domain: 'doorbell.example.com'
|
||||
# policy: 'two_factor'
|
||||
|
||||
session:
|
||||
# secret loaded via AUTHELIA_SESSION_SECRET_FILE
|
||||
cookies:
|
||||
- name: 'authelia_session'
|
||||
domain: 'example.com' # CHANGE: your root domain
|
||||
authelia_url: 'https://auth.example.com' # CHANGE
|
||||
default_redirection_url: 'https://example.com' # CHANGE
|
||||
expiration: '1 hour'
|
||||
inactivity: '5 minutes'
|
||||
remember_me: '1 month'
|
||||
same_site: 'lax'
|
||||
|
||||
# In-app rate limiting. First line of defense; fail2ban is the second.
|
||||
regulation:
|
||||
max_retries: 3
|
||||
find_time: '2 minutes'
|
||||
ban_time: '5 minutes'
|
||||
|
||||
storage:
|
||||
# encryption_key loaded via AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE
|
||||
local:
|
||||
path: '/config/db.sqlite3'
|
||||
|
||||
# Filesystem notifier -- password reset / new device emails get written to
|
||||
# a file you can `tail -f`. Swap to `smtp:` when you wire up a real
|
||||
# transactional sender.
|
||||
notifier:
|
||||
disable_startup_check: false
|
||||
filesystem:
|
||||
filename: '/config/notifications/notification.txt'
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
###############################################################################
|
||||
# Authelia users database
|
||||
#
|
||||
# Copy this to users_database.yml (gitignored) and edit. Generate the
|
||||
# password hash with:
|
||||
#
|
||||
# docker compose run --rm authelia \
|
||||
# authelia crypto hash generate argon2 --password 'your-plaintext-pass'
|
||||
#
|
||||
# Paste the resulting `$argon2id$v=19$m=...` string as the `password:` value.
|
||||
# Restart Authelia for changes to take effect (or wait refresh_interval).
|
||||
###############################################################################
|
||||
|
||||
users:
|
||||
|
||||
yourname:
|
||||
disabled: false
|
||||
displayname: 'Your Name'
|
||||
password: '$argon2id$v=19$m=65536,t=3,p=4$REPLACE_WITH_GENERATED_HASH'
|
||||
email: 'you@example.com'
|
||||
groups:
|
||||
- 'admins'
|
||||
|
||||
# Add more users here. `groups` are referenced from access_control rules
|
||||
# via `subject: 'group:admins'`.
|
||||
#
|
||||
# guest:
|
||||
# disabled: false
|
||||
# displayname: 'Guest'
|
||||
# password: '$argon2id$v=19$m=65536,t=3,p=4$...'
|
||||
# email: 'guest@example.com'
|
||||
# groups:
|
||||
# - 'guests'
|
||||
Reference in New Issue
Block a user