Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ This repository contains Docker Compose setups for a variety of applications, en
- Traefik (`networking/proxies/traefik`)
- **Security**
- HashiCorp Vault (`security/vaults/hashicorp`)
- Authelia (`security/access/authelia`)
- **Operating Systems**
- Windows (`oses/windows`)

Expand Down
68 changes: 68 additions & 0 deletions security/access/authelia/configuration/configuration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
# Authelia configuration.
# This file is mounted read-only; on every container start (see
# `docker-compose.yml`) it's rendered into a container-local copy with the
# domain placeholders below substituted from DOMAIN in `.env`, so this
# tracked copy is never modified. Edit the rest of this file directly for
# anything else, the same way Traefik's `configuration/*.yml` files are
# hand-edited.
#
# Secrets, hosts, and ports for the shared `postgresql`/`redis` containers are
# supplied via the `AUTHELIA_*` environment variables in `docker-compose.yml`
# (Authelia lets any config key be overridden this way), so they are left as
# empty stubs below rather than duplicated here.

server:
address: 'tcp://:9091'

log:
level: 'info'

totp:
issuer: 'authelia.${DOMAIN}'

identity_validation:
reset_password:
jwt_secret: ''

authentication_backend:
file:
path: '/tmp/users_database.yml'

access_control:
default_policy: 'deny'
rules:
# TODO: Add more rules as needed, for example a `bypass` policy for
# publicly-reachable apps under this domain.
- domain: '*.${DOMAIN}'
policy: 'two_factor'

session:
secret: ''
cookies:
- name: 'authelia_session'
domain: '${DOMAIN}'
authelia_url: 'https://authelia.${DOMAIN}'
expiration: '1 hour'
inactivity: '5 minutes'
redis:
host: ''
port: 0

regulation:
max_retries: 3
find_time: '2 minutes'
ban_time: '5 minutes'

storage:
encryption_key: ''
postgres:
address: ''
database: ''
username: ''
password: ''

notifier:
filesystem:
filename: '/tmp/notification.txt'
...
79 changes: 79 additions & 0 deletions security/access/authelia/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# TODO: Use Secrets to store the passwords to all containers.
# `postgresql` and `redis` live in separate compose projects (`databases/postgresql`,
# `databases/redis`), so `depends_on` cannot reference them. Authelia's image is
# a minimal static binary without a confirmed shell/`nc`, so rather than risk
# breaking its entrypoint with a wait script, rely on `restart: unless-stopped`
# to retry until they're reachable.
#
# After starting Postgres, add `authelia` to `POSTGRESQL_ADDITIONAL_DATABASES`
# in `databases/postgresql`'s `.env` and create a matching role/password.
networks:
internal:
name: "internal"
# External means the container will be accessible from other containers in the same network.
# If you want to isolate the container create a new network, with different name for each container and without being external.
external: true

services:
authelia:
image: "authelia/authelia:4.39.20"
container_name: "authelia"
restart: "unless-stopped"
healthcheck:
test: ["CMD", "/app/healthcheck.sh"]
interval: "10s"
timeout: "5s"
retries: 5
networks:
- "internal"
ports:
- "${AUTHELIA_PORT?Variable not set}:9091"
volumes:
- "./configuration/configuration.yml:/config/configuration.yml:ro"
environment:
- "TZ=${TIMEZONE?Variable not set}"
- "DOMAIN=${DOMAIN?Variable not set}"
- "ADMIN_USERNAME=${ADMIN_USERNAME?Variable not set}"
- "ADMIN_PASSWORD=${ADMIN_PASSWORD?Variable not set}"
- "ADMIN_EMAIL=${ADMIN_EMAIL?Variable not set}"
- "AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET=${AUTHELIA_JWT_SECRET?Variable not set}"
- "AUTHELIA_SESSION_SECRET=${AUTHELIA_SESSION_SECRET?Variable not set}"
- "AUTHELIA_SESSION_REDIS_HOST=redis"
- "AUTHELIA_SESSION_REDIS_PORT=${REDIS_PORT?Variable not set}"
- "AUTHELIA_SESSION_REDIS_PASSWORD=${REDIS_PASSWORD?Variable not set}"
- "AUTHELIA_STORAGE_ENCRYPTION_KEY=${AUTHELIA_STORAGE_ENCRYPTION_KEY?Variable not set}"
- "AUTHELIA_STORAGE_POSTGRES_ADDRESS=tcp://postgresql:${POSTGRESQL_PORT?Variable not set}"
- "AUTHELIA_STORAGE_POSTGRES_DATABASE=authelia"
- "AUTHELIA_STORAGE_POSTGRES_USERNAME=${POSTGRESQL_USER?Variable not set}"
- "AUTHELIA_STORAGE_POSTGRES_PASSWORD=${POSTGRESQL_PASSWORD?Variable not set}"
# Renders a container-local `/tmp/configuration.yml` from the read-only
# mounted `configuration.yml` (so the tracked copy is never modified) and
# generates `/tmp/users_database.yml`, both from plain env vars, on every
# start (`ADMIN_*`/`DOMAIN` are kept outside the `AUTHELIA_` prefix so
# Authelia doesn't warn about an unrecognized config override), hashing
# the password with Authelia's own bundled `crypto` subcommand. Passes
# `--config` to the original entrypoint (rather than args directly),
# which still handles the `/config` chown and privilege drop to
# PUID/PGID afterwards, using our custom config path.
entrypoint: ["sh", "-c"]
command:
# All `$` below are escaped as `$$` so Compose leaves them for the
# container's shell to evaluate at runtime, instead of interpolating
# them from `.env` while parsing this file.
- |
sed "s|\$${DOMAIN}|$$DOMAIN|g" /config/configuration.yml > /tmp/configuration.yml
HASH=$$(authelia crypto hash generate bcrypt --password "$$ADMIN_PASSWORD" | awk '{print $$2}')
cat > /tmp/users_database.yml <<-CONFIG
---
users:
$${ADMIN_USERNAME}:
disabled: false
displayname: 'Admin'
password: '$${HASH}'
email: '$${ADMIN_EMAIL}'
groups:
- 'admins'
CONFIG
exec /app/entrypoint.sh --config /tmp/configuration.yml
labels:
- "traefik.enable=false"
29 changes: 29 additions & 0 deletions security/access/authelia/template.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# For all strings containing special characters, use single quotes.
# In case of older docker compose versions (<3.9), do not use single or double quotes at all.

# Container's docker environment configuration.
COMPOSE_PROJECT_NAME='lowercase_string_without_special_characters'
TIMEZONE="Region/Country"

# Shared PostgreSQL and Redis connection details (must match the values in
# `databases/postgresql`'s and `databases/redis`'s `.env` files).
POSTGRESQL_PORT=1234
POSTGRESQL_USER='string_with_special_characters'
POSTGRESQL_PASSWORD='string_with_special_characters'
REDIS_PORT=1234
REDIS_PASSWORD="string_without_special_characters"

# Authelia's docker environment configuration.
AUTHELIA_PORT=5678
# Generate each of the 3 secrets below with: openssl rand -hex 32
AUTHELIA_JWT_SECRET='string_without_special_characters'
AUTHELIA_SESSION_SECRET='string_without_special_characters'
AUTHELIA_STORAGE_ENCRYPTION_KEY='string_without_special_characters_more_than_twenty_chars_long'
# Root domain this instance protects, rendered into `configuration.yml` (from
# `configuration.yml.template`) on every container start, see that file's
# comment. Authelia's own portal is served at `authelia.<DOMAIN>`.
DOMAIN='string_with_special_characters'
# Admin user, hashed into `users_database.yml` on every container start.
ADMIN_USERNAME='admin'
ADMIN_PASSWORD='string_without_special_characters'
ADMIN_EMAIL='string_with_special_characters'