Add authelia base

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2025-03-08 00:35:15 +00:00
parent 881b18065a
commit e9ffd4d839
8 changed files with 250 additions and 0 deletions

View File

@@ -0,0 +1,215 @@
{
user ? throw "user argument is required",
home ? throw "home argument is required",
}:
{
config,
inputs,
pkgs,
system,
lib,
...
}:
let
selfLib = inputs.self.lib.${system};
hmConfig = config.home-manager.users.${user};
inherit (hmConfig.virtualisation.quadlet) volumes containers networks;
in
{
environment.persistence."/persist"."${home}/.local/share/authelia" = { };
home-manager.users.${user} = {
sops = {
secrets = {
"authelia/jwt".sopsFile = ../../../../../../secrets/secrets.yaml;
"authelia/session".sopsFile = ../../../../../../secrets/secrets.yaml;
"authelia/storage".sopsFile = ../../../../../../secrets/secrets.yaml;
"authelia/postgresql".sopsFile = ../../../../../../secrets/secrets.yaml;
"authelia/smtp".sopsFile = ../../../../../../secrets/secrets.yaml;
"authelia/users/karaolidis".sopsFile = ../../../../../../secrets/secrets.yaml;
};
templates = {
"authelia-postgresql.env".content = ''
POSTGRES_PASSWORD=${hmConfig.sops.placeholder."authelia/postgresql"}
'';
"authelia-users.yaml".content = builtins.readFile (
(pkgs.formats.yaml { }).generate "users.yaml" {
users.karaolidis = {
displayname = "Nick Karaolidis";
password = hmConfig.sops.placeholder."authelia/users/karaolidis";
email = "nick@karaolidis.com";
groups = [ "admins" ];
};
}
);
};
};
virtualisation.quadlet = {
networks.authelia = { };
volumes."authelia-redis" = { };
containers = {
"authelia-init" = {
containerConfig = {
autoUpdate = "registry";
image = "docker.io/mikefarah/yq:latest";
networks = [ networks.authelia.ref ];
volumes = [
"${home}/.local/share/authelia/config:/workdir/config"
"${hmConfig.sops.templates."authelia-users.yaml".path}:/workdir/users.yaml:ro"
];
exec = [
"eval-all"
". as $item ireduce ({}; . * $item)"
"/workdir/config/users.yaml"
"/workdir/users.yaml"
"-i"
];
userns = "keep-id:uid=1000,gid=1000";
};
serviceConfig = {
Type = "oneshot";
Restart = "on-failure";
};
unitConfig.After = [ "sops-nix.service" ];
};
authelia = {
containerConfig =
let
config = (pkgs.formats.yaml { }).generate "configuration.yaml" {
theme = "auto";
telemetry.metrics.enabled = true;
authentication_backend = {
refresh_interval = "always";
file = {
path = "/config/users.yaml";
watch = true;
};
};
password_policy.zxcvbn.enabled = true;
access_control.default_policy = "two_factor";
session = {
cookies = [
{
domain = "karaolidis.com";
authelia_url = "https://id.karaolidis.com";
}
];
redis = {
host = "authelia-redis";
port = 6379;
};
};
storage.postgres = {
address = "tcp://authelia-postgresql:5432";
database = "authelia";
username = "authelia";
};
notifier.smtp = {
address = "smtp://smtp.protonmail.ch:587";
username = "jupiter@karaolidis.com";
sender = "jupiter@karaolidis.com";
};
};
in
{
autoUpdate = "registry";
image = "ghcr.io/authelia/authelia";
environments = {
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE = "/secrets/JWT_SECRET";
AUTHELIA_SESSION_SECRET_FILE = "/secrets/SESSION_SECRET";
AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE = "/secrets/STORAGE_ENCRYPTION_KEY";
AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE = "/secrets/STORAGE_PASSWORD";
AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = "/secrets/SMTP_PASSWORD";
};
volumes = [
"${home}/.local/share/authelia/config:/config"
"${config}:/config/conf.d/configuration.yaml:ro"
"${hmConfig.sops.secrets."authelia/jwt".path}:/secrets/JWT_SECRET:ro"
"${hmConfig.sops.secrets."authelia/session".path}:/secrets/SESSION_SECRET:ro"
"${hmConfig.sops.secrets."authelia/storage".path}:/secrets/STORAGE_ENCRYPTION_KEY:ro"
"${hmConfig.sops.secrets."authelia/postgresql".path}:/secrets/STORAGE_PASSWORD:ro"
"${hmConfig.sops.secrets."authelia/smtp".path}:/secrets/SMTP_PASSWORD:ro"
];
networks = [
networks.authelia.ref
networks.traefik.ref
];
exec = [ "--config /config/conf.d/" ];
labels = [
"traefik.enable=true"
"traefik.http.routers.authelia.rule=Host(`id.karaolidis.com`)"
"traefik.http.routers.authelia.entryPoints=https"
"traefik.http.routers.traefik.tls.certresolver=letsencrypt"
"traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true"
"traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth"
"traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Email,Remote-Name"
];
};
unitConfig.After = [
"${containers."authelia-init"._serviceName}.service"
"${containers."authelia-postgresql"._serviceName}.service"
"${containers."authelia-redis"._serviceName}.service"
"sops-nix.service"
];
};
"authelia-postgresql" = {
containerConfig = {
autoUpdate = "registry";
image = "docker.io/library/postgres:latest";
networks = [ networks.authelia.ref ];
volumes = [
"${selfLib.runtime.log.docker.postgres}:/entrypoint.sh:ro"
"${home}/.local/share/authelia/postgresql:/var/lib/postgresql/data"
];
environments = {
POSTGRES_DB = "authelia";
POSTGRES_USER = "authelia";
};
environmentFiles = [ hmConfig.sops.templates."authelia-postgresql.env".path ];
entrypoint = "/entrypoint.sh";
exec = [ "postgres" ];
user = "999";
group = "999";
userns = "keep-id:uid=999,gid=999";
};
unitConfig.After = [ "sops-nix.service" ];
};
"authelia-redis".containerConfig = {
autoUpdate = "registry";
image = "docker.io/library/redis:latest";
networks = [ networks.authelia.ref ];
volumes = [ "${volumes."authelia-redis".ref}:/data" ];
exec = [ "--save 60 1" ];
user = "999";
group = "999";
userns = "keep-id:uid=999,gid=999";
};
};
};
systemd.user.tmpfiles.rules = [
"d ${home}/.local/share/authelia/config 0755 ${user} ${user}"
"f ${home}/.local/share/authelia/config/users.yaml 644 ${user} ${user}"
"d ${home}/.local/share/authelia/postgresql 0700 ${user} ${user}"
];
};
}

View File

@@ -8,6 +8,7 @@ let
in
{
imports = [
(import ./authelia { inherit user home; })
(import ./ntfy { inherit user home; })
(import ./traefik { inherit user home; })
(import ./whoami { inherit user home; })

View File

@@ -29,6 +29,8 @@ in
in
builtins.readFile (
(pkgs.formats.yaml { }).generate "server.yml" {
log-level = "warn";
base-url = "https://ntfy.karaolidis.com";
cache-file = "/var/lib/ntfy/cache.db";

View File

@@ -1,4 +1,5 @@
{ pkgs, ... }:
{
log = import ./log { inherit pkgs; };
merge = import ./merge { inherit pkgs; };
}

View File

@@ -0,0 +1,4 @@
{ pkgs, ... }:
{
docker = import ./docker { inherit pkgs; };
}

View File

@@ -0,0 +1,4 @@
{ pkgs, ... }:
{
postgres = import ./postgres { inherit pkgs; };
}

View File

@@ -0,0 +1,6 @@
{ pkgs, ... }:
pkgs.writeTextFile {
name = "log-wrapper-docker-postgres";
text = builtins.readFile ./wrapper.sh;
executable = true;
}

View File

@@ -0,0 +1,17 @@
#!/bin/sh
set -o errexit
set -o nounset
LOG_PIPE="$(mktemp -u)"
mkfifo "$LOG_PIPE"
while IFS= read -r line; do
if echo "$line" | grep -qE "ERROR|FATAL|PANIC"; then
echo "$line" >&2
else
echo "$line" >&1
fi
done < "$LOG_PIPE" &
exec /usr/local/bin/docker-entrypoint.sh "$@" >"$LOG_PIPE" 2>&1