Add podman and authentik roles

main
kalle 2025-02-07 19:32:06 +01:00
parent a3d887ef8d
commit a929b42096
9 changed files with 227 additions and 23 deletions

View File

@ -37,6 +37,8 @@ HTTP reverse proxy.
## TODO:
- Docker/podman images are currently not persisted, maybe they should be.
### Services
**For sure**:
- Authentik: Authentication

13
example_secrets.yaml Normal file
View File

@ -0,0 +1,13 @@
traefik:
acmeEmail: email@example.com
CLOUDFLARE_EMAIL: email@example.com
CLOUDFLARE_DNS_API_TOKEN: AVeryLongAPIKeyHere
authentik:
db_pass: AVeryLongSecurePassword
secret_key: AVeryLongSecretKey
# Some of these are not really secret, but having it in one place is easier
email_host: mail.example.com
email_port: "587"
email_from: mail@example.com
email_username: mail@example.com
email_password: ADifferentVeryLongSecurePassword

View File

@ -10,9 +10,12 @@
roles = with roles; [
traefik
sonarr
podman
authentik
];
config = {
sonarr.domain = "service1.${hlConfig.domain}";
authentik.domain = "service2.${hlConfig.domain}";
traefik.wildcardDomains = [
hlConfig.domain
"pds.${hlConfig.domain}"

View File

@ -7,13 +7,15 @@ rec {
managed = false;
ip = "192.168.10.174";
traefikRoutes = [
{
name = "${hostname}";
rule = "Host(`${hlConfig.domain}`) || HostRegexp(`.+${
builtins.replaceStrings [ "." ] [ "\\." ] hlConfig.domain
}`)";
target = "http://${ip}:3000";
}
];
traefikRoutes =
let
domain = "pds.${hlConfig.domain}";
in
[
{
name = "${hostname}";
rule = "Host(`${domain}`) || HostRegexp(`.+${builtins.replaceStrings [ "." ] [ "\\." ] domain}`)";
target = "http://${ip}:3000";
}
];
}

View File

@ -17,13 +17,25 @@
{
name = "${hostname}-authentik";
rule = "Host(`${config.domain}`)";
# TODO: Change port
target = "http://${host.ip}:PORTHERE";
target = "http://${host.ip}:9000";
}
];
nixosModule =
{ lib, ... }:
{
lib,
config,
pkgs,
...
}:
let
AUTHENTIK_VERSION = "2024.12.3";
publicEnv = pkgs.writeText "authentik-public.env" ''
AUTHENTIK_EMAIL__USE_TLS=false
AUTHENTIK_EMAIL__USE_SSL=true
AUTHENTIK_EMAIL__TIMEOUT=10
'';
in
{
options.authentik = {
domain = lib.mkOption {
@ -32,15 +44,140 @@
};
config = {
# Enable the sonarr service
services.sonarr = {
enable = true;
openFirewall = true;
group = "media";
# Set up user to run authentik
users.users."authentik" = {
isSystemUser = true;
group = "authentik";
};
users.groups."authentik" = { };
# TODO: Persist some/all of this into ceph cluster
environment.persistence."/persistent" = {
directories = [
{
directory = "/appdata/authentik/postgres";
mode = "0700";
}
{
directory = "/appdata/authentik/redis";
mode = "0700";
}
{
directory = "/appdata/authentik/media";
mode = "0700";
}
{
directory = "/appdata/authentik/certs";
mode = "0700";
}
];
};
# Ensure that the media group exists
users.groups.media = { };
sops.secrets = {
"authentik/db_pass" = {
owner = "authentik";
};
"authentik/secret_key" = {
owner = "authentik";
};
"authentik/email_host" = {
owner = "authentik";
};
"authentik/email_port" = {
owner = "authentik";
};
"authentik/email_from" = {
owner = "authentik";
};
"authentik/email_username" = {
owner = "authentik";
};
"authentik/email_password" = {
owner = "authentik";
};
};
sops.templates."authentik-secret.env" = {
owner = "authentik";
content = ''
AUTHENTIK_POSTGRESQL__PASSWORD=${config.sops.placeholder."authentik/db_pass"}
POSTGRES_PASSWORD=${config.sops.placeholder."authentik/db_pass"}
AUTHENTIK_SECRET_KEY="${config.sops.placeholder."authentik/secret_key"}"
AUTHENTIK_EMAIL__HOST="${config.sops.placeholder."authentik/email_host"}"
AUTHENTIK_EMAIL__PORT="${config.sops.placeholder."authentik/email_port"}"
AUTHENTIK_EMAIL__FROM="${config.sops.placeholder."authentik/email_from"}"
AUTHENTIK_EMAIL__USERNAME="${config.sops.placeholder."authentik/email_username"}"
AUTHENTIK_EMAIL__PASSWORD="${config.sops.placeholder."authentik/email_password"}"
'';
};
podman.containers = {
# TODO: Use system postgres here instead of a separate container
"authentik-postgres" = {
image = "docker.io/library/postgres:16-alpine";
autoStart = true;
volumes = [
"/appdata/authentik/postgres:/var/lib/postgresql/data"
];
environment = {
POSTGRES_USER = "authentik";
POSTGRES_DB = "authentik";
};
environmentFiles = [
config.sops.templates."authentik-secret.env".path
publicEnv
];
};
"authentik-redis" = {
image = "docker.io/library/redis:7.4.2-alpine";
autoStart = true;
volumes = [
"/appdata/authentik/redis:/data"
];
};
"authentik-server" = {
image = "ghcr.io/goauthentik/server:${AUTHENTIK_VERSION}";
user = "authentik";
autoStart = true;
cmd = [ "server" ];
environment = {
AUTHENTIK_REDIS__HOST = "authentik-redis";
AUTHENTIK_POSTGRESQL__HOST = "authentik-postgres";
AUTHENTIK_POSTGRESQL__USER = "authentik";
AUTHENTIK_POSTGRESQL__NAME = "authentik";
};
environmentFiles = [
config.sops.templates."authentik-secret.env".path
publicEnv
];
volumes = [
"/appdata/authentik/media:/media"
];
ports = [
"9000:9000"
];
};
"authentik-worker" = {
image = "ghcr.io/goauthentik/server:${AUTHENTIK_VERSION}";
user = "authentik";
autoStart = true;
cmd = [ "worker" ];
environment = {
AUTHENTIK_REDIS__HOST = "authentik-redis";
AUTHENTIK_POSTGRESQL__HOST = "authentik-postgres";
AUTHENTIK_POSTGRESQL__USER = "authentik";
AUTHENTIK_POSTGRESQL__NAME = "authentik";
};
environmentFiles = [
config.sops.templates."authentik-secret.env".path
publicEnv
];
volumes = [
"/appdata/authentik/media:/media"
"/appdata/authentik/certs:/certs"
];
};
};
};
};
}

View File

@ -5,5 +5,6 @@
{
sonarr = utils.mkRole (import ./sonarr.nix);
traefik = utils.mkRole (import ./traefik.nix);
podman = utils.mkRole (import ./podman.nix);
authentik = utils.mkRole (import ./authentik.nix);
}

29
roles/podman.nix Normal file
View File

@ -0,0 +1,29 @@
{
name = "Podman";
description = ''
Provide support for running docker containers on the system
'';
nixosModule =
{ lib, config, ... }:
{
options.podman = {
containers = lib.mkOption {
type = lib.types.attrs;
};
};
config =
let
cfg = config.podman;
in
{
virtualisation.containers.enable = true;
virtualisation.podman.enable = true;
virtualisation.podman.defaultNetwork.settings.dns_enabled = true;
virtualisation.oci-containers.backend = "podman";
virtualisation.oci-containers.containers = cfg.containers;
};
};
}

View File

@ -7,7 +7,6 @@
nixosModule =
{
lib,
pkgs,
config,
hosts,
...
@ -43,6 +42,16 @@
443
];
environment.persistence."/persistent" = {
directories = [
{
directory = "/appdata/traefik/acme";
user = "traefik";
mode = "0700";
}
];
};
sops.secrets = {
"traefik/acmeEmail" = {
owner = "traefik";
@ -107,7 +116,7 @@
letsencrypt = {
acme = {
email = "$acmeEmail";
storage = "/run/traefik/acme.json";
storage = "/appdata/traefik/acme/acme.json";
dnsChallenge = {
provider = "cloudflare";
};

View File

@ -2,6 +2,14 @@ traefik:
acmeEmail: ENC[AES256_GCM,data:aM2AQADo5s0c1b//UWPXNPlKMXNRRnPFDbM=,iv:RP7Tn8s1nYKJf0B0KO0BQkI4tnz/zUK8KqzQqeNiyZk=,tag:g4+lwK4miUdxOwLHQcUZhg==,type:str]
CLOUDFLARE_EMAIL: ENC[AES256_GCM,data:YHQ00Qh0t7owvFE/PXu8o4a8ry1P92/CVA==,iv:z982jUAm8W4Du/5dLopQZE0p5eWi4Ls7TYsiiwUlqvg=,tag:bek2eQ4duYBH8F2LG+Tr+g==,type:str]
CLOUDFLARE_DNS_API_TOKEN: ENC[AES256_GCM,data:zyTpv1AGA9GzfGfFyxqO40NKZt8LlHU1YT9kvXPZYAGUc5wE3GVxzg==,iv:W7u5gEeYNkCGO3D0Y+XBZ4PCI081QsNK10ThHKbV68M=,tag:7onKfU+mVz3euCbFrX1mdg==,type:str]
authentik:
db_pass: ENC[AES256_GCM,data:Jkz/wWf+yOm3d+hb+c56XXSGYjYRJbMwJqpcr4HMmu+WVflZCh/ILw==,iv:42uswgv+lIRnonX6kT0MFhs5EYaTgdakrBe9DmFUY2k=,tag:hUxlquZT4RBHlcLKVtHVlg==,type:str]
secret_key: ENC[AES256_GCM,data:JdSbOxLGa0Bqac/YV4HgpN2lD+UEgvWa4YqQ4nQJka8MTRmuFYNDN3eQ5d1bI7JCijy4y7QqyhtKfdpK/puVsNkoSb4Cmh3m7nlqHx/2b9M=,iv:2c5Zk+TLvvlW/JTq2pvdyqT0PNe4qJ9OXEGA20feh1g=,tag:7y2yYlUXrq7gH6qAHaypqA==,type:str]
email_host: ENC[AES256_GCM,data:T5UErdKKbyfYkbd+1V6JEz6yp7h+ww==,iv:o/wvYwDgx+z8v8l9A7OudP0GFGK6ngMrj/X3cLTDN6U=,tag:sR9PZkQc+28rs+rpPV142Q==,type:str]
email_port: ENC[AES256_GCM,data:bPPI,iv:3174C+o4058QF5c46qDWbUMRt+SpDEHtV+vbvQxfTn4=,tag:1oR0WLLzYru5BGdWluKJZg==,type:str]
email_from: ENC[AES256_GCM,data:X6NP2i3uAZQFK7JdeviIMFhNPw==,iv:dwZFyzzzzFNTVfe1nhWebXrTolCa991p+vJUAOxFJf8=,tag:gClo9mZfaVFP35yZath0Nw==,type:str]
email_username: ENC[AES256_GCM,data:c1lu5Tw6N6w96uUujSj1wHh7fQ==,iv:XX2iYXOzz8EhcZ75NlmLsasnZnCrihE9K17qS2nhAyI=,tag:qfhh3bB530IIsJwmjG20Lw==,type:str]
email_password: ENC[AES256_GCM,data:2f/LN5q/5RRIzAc8ol9RByf+RrQ=,iv:gy/UvcKzpvC0r4nQFbTYta8alzTjPWhFWCjGIw/PnuU=,tag:LLOk7NMuQ3VZ2zA779A5dw==,type:str]
sops:
kms: []
gcp_kms: []
@ -35,8 +43,8 @@ sops:
OHkvUTViMVZSUGFSeDN1ZDcxN3NtNzQK48qiEMcKbsrh8ZhnMD7lkhsy0JRMYiOU
EtXwHxEzIXukStQ9kXazfHJJouuqv7mhx12tgv+QKvrfWxCJ5WvE2A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-12-26T18:39:38Z"
mac: ENC[AES256_GCM,data:2dr8o3njYlYVHiFItM4MrlHfpiw7AurdedXm614MbMiX6b5bkAoIuSJHWjjwmBsQY52yTUwl5GS0oLztRGOZ9OsxiwvGRoxNG5lAPK83t4pralaWvLKVn7CCClU6fyYnUwqPEfw/YFSxlm00iBPz54zRQNvIigrZhhAM3lHswaM=,iv:sgvpiOwz183/GewbTFsW3EV8bHX7p/13b32sDPxRcMw=,tag:ZHHv4fAOT/lPZg/n9rnMvA==,type:str]
lastmodified: "2025-02-10T22:59:35Z"
mac: ENC[AES256_GCM,data:uTzFEW5na0YCBLGb9k/yICjNGKWCefGgiSH8M0QZgrvRf3ioXz1W/rGUJqTmIh3QdQ45evHoj6cKSIys2gU28dR98qGX2sCBmnWYMB2oT57YLXeACsaqXKtXFsOx/YnOy8baQpckUYOwHJpM+dhKf/s348X1jfx1k8TOoNE3aj0=,iv:Jr1HvXKsxKfMBUu2r6ezodySMWduVdlPw+EIckpi5i0=,tag:fDjBfC7nKwkO3mm91iB/HQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.2