{ config, pkgs, lib, ... }: let domain = "auth.felschr.com"; port = 9091; ldapHost = "localhost"; ldapPort = config.services.lldap.settings.ldap_port; redis = config.services.redis.servers.authelia; cfg = config.services.authelia.instances.main; mkWebfinger = config: file: pkgs.writeTextDir file (lib.generators.toJSON { } config); mkWebfingers = { subject, ... }@config: map (mkWebfinger config) [ subject (lib.escapeURL subject) ]; webfingerRoot = pkgs.symlinkJoin { name = "felschr.com-webfinger"; paths = lib.flatten (builtins.map mkWebfingers [ { subject = "acct:me@felschr.com"; links = [{ rel = "http://openid.net/specs/connect/1.0/issuer"; href = "https://auth.felschr.com"; }]; } { subject = "acct:felschr@fosstodon.org"; aliases = [ "https://fosstodon.org/@felschr" "https://fosstodon.org/users/felschr" ]; links = [ { rel = "http://webfinger.net/rel/profile-page"; type = "text/html"; href = "https://fosstodon.org/@felschr"; } { rel = "self"; type = "application/activity+json"; href = "https://fosstodon.org/users/felschr"; } { rel = "http://ostatus.org/schema/1.0/subscribe"; template = "https://fosstodon.org/authorize_interaction?uri={uri}"; } ]; } ]); }; smtpAccount = config.programs.msmtp.accounts.default; in { age.secrets.authelia-jwt = { file = ../secrets/authelia/jwt.age; owner = cfg.user; }; age.secrets.authelia-session = { file = ../secrets/authelia/session.age; owner = cfg.user; }; age.secrets.authelia-storage = { file = ../secrets/authelia/storage.age; owner = cfg.user; }; age.secrets.authelia-oidc-hmac = { file = ../secrets/authelia/oidc-hmac.age; owner = cfg.user; }; age.secrets.authelia-oidc-issuer = { file = ../secrets/authelia/oidc-issuer.age; owner = cfg.user; }; services.authelia.instances.main = { enable = true; secrets = { jwtSecretFile = config.age.secrets.authelia-jwt.path; storageEncryptionKeyFile = config.age.secrets.authelia-storage.path; sessionSecretFile = config.age.secrets.authelia-session.path; oidcHmacSecretFile = config.age.secrets.authelia-oidc-hmac.path; oidcIssuerPrivateKeyFile = config.age.secrets.authelia-oidc-issuer.path; }; environmentVariables = { AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE = config.age.secrets.lldap-password.path; AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = config.age.secrets.smtp.path; }; settings = { theme = "dark"; server = { host = "::1"; inherit port; }; default_2fa_method = "webauthn"; default_redirection_url = "https://${domain}"; log.level = "debug"; authentication_backend = { password_reset.disable = false; refresh_interval = "1m"; ldap = { implementation = "custom"; url = "ldap://${ldapHost}:${toString ldapPort}"; timeout = "5m"; start_tls = false; base_dn = "dc=felschr,dc=com"; username_attribute = "uid"; additional_users_dn = "ou=people"; users_filter = "(&({username_attribute}={input})(objectClass=person))"; additional_groups_dn = "ou=groups"; groups_filter = "(member={dn})"; group_name_attribute = "cn"; mail_attribute = "mail"; display_name_attribute = "displayName"; user = "uid=admin,ou=people,dc=felschr,dc=com"; }; }; access_control = { default_policy = "deny"; rules = [{ domain = [ "*.felschr.com" ]; policy = "two_factor"; }]; }; session = { domain = "felschr.com"; redis = { host = redis.unixSocket; port = 0; }; }; regulation = { max_retries = 3; find_time = "5m"; ban_time = "15m"; }; storage.postgres = { host = "/run/postgresql"; inherit (config.services.postgresql) port; username = cfg.user; database = cfg.user; # password not used since it uses peer auth password = "dummy"; }; # notifier.filesystem.filename = "/var/lib/authelia-main/notifications.log"; notifier.smtp = { inherit (smtpAccount) host port; username = smtpAccount.user; sender = smtpAccount.from; }; identity_providers.oidc.clients = [ { id = "miniflux"; description = "Miniflux RSS"; secret = "$pbkdf2-sha512$310000$uDoutefLT0wyfye.kBEyZw$tX7nwcRVo0LpPPS63Oh9MIeOLkdPRnXX/0JBwMd.aitFIxKDxU.rlywn/WqLVgpIllyFttMl5OnZzjMTbGKZ0A"; redirect_uris = [ "https://news.felschr.com/oauth2/oidc/callback" ]; scopes = [ "openid" "email" "profile" ]; } { id = "tailscale"; description = "Tailscale"; # The digest of "insecure_secret" secret = "$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng"; redirect_uris = [ "https://login.tailscale.com/a/oauth_response" ]; scopes = [ "openid" "email" "profile" ]; } { id = "jellyfin"; description = "Jellyfin"; secret = "$pbkdf2-sha512$310000$X7amOzLsURvZSwdLmSstlQ$/WK4lZ9KvEEuotOxUJkeTo0ZAa.rD7VVdkAPFcUQmr2WzkCXmXXJbYYy7vx0hc4nqLgBVeo8q/71R3rvfl9BFQ"; redirect_uris = [ "https://media.felschr.com/sso/OID/redirect/Authelia" ]; scopes = [ "openid" "email" "profile" ]; } ]; }; }; systemd.services.authelia.requires = [ "postgresql.service" "lldap.service" ]; systemd.services.authelia.after = [ "postgresql.service" "lldap.service" ]; services.postgresql = { enable = true; ensureDatabases = [ cfg.user ]; ensureUsers = [{ name = cfg.user; ensurePermissions."DATABASE \"${cfg.user}\"" = "ALL PRIVILEGES"; }]; }; services.redis.servers.authelia = { enable = true; port = 31641; inherit (cfg) user; }; services.nginx.virtualHosts.${domain} = { enableACME = true; forceSSL = true; locations."/".proxyPass = "http://[::1]:${toString port}"; }; services.nginx.virtualHosts."felschr.com" = { enableACME = true; forceSSL = true; locations."/.well-known/webfinger" = { root = webfingerRoot; extraConfig = '' add_header Access-Control-Allow-Origin "*"; default_type "application/jrd+json"; types { application/jrd+json json; } if ($arg_resource) { rewrite ^(.*)$ /$arg_resource break; } rewrite ^(.*)$ /acct:felschr@fosstodon.org break; ''; }; }; users.users.${cfg.user}.extraGroups = [ "smtp" "ldap" ]; }