From b1df749b24d5a451815cf8b89b38fa836afc8655 Mon Sep 17 00:00:00 2001 From: traxys Date: Tue, 10 Oct 2023 20:35:10 +0200 Subject: [PATCH] Add a nixos module --- flake.nix | 5 +- nixos/default.nix | 146 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 nixos/default.nix diff --git a/flake.nix b/flake.nix index 264ed94..3e36f55 100644 --- a/flake.nix +++ b/flake.nix @@ -29,6 +29,7 @@ RUST_DOC_PATH = "${rust}/share/doc/rust/html/std/index.html"; }; - defaultPackage = naersk'.buildPackage ./.; - }); + packages.default = naersk'.buildPackage ./.; + }) + // {nixosModules.stalwart-accounts = import ./nixos self;}; } diff --git a/nixos/default.nix b/nixos/default.nix new file mode 100644 index 0000000..f65229f --- /dev/null +++ b/nixos/default.nix @@ -0,0 +1,146 @@ +self: { + lib, + pkgs, + config, + options, + ... +}: +with lib; { + options.services.stalwart-accounts = { + enable = mkEnableOption "stalwart-accounts, an account manager for stalwart mail server"; + + package = mkOption { + type = types.package; + inherit (self.packages.${config.nixpkgs.system}) default; + }; + + logLevel = mkOption { + type = types.str; + default = "info"; + }; + + settings = { + jwtSecret = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The JWT secret to be used by the application. Should be passed through environmentFile, + with MAIL_ADMIN_JWT_SECRET. + ''; + }; + + oidcEndpoint = mkOption { + type = types.str; + }; + + oidcClientId = mkOption { + type = types.str; + }; + + oidcClientSecret = mkOption { + type = types.nullOr types.str; + default = null; + description = "The environment variable MAIL_ADMIN_CLIENT_SECRET should be preferred"; + }; + + domain = mkOption { + type = types.str; + }; + + scopes = mkOption { + type = types.str; + default = "openid,profile"; + }; + + mailDomain = mkOption { + type = types.str; + }; + + databaseUrl = mkOption { + type = types.str; + default = "postgres://${config.services.stalwart-accounts.user}/stalwart-accounts?host=/var/run/postgresql"; + }; + }; + + user = mkOption { + type = types.str; + default = "stalwart-accounts"; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + }; + }; + + config = let + cfg = config.services.stalwart-accounts; + in + mkIf cfg.enable { + systemd.services.stalwart-accounts = { + description = "stalwart-accounts"; + after = ["network.target" "postgresql.service"]; + wantedBy = ["multi-user.target"]; + + serviceConfig = { + Type = "simple"; + User = cfg.user; + ExecStart = "${cfg.package}/bin/mail_accounts"; + EnvironmentFile = optional (cfg.environmentFile != null) cfg.environmentFile; + # Security + NoNewPrivileges = true; + # Sandboxing + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = ["AF_UNIX AF_INET AF_INET6"]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + PrivateMounts = true; + }; + + environment = { + RUST_LOG = cfg.logLevel; + MAIL_ADMIN_DATABASE_URL = cfg.settings.databaseUrl; + MAIL_ADMIN_DOMAIN = cfg.settings.domain; + MAIL_ADMIN_OIDC_ENDPOINT = cfg.settings.oidcEndpoint; + MAIL_ADMIN_CLIENT_ID = cfg.settings.oidcClientId; + MAIL_ADMIN_SCOPES = cfg.settings.scopes; + MAIL_ADMIN_MAIL_DOMAIN = cfg.settings.mailDomain; + MAIL_ADMIN_JWT_SECRET = cfg.settings.jwtSecret; + MAIL_ADMIN_CLIENT_SECRET = cfg.settings.oidcClientSecret; + }; + }; + + services.postgresql = + mkIf (cfg.settings.databaseUrl == options.services.stalwart-accounts.settings.databaseUrl.default) + { + ensureUsers = [ + { + name = cfg.user; + ensurePermissions = {"DATABASE \"stalwart-accounts\"" = "ALL PRIVILEGES";}; + } + ]; + ensureDatabases = ["stalwart-accounts"]; + }; + + users = mkIf (cfg.user == "stalwart-accounts") { + users.stalwart-accounts = { + description = "stalwart-accounts user"; + group = "stalwart-accounts"; + isSystemUser = true; + }; + groups.stalwart-accounts = {}; + }; + }; +}