321 lines
9.8 KiB
Nix
321 lines
9.8 KiB
Nix
|
# Thanks for original module, anpin! https://gist.github.com/anpin/ecbdb6625400908856ef9482eca3380c
|
||
|
{ config, pkgs, lib, ... }:
|
||
|
let
|
||
|
cfg = config.services.authentik;
|
||
|
databaseActuallyCreateLocally = cfg.database.createLocally
|
||
|
&& cfg.database.host == "/run/postgresql";
|
||
|
|
||
|
inherit (lib)
|
||
|
mkIf mkEnableOption mkOption types mdDoc literalExpression optional attrsets;
|
||
|
inherit (attrsets) optionalAttrs;
|
||
|
inherit (types) str bool port submodule package nullOr path enum;
|
||
|
|
||
|
hostWithPort = h: p: "${h}:${toString p}";
|
||
|
|
||
|
authentikBaseService = {
|
||
|
after = [ "network.target" ]
|
||
|
++ optional databaseActuallyCreateLocally "postgresql.service";
|
||
|
wantedBy = [ "multi-user.target" ];
|
||
|
path = [ cfg.package ];
|
||
|
environment = let
|
||
|
listenAddress = hostWithPort cfg.listen.address;
|
||
|
in {
|
||
|
AUTHENTIK_REDIS__HOST = cfg.redis.host;
|
||
|
AUTHENTIK_REDIS__PORT = toString cfg.redis.port;
|
||
|
|
||
|
AUTHENTIK_POSTGRESQL__HOST = cfg.database.host;
|
||
|
AUTHENTIK_POSTGRESQL__PORT = toString cfg.database.port;
|
||
|
AUTHENTIK_POSTGRESQL__USER = cfg.database.user;
|
||
|
AUTHENTIK_POSTGRESQL__NAME = cfg.database.name;
|
||
|
|
||
|
AUTHENTIK_LISTEN__HTTP = listenAddress cfg.listen.http;
|
||
|
AUTHENTIK_LISTEN__HTTPS = listenAddress cfg.listen.https;
|
||
|
|
||
|
# initial password for admin user
|
||
|
AUTHENTIK_BOOTSTRAP_PASSWORD = cfg.defaultPassword;
|
||
|
|
||
|
# disable outbound connections
|
||
|
AUTHENTIK_DISABLE_UPDATE_CHECK = "true";
|
||
|
AUTHENTIK_ERROR_REPORTING__ENABLED = "false";
|
||
|
AUTHENTIK_DISABLE_STARTUP_ANALYTICS = "true";
|
||
|
AUTHENTIK_AVATARS = "initials";
|
||
|
|
||
|
AUTHENTIK_LOG_LEVEL = cfg.logLevel;
|
||
|
};
|
||
|
serviceConfig = {
|
||
|
User = "authentik";
|
||
|
Group = "authentik";
|
||
|
EnvironmentFile = cfg.environmentFile;
|
||
|
WorkingDirectory = cfg.package;
|
||
|
DynamicUser = true;
|
||
|
RuntimeDirectory = "authentik";
|
||
|
NoNewPrivileges = true;
|
||
|
PrivateTmp = true;
|
||
|
ProtectHome = true;
|
||
|
ProtectSystem = "strict";
|
||
|
ProtectKernelTunables = true;
|
||
|
ProtectKernelModules = true;
|
||
|
ProtectControlGroups = true;
|
||
|
SystemCallFilter= "~@cpu-emulation @keyring @module @obsolete @raw-io @reboot @swap @sync";
|
||
|
ConfigurationDirectory = "authentik";
|
||
|
StateDirectoryMode = "0750";
|
||
|
};
|
||
|
};
|
||
|
in {
|
||
|
options.services.authentik = {
|
||
|
enable = mkEnableOption "Enables Authentik service";
|
||
|
|
||
|
package = mkOption {
|
||
|
type = package;
|
||
|
default = pkgs.authentik;
|
||
|
defaultText = literalExpression "pkgs.authentik";
|
||
|
description = mdDoc "Authentik package to use.";
|
||
|
};
|
||
|
|
||
|
defaultPassword = mkOption {
|
||
|
description = mdDoc "Default admin password. Only read on first startup.";
|
||
|
type = str;
|
||
|
default = "change-me";
|
||
|
};
|
||
|
|
||
|
logLevel = mkOption {
|
||
|
description = mdDoc
|
||
|
"Log level for the server and worker containers. Setting the log level to trace will include sensitive details in logs, so it shouldn't be used in most cases.";
|
||
|
type = enum [ "trace" "debug" "info" "warning" "error" ];
|
||
|
default = "info";
|
||
|
};
|
||
|
|
||
|
listen = mkOption {
|
||
|
description = mdDoc "Listen ports";
|
||
|
default = { };
|
||
|
type = submodule {
|
||
|
options = {
|
||
|
http = mkOption {
|
||
|
description = mdDoc "HTTP port.";
|
||
|
type = port;
|
||
|
default = 9000;
|
||
|
};
|
||
|
https = mkOption {
|
||
|
description = mdDoc "HTTPS port.";
|
||
|
type = port;
|
||
|
default = 9443;
|
||
|
};
|
||
|
address = mkOption {
|
||
|
description = mdDoc "Address to listen on.";
|
||
|
type = str;
|
||
|
default = "0.0.0.0";
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
redis = {
|
||
|
createLocally = mkOption {
|
||
|
description = mdDoc "Configure local Redis server for Authentik.";
|
||
|
type = bool;
|
||
|
default = true;
|
||
|
};
|
||
|
|
||
|
host = mkOption {
|
||
|
description = mdDoc "Redis host.";
|
||
|
type = str;
|
||
|
default = "127.0.0.1";
|
||
|
};
|
||
|
|
||
|
port = mkOption {
|
||
|
description = mdDoc "Redis port.";
|
||
|
type = port;
|
||
|
default = 31637;
|
||
|
};
|
||
|
};
|
||
|
ssl = {
|
||
|
cert = mkOption {
|
||
|
type = nullOr path;
|
||
|
default = null;
|
||
|
};
|
||
|
|
||
|
key = mkOption {
|
||
|
type = nullOr path;
|
||
|
default = null;
|
||
|
};
|
||
|
|
||
|
name = mkOption {
|
||
|
type = str;
|
||
|
default = "SSL from NIXOS";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
environmentFile = mkOption {
|
||
|
type = nullOr path;
|
||
|
default = null;
|
||
|
example = "/var/lib/authentik/secrets/db-password";
|
||
|
description = mdDoc ''
|
||
|
Environment variables including :
|
||
|
- Secret key used for cookie signing and unique user IDs, don't change this after the first install.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
database = {
|
||
|
createLocally = mkOption {
|
||
|
description =
|
||
|
mdDoc "Configure local PostgreSQL database server for authentik.";
|
||
|
type = bool;
|
||
|
default = true;
|
||
|
};
|
||
|
|
||
|
host = mkOption {
|
||
|
type = str;
|
||
|
default = "/run/postgresql";
|
||
|
example = "192.168.23.42";
|
||
|
description = mdDoc "Database host address or unix socket.";
|
||
|
};
|
||
|
|
||
|
port = mkOption {
|
||
|
type = nullOr port;
|
||
|
default = if cfg.database.createLocally then null else 5432;
|
||
|
defaultText = literalExpression ''
|
||
|
if config.database.createLocally then null else 5432
|
||
|
'';
|
||
|
description = mdDoc "Database host port.";
|
||
|
};
|
||
|
|
||
|
name = mkOption {
|
||
|
type = str;
|
||
|
default = "authentik";
|
||
|
description = mdDoc "Database name.";
|
||
|
};
|
||
|
|
||
|
user = mkOption {
|
||
|
type = str;
|
||
|
default = "authentik";
|
||
|
description = mdDoc "Database user.";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
outposts = mkOption {
|
||
|
type = submodule {
|
||
|
options = {
|
||
|
ldap = mkOption {
|
||
|
type = submodule {
|
||
|
options = {
|
||
|
enable =
|
||
|
mkEnableOption (lib.mdDoc "the authentik ldap outpost");
|
||
|
package = mkOption {
|
||
|
type = path;
|
||
|
default = pkgs.authentik-outposts.ldap;
|
||
|
};
|
||
|
host = mkOption {
|
||
|
type = str;
|
||
|
default = if cfg.outposts.ldap.insecure then
|
||
|
"http://127.0.0.1:${toString cfg.listen.http}"
|
||
|
else
|
||
|
"https://127.0.0.1:${toString cfg.listen.https}";
|
||
|
};
|
||
|
insecure = mkOption {
|
||
|
type = bool;
|
||
|
default = false;
|
||
|
};
|
||
|
environmentFile = mkOption {
|
||
|
type = nullOr path;
|
||
|
default = null;
|
||
|
example = "/var/lib/authentik-ldap/secrets/env";
|
||
|
description = mdDoc ''
|
||
|
Environment variables including :
|
||
|
- API TOKEN
|
||
|
'';
|
||
|
};
|
||
|
listen = mkOption {
|
||
|
description = mdDoc "Listen ports";
|
||
|
default = { };
|
||
|
type = submodule {
|
||
|
options = {
|
||
|
ldap = mkOption {
|
||
|
description = mdDoc "LDAP port.";
|
||
|
type = port;
|
||
|
default = 3389;
|
||
|
};
|
||
|
ldaps = mkOption {
|
||
|
description = mdDoc "LDAPS port.";
|
||
|
type = port;
|
||
|
default = 6636;
|
||
|
};
|
||
|
address = mkOption {
|
||
|
description = mdDoc "Address to listen on.";
|
||
|
type = str;
|
||
|
default = "0.0.0.0";
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
default = { ldap = { enable = false; }; };
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = mkIf cfg.enable {
|
||
|
users.users.authentik = {
|
||
|
isSystemUser = true;
|
||
|
home = cfg.package;
|
||
|
group = "authentik";
|
||
|
};
|
||
|
users.groups.authentik = { };
|
||
|
|
||
|
services.postgresql = mkIf databaseActuallyCreateLocally {
|
||
|
enable = true;
|
||
|
ensureUsers = [{
|
||
|
name = cfg.database.name;
|
||
|
ensureDBOwnership = true;
|
||
|
}];
|
||
|
ensureDatabases = [ cfg.database.name ];
|
||
|
};
|
||
|
|
||
|
services.redis.servers.authentik =
|
||
|
mkIf (cfg.redis.createLocally && cfg.redis.host == "127.0.0.1") {
|
||
|
enable = true;
|
||
|
port = cfg.redis.port;
|
||
|
bind = "127.0.0.1";
|
||
|
};
|
||
|
|
||
|
systemd.services.authentik-server = authentikBaseService // {
|
||
|
serviceConfig = authentikBaseService.serviceConfig // {
|
||
|
ExecStart = "${cfg.package}/bin/ak server";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
systemd.services.authentik-worker = authentikBaseService // {
|
||
|
serviceConfig = authentikBaseService.serviceConfig // {
|
||
|
ExecStart = "${cfg.package}/bin/ak worker";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
# systemd.services.authentik-ssl-import = authentikBaseService // {
|
||
|
# before = [ "authentik-server.service" ];
|
||
|
# serviceConfig = authentikBaseService.serviceConfig // {
|
||
|
# Type = "oneshot";
|
||
|
# RemainAfterExit = true;
|
||
|
# ExecStart = ''
|
||
|
# ${cfg.package}/bin/ak import_certificate --name "${cfg.ssl.name}" --certificate "${cfg.ssl.cert}" --private-key "${cfg.ssl.key}"'';
|
||
|
# };
|
||
|
# };
|
||
|
|
||
|
systemd.services.authentik-ldap-outpost = let
|
||
|
ldapCfg = cfg.outposts.ldap;
|
||
|
in mkIf ldapCfg.enable (authentikBaseService // {
|
||
|
description = "authentik ldap outpost";
|
||
|
environment = let listenAddress = hostWithPort ldapCfg.listen.address;
|
||
|
in {
|
||
|
AUTHENTIK_HOST = ldapCfg.host;
|
||
|
AUTHENTIK_LISTEN__LDAP = listenAddress ldapCfg.listen.ldap;
|
||
|
AUTHENTIK_LISTEN__LDAPS = listenAddress ldapCfg.listen.ldaps;
|
||
|
} // optionalAttrs ldapCfg.insecure { AUTHENTIK_INSECURE = "true"; };
|
||
|
serviceConfig = authentikBaseService.serviceConfig // {
|
||
|
ExecStart = "${cfg.outposts.ldap.package}/bin/ldap";
|
||
|
EnvironmentFile = ldapCfg.environmentFile;
|
||
|
};
|
||
|
});
|
||
|
};
|
||
|
}
|