From 3ae17848ceec6c34979964b29e353a0ff9939ba4 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 5 Nov 2024 00:26:26 +0100 Subject: [PATCH] nixos/kanidm: rename options --- nixos/modules/security/pam.nix | 10 +- nixos/modules/services/security/kanidm.nix | 462 ++++++++++++--------- nixos/tests/kanidm.nix | 105 +++-- 3 files changed, 342 insertions(+), 235 deletions(-) diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index e50038ecbec9f6..2af0e2b7a57170 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -658,7 +658,7 @@ let { name = "mysql"; enable = cfg.mysqlAuth; control = "sufficient"; modulePath = "${pkgs.pam_mysql}/lib/security/pam_mysql.so"; settings = { config_file = "/etc/security/pam_mysql.conf"; }; } - { name = "kanidm"; enable = config.services.kanidm.enablePam; control = "sufficient"; modulePath = "${config.services.kanidm.package}/lib/pam_kanidm.so"; settings = { + { name = "kanidm"; enable = config.services.kanidm.unix.enable; control = "sufficient"; modulePath = "${config.services.kanidm.package}/lib/pam_kanidm.so"; settings = { ignore_unknown_user = true; }; } { name = "sss"; enable = config.services.sssd.enable; control = if cfg.sssdStrictAccess then "[default=bad success=ok user_unknown=ignore]" else "sufficient"; modulePath = "${pkgs.sssd}/lib/security/pam_sss.so"; } @@ -772,7 +772,7 @@ let { name = "ldap"; enable = use_ldap; control = "sufficient"; modulePath = "${pam_ldap}/lib/security/pam_ldap.so"; settings = { use_first_pass = true; }; } - { name = "kanidm"; enable = config.services.kanidm.enablePam; control = "sufficient"; modulePath = "${config.services.kanidm.package}/lib/pam_kanidm.so"; settings = { + { name = "kanidm"; enable = config.services.kanidm.unix.enable; control = "sufficient"; modulePath = "${config.services.kanidm.package}/lib/pam_kanidm.so"; settings = { ignore_unknown_user = true; use_first_pass = true; }; } @@ -809,7 +809,7 @@ let { name = "mysql"; enable = cfg.mysqlAuth; control = "sufficient"; modulePath = "${pkgs.pam_mysql}/lib/security/pam_mysql.so"; settings = { config_file = "/etc/security/pam_mysql.conf"; }; } - { name = "kanidm"; enable = config.services.kanidm.enablePam; control = "sufficient"; modulePath = "${config.services.kanidm.package}/lib/pam_kanidm.so"; } + { name = "kanidm"; enable = config.services.kanidm.unix.enable; control = "sufficient"; modulePath = "${config.services.kanidm.package}/lib/pam_kanidm.so"; } { name = "sss"; enable = config.services.sssd.enable; control = "sufficient"; modulePath = "${pkgs.sssd}/lib/security/pam_sss.so"; } { name = "krb5"; enable = config.security.pam.krb5.enable; control = "sufficient"; modulePath = "${pam_krb5}/lib/security/pam_krb5.so"; settings = { use_first_pass = true; @@ -863,7 +863,7 @@ let { name = "mysql"; enable = cfg.mysqlAuth; control = "optional"; modulePath = "${pkgs.pam_mysql}/lib/security/pam_mysql.so"; settings = { config_file = "/etc/security/pam_mysql.conf"; }; } - { name = "kanidm"; enable = config.services.kanidm.enablePam; control = "optional"; modulePath = "${config.services.kanidm.package}/lib/pam_kanidm.so"; } + { name = "kanidm"; enable = config.services.kanidm.unix.enable; control = "optional"; modulePath = "${config.services.kanidm.package}/lib/pam_kanidm.so"; } { name = "sss"; enable = config.services.sssd.enable; control = "optional"; modulePath = "${pkgs.sssd}/lib/security/pam_sss.so"; } { name = "krb5"; enable = config.security.pam.krb5.enable; control = "optional"; modulePath = "${pam_krb5}/lib/security/pam_krb5.so"; } { name = "otpw"; enable = cfg.otpwAuth; control = "optional"; modulePath = "${pkgs.otpw}/lib/security/pam_otpw.so"; } @@ -1604,7 +1604,7 @@ in # Include the PAM modules in the system path mostly for the manpages. [ package ] ++ lib.optional config.users.ldap.enable pam_ldap - ++ lib.optional config.services.kanidm.enablePam config.services.kanidm.package + ++ lib.optional config.services.kanidm.unix.enable config.services.kanidm.package ++ lib.optional config.services.sssd.enable pkgs.sssd ++ lib.optionals config.security.pam.krb5.enable [pam_krb5 pam_ccreds] ++ lib.optionals config.security.pam.enableOTPW [ pkgs.otpw ] diff --git a/nixos/modules/services/security/kanidm.nix b/nixos/modules/services/security/kanidm.nix index 845a6703dcfbdc..4ef1093b385960 100644 --- a/nixos/modules/services/security/kanidm.nix +++ b/nixos/modules/services/security/kanidm.nix @@ -19,10 +19,8 @@ let flip foldl' getExe - hasInfix hasPrefix isStorePath - last mapAttrsToList mkEnableOption mkForce @@ -32,7 +30,6 @@ let mkPackageOption optional optionalString - splitString subtractLists types unique @@ -42,12 +39,12 @@ let settingsFormat = pkgs.formats.toml { }; # Remove null values, so we can document optional values that don't end up in the generated TOML file. filterConfig = converge (filterAttrsRecursive (_: v: v != null)); - serverConfigFile = settingsFormat.generate "server.toml" (filterConfig cfg.serverSettings); - clientConfigFile = settingsFormat.generate "kanidm-config.toml" (filterConfig cfg.clientSettings); - unixConfigFile = settingsFormat.generate "kanidm-unixd.toml" (filterConfig cfg.unixSettings); + serverConfigFile = settingsFormat.generate "server.toml" (filterConfig cfg.server.settings); + clientConfigFile = settingsFormat.generate "kanidm-config.toml" (filterConfig cfg.client.settings); + unixConfigFile = settingsFormat.generate "kanidm-unixd.toml" (filterConfig cfg.unix.settings); certPaths = builtins.map builtins.dirOf [ - cfg.serverSettings.tls_chain - cfg.serverSettings.tls_key + cfg.server.settings.tls_chain + cfg.server.settings.tls_key ]; # Merge bind mount paths and remove paths where a prefix is already mounted. @@ -197,169 +194,255 @@ let --state ${provisionStateJson} ''; - serverPort = - # ipv6: - if hasInfix "]:" cfg.serverSettings.bindaddress then - last (splitString "]:" cfg.serverSettings.bindaddress) - else - # ipv4: - if hasInfix "." cfg.serverSettings.bindaddress then - last (splitString ":" cfg.serverSettings.bindaddress) - # default is 8443 - else - "8443"; in { + imports = [ + (lib.mkRenamedOptionModule + [ + "services" + "kanidm" + "enablePam" + ] + [ + "services" + "kanidm" + "unix" + "enable" + ] + ) + (lib.mkRenamedOptionModule + [ + "services" + "kanidm" + "unixSettings" + ] + [ + "services" + "kanidm" + "unix" + "settings" + ] + ) + (lib.mkRenamedOptionModule + [ + "services" + "kanidm" + "enableClient" + ] + [ + "services" + "kanidm" + "client" + "enable" + ] + ) + (lib.mkRenamedOptionModule + [ + "services" + "kanidm" + "clientSettings" + ] + [ + "services" + "kanidm" + "client" + "settings" + ] + ) + (lib.mkRenamedOptionModule + [ + "services" + "kanidm" + "enableServer" + ] + [ + "services" + "kanidm" + "serves" + "enable" + ] + ) + (lib.mkRenamedOptionModule + [ + "services" + "kanidm" + "serverSettings" + ] + [ + "services" + "kanidm" + "serves" + "settings" + ] + ) + ]; options.services.kanidm = { - enableClient = mkEnableOption "the Kanidm client"; - enableServer = mkEnableOption "the Kanidm server"; - enablePam = mkEnableOption "the Kanidm PAM and NSS integration"; package = mkPackageOption pkgs "kanidm" { }; - serverSettings = mkOption { - type = types.submodule { - freeformType = settingsFormat.type; + server = { + enable = mkEnableOption "the Kanidm server"; + port = mkOption { + description = "Port the webserver binds to."; + default = 8443; + type = types.port; + }; + address = mkOption { + description = "Address the webserver binds to."; + example = "[::1]"; + default = "127.0.0.1"; + type = types.str; + }; + settings = mkOption { + type = types.submodule { + freeformType = settingsFormat.type; - options = { - bindaddress = mkOption { - description = "Address/port combination the webserver binds to."; - example = "[::1]:8443"; - type = types.str; - }; - # Should be optional but toml does not accept null - ldapbindaddress = mkOption { - description = '' - Address and port the LDAP server is bound to. Setting this to `null` disables the LDAP interface. - ''; - example = "[::1]:636"; - default = null; - type = types.nullOr types.str; - }; - origin = mkOption { - description = "The origin of your Kanidm instance. Must have https as protocol."; - example = "https://idm.example.org"; - type = types.strMatching "^https://.*"; - }; - domain = mkOption { - description = '' - The `domain` that Kanidm manages. Must be below or equal to the domain - specified in `serverSettings.origin`. - This can be left at `null`, only if your instance has the role `ReadOnlyReplica`. - While it is possible to change the domain later on, it requires extra steps! - Please consider the warnings and execute the steps described - [in the documentation](https://kanidm.github.io/kanidm/stable/administrivia.html#rename-the-domain). - ''; - example = "example.org"; - default = null; - type = types.nullOr types.str; - }; - db_path = mkOption { - description = "Path to Kanidm database."; - default = "/var/lib/kanidm/kanidm.db"; - readOnly = true; - type = types.path; - }; - tls_chain = mkOption { - description = "TLS chain in pem format."; - type = types.path; - }; - tls_key = mkOption { - description = "TLS key in pem format."; - type = types.path; - }; - log_level = mkOption { - description = "Log level of the server."; - default = "info"; - type = types.enum [ - "info" - "debug" - "trace" - ]; - }; - role = mkOption { - description = "The role of this server. This affects the replication relationship and thereby available features."; - default = "WriteReplica"; - type = types.enum [ - "WriteReplica" - "WriteReplicaNoUI" - "ReadOnlyReplica" - ]; - }; - online_backup = { - path = mkOption { - description = "Path to the output directory for backups."; - type = types.path; - default = "/var/lib/kanidm/backups"; - }; - schedule = mkOption { - description = "The schedule for backups in cron format."; + options = { + bindaddress = mkOption { + description = "Address/port combination the webserver binds to."; type = types.str; - default = "00 22 * * *"; }; - versions = mkOption { + # Should be optional but toml does not accept null + ldapbindaddress = mkOption { description = '' - Number of backups to keep. - - The default is set to `0`, in order to disable backups by default. + Address and port the LDAP server is bound to. Setting this to `null` disables the LDAP interface. + ''; + example = "[::1]:636"; + default = null; + type = types.nullOr types.str; + }; + origin = mkOption { + description = "The origin of your Kanidm instance. Must have https as protocol."; + example = "https://idm.example.org"; + type = types.strMatching "^https://.*"; + }; + domain = mkOption { + description = '' + The `domain` that Kanidm manages. Must be below or equal to the domain + specified in `server.settings.origin`. + This can be left at `null`, only if your instance has the role `ReadOnlyReplica`. + While it is possible to change the domain later on, it requires extra steps! + Please consider the warnings and execute the steps described + [in the documentation](https://kanidm.github.io/kanidm/stable/administrivia.html#rename-the-domain). ''; - type = types.ints.unsigned; - default = 0; - example = 7; + example = "example.org"; + default = null; + type = types.nullOr types.str; + }; + db_path = mkOption { + description = "Path to Kanidm database."; + default = "/var/lib/kanidm/kanidm.db"; + readOnly = true; + type = types.path; + }; + tls_chain = mkOption { + description = "TLS chain in pem format."; + type = types.path; + }; + tls_key = mkOption { + description = "TLS key in pem format."; + type = types.path; + }; + log_level = mkOption { + description = "Log level of the server."; + default = "info"; + type = types.enum [ + "info" + "debug" + "trace" + ]; + }; + role = mkOption { + description = "The role of this server. This affects the replication relationship and thereby available features."; + default = "WriteReplica"; + type = types.enum [ + "WriteReplica" + "WriteReplicaNoUI" + "ReadOnlyReplica" + ]; + }; + online_backup = { + path = mkOption { + description = "Path to the output directory for backups."; + type = types.path; + default = "/var/lib/kanidm/backups"; + }; + schedule = mkOption { + description = "The schedule for backups in cron format."; + type = types.str; + default = "00 22 * * *"; + }; + versions = mkOption { + description = '' + Number of backups to keep. + + The default is set to `0`, in order to disable backups by default. + ''; + type = types.ints.unsigned; + default = 0; + example = 7; + }; }; }; + config.bindaddress = "${cfg.server.address}:${builtins.toString cfg.server.port}"; }; + default = { }; + description = '' + Settings for Kanidm, see + [the documentation](https://kanidm.github.io/kanidm/stable/server_configuration.html) + and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/server.toml) + for possible values. + ''; }; - default = { }; - description = '' - Settings for Kanidm, see - [the documentation](https://kanidm.github.io/kanidm/stable/server_configuration.html) - and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/server.toml) - for possible values. - ''; }; - clientSettings = mkOption { - type = types.submodule { - freeformType = settingsFormat.type; + client = { + enable = mkEnableOption "the Kanidm client"; + settings = mkOption { + type = types.submodule { + freeformType = settingsFormat.type; - options.uri = mkOption { - description = "Address of the Kanidm server."; - example = "http://127.0.0.1:8080"; - type = types.str; + options.uri = mkOption { + description = "Address of the Kanidm server."; + example = "http://127.0.0.1:8080"; + type = types.str; + }; }; + description = '' + Configure Kanidm clients, needed for the PAM daemon. See + [the documentation](https://kanidm.github.io/kanidm/stable/client_tools.html#kanidm-configuration) + and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/config) + for possible values. + ''; }; - description = '' - Configure Kanidm clients, needed for the PAM daemon. See - [the documentation](https://kanidm.github.io/kanidm/stable/client_tools.html#kanidm-configuration) - and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/config) - for possible values. - ''; }; - unixSettings = mkOption { - type = types.submodule { - freeformType = settingsFormat.type; - - options = { - pam_allowed_login_groups = mkOption { - description = "Kanidm groups that are allowed to login using PAM."; - example = "my_pam_group"; - type = types.listOf types.str; - }; - hsm_pin_path = mkOption { - description = "Path to a HSM pin."; - default = "/var/cache/kanidm-unixd/hsm-pin"; - type = types.path; + unix = { + enable = mkEnableOption "the Kanidm PAM and NSS integration"; + settings = mkOption { + type = types.submodule { + freeformType = settingsFormat.type; + + options = { + pam_allowed_login_groups = mkOption { + description = "Kanidm groups that are allowed to login using PAM."; + example = "my_pam_group"; + type = types.listOf types.str; + }; + hsm_pin_path = mkOption { + description = "Path to a HSM pin."; + default = "/var/cache/kanidm-unixd/hsm-pin"; + type = types.path; + }; }; }; + description = '' + Configure Kanidm unix daemon. + See [the documentation](https://kanidm.github.io/kanidm/stable/integrations/pam_and_nsswitch.html#the-unix-daemon) + and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/unixd) + for possible values. + ''; }; - description = '' - Configure Kanidm unix daemon. - See [the documentation](https://kanidm.github.io/kanidm/stable/integrations/pam_and_nsswitch.html#the-unix-daemon) - and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/unixd) - for possible values. - ''; }; provision = { @@ -367,8 +450,8 @@ in instanceUrl = mkOption { description = "The instance url to which the provisioning tool should connect."; - default = "https://localhost:${serverPort}"; - defaultText = ''"https://localhost:"''; + default = "https://localhost:${cfg.serverSetting.port}"; + defaultText = ''"https://localhost:"''; type = types.str; }; @@ -613,7 +696,7 @@ in }; }; - config = mkIf (cfg.enableClient || cfg.enableServer || cfg.enablePam) { + config = mkIf (cfg.client.enable || cfg.server.enable || cfg.unix.enable) { assertions = let entityList = @@ -635,7 +718,7 @@ in unknownGroups = subtractLists knownGroups groups; in { - assertion = (cfg.enableServer && cfg.provision.enable) -> unknownGroups == [ ]; + assertion = (cfg.server.enable && cfg.provision.enable) -> unknownGroups == [ ]; message = "${opt} refers to unknown groups: ${toString unknownGroups}"; }; @@ -645,63 +728,63 @@ in unknownEntities = subtractLists (attrNames entitiesByName) entities; in { - assertion = (cfg.enableServer && cfg.provision.enable) -> unknownEntities == [ ]; + assertion = (cfg.server.enable && cfg.provision.enable) -> unknownEntities == [ ]; message = "${opt} refers to unknown entities: ${toString unknownEntities}"; }; in [ { assertion = - !cfg.enableServer - || ((cfg.serverSettings.tls_chain or null) == null) - || (!isStorePath cfg.serverSettings.tls_chain); + !cfg.server.enable + || ((cfg.server.settings.tls_chain or null) == null) + || (!isStorePath cfg.server.settings.tls_chain); message = '' - points to + points to a file in the Nix store. You should use a quoted absolute path to prevent this. ''; } { assertion = - !cfg.enableServer - || ((cfg.serverSettings.tls_key or null) == null) - || (!isStorePath cfg.serverSettings.tls_key); + !cfg.server.enable + || ((cfg.server.settings.tls_key or null) == null) + || (!isStorePath cfg.server.settings.tls_key); message = '' - points to + points to a file in the Nix store. You should use a quoted absolute path to prevent this. ''; } { - assertion = !cfg.enableClient || options.services.kanidm.clientSettings.isDefined; + assertion = !cfg.client.enable || options.services.kanidm.client.settings.isDefined; message = '' - needs to be configured + needs to be configured if the client is enabled. ''; } { - assertion = !cfg.enablePam || options.services.kanidm.clientSettings.isDefined; + assertion = !cfg.unix.enable || options.services.kanidm.client.settings.isDefined; message = '' - needs to be configured + needs to be configured for the PAM daemon to connect to the Kanidm server. ''; } { assertion = - !cfg.enableServer + !cfg.server.enable || ( - cfg.serverSettings.domain == null - -> cfg.serverSettings.role == "WriteReplica" || cfg.serverSettings.role == "WriteReplicaNoUI" + cfg.server.settings.domain == null + -> cfg.server.settings.role == "WriteReplica" || cfg.server.settings.role == "WriteReplicaNoUI" ); message = '' - can only be set if this instance + can only be set if this instance is not a ReadOnlyReplica. Otherwise the db would inherit it from the instance it follows. ''; } { - assertion = cfg.provision.enable -> cfg.enableServer; - message = " requires to be true"; + assertion = cfg.provision.enable -> cfg.server.enable; + message = " requires to be true"; } # If any secret is provisioned, the kanidm package must have some required patches applied to it { @@ -764,27 +847,28 @@ in # At least one group must map to a value in each claim map { assertion = - (cfg.provision.enable && cfg.enableServer) + (cfg.provision.enable && cfg.server.enable) -> any (xs: xs != [ ]) (attrValues claimCfg.valuesByGroup); message = "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim} does not specify any values for any group"; } # Public clients cannot define a basic secret { assertion = - (cfg.provision.enable && cfg.enableServer && oauth2Cfg.public) -> oauth2Cfg.basicSecretFile == null; + (cfg.provision.enable && cfg.server.enable && oauth2Cfg.public) + -> oauth2Cfg.basicSecretFile == null; message = "services.kanidm.provision.systems.oauth2.${oauth2} is a public client and thus cannot specify a basic secret"; } # Public clients cannot disable PKCE { assertion = - (cfg.provision.enable && cfg.enableServer && oauth2Cfg.public) + (cfg.provision.enable && cfg.server.enable && oauth2Cfg.public) -> !oauth2Cfg.allowInsecureClientDisablePkce; message = "services.kanidm.provision.systems.oauth2.${oauth2} is a public client and thus cannot disable PKCE"; } # Non-public clients cannot enable localhost redirects { assertion = - (cfg.provision.enable && cfg.enableServer && !oauth2Cfg.public) + (cfg.provision.enable && cfg.server.enable && !oauth2Cfg.public) -> !oauth2Cfg.enableLocalhostRedirects; message = "services.kanidm.provision.systems.oauth2.${oauth2} is a non-public client and thus cannot enable localhost redirects"; } @@ -794,17 +878,17 @@ in ) ); - environment.systemPackages = mkIf cfg.enableClient [ cfg.package ]; + environment.systemPackages = mkIf cfg.client.enable [ cfg.package ]; systemd.tmpfiles.settings."10-kanidm" = { - ${cfg.serverSettings.online_backup.path}.d = { + ${cfg.server.settings.online_backup.path}.d = { mode = "0700"; user = "kanidm"; group = "kanidm"; }; }; - systemd.services.kanidm = mkIf cfg.enableServer { + systemd.services.kanidm = mkIf cfg.server.enable { description = "kanidm identity management daemon"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; @@ -829,7 +913,7 @@ in # To create the socket "/run/kanidmd:/run/kanidmd" # To store backups - cfg.serverSettings.online_backup.path + cfg.server.settings.online_backup.path ]; AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; @@ -849,7 +933,7 @@ in environment.RUST_LOG = "info"; }; - systemd.services.kanidm-unixd = mkIf cfg.enablePam { + systemd.services.kanidm-unixd = mkIf cfg.unix.enable { description = "Kanidm PAM daemon"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; @@ -892,7 +976,7 @@ in environment.RUST_LOG = "info"; }; - systemd.services.kanidm-unixd-tasks = mkIf cfg.enablePam { + systemd.services.kanidm-unixd-tasks = mkIf cfg.unix.enable { description = "Kanidm PAM home management daemon"; wantedBy = [ "multi-user.target" ]; after = [ @@ -943,24 +1027,24 @@ in # These paths are hardcoded environment.etc = mkMerge [ - (mkIf cfg.enableServer { "kanidm/server.toml".source = serverConfigFile; }) - (mkIf options.services.kanidm.clientSettings.isDefined { + (mkIf cfg.server.enable { "kanidm/server.toml".source = serverConfigFile; }) + (mkIf options.services.kanidm.client.settings.isDefined { "kanidm/config".source = clientConfigFile; }) - (mkIf cfg.enablePam { "kanidm/unixd".source = unixConfigFile; }) + (mkIf cfg.unix.enable { "kanidm/unixd".source = unixConfigFile; }) ]; - system.nssModules = mkIf cfg.enablePam [ cfg.package ]; + system.nssModules = mkIf cfg.unix.enable [ cfg.package ]; - system.nssDatabases.group = optional cfg.enablePam "kanidm"; - system.nssDatabases.passwd = optional cfg.enablePam "kanidm"; + system.nssDatabases.group = optional cfg.unix.enable "kanidm"; + system.nssDatabases.passwd = optional cfg.unix.enable "kanidm"; users.groups = mkMerge [ - (mkIf cfg.enableServer { kanidm = { }; }) - (mkIf cfg.enablePam { kanidm-unixd = { }; }) + (mkIf cfg.server.enable { kanidm = { }; }) + (mkIf cfg.unix.enable { kanidm-unixd = { }; }) ]; users.users = mkMerge [ - (mkIf cfg.enableServer { + (mkIf cfg.server.enable { kanidm = { description = "Kanidm server"; isSystemUser = true; @@ -968,7 +1052,7 @@ in packages = [ cfg.package ]; }; }) - (mkIf cfg.enablePam { + (mkIf cfg.unix.enable { kanidm-unixd = { description = "Kanidm PAM daemon"; isSystemUser = true; diff --git a/nixos/tests/kanidm.nix b/nixos/tests/kanidm.nix index abbc8dc8a4769d..2d5238336ec417 100644 --- a/nixos/tests/kanidm.nix +++ b/nixos/tests/kanidm.nix @@ -1,4 +1,5 @@ -import ./make-test-python.nix ({ pkgs, ... }: +import ./make-test-python.nix ( + { pkgs, ... }: let certs = import ./common/acme/server/snakeoil-certs.nix; serverDomain = certs.domain; @@ -16,58 +17,79 @@ import ./make-test-python.nix ({ pkgs, ... }: in { name = "kanidm"; - meta.maintainers = with pkgs.lib.maintainers; [ Flakebi oddlama ]; - - nodes.server = { pkgs, ... }: { - services.kanidm = { - enableServer = true; - serverSettings = { - origin = "https://${serverDomain}"; - domain = serverDomain; - bindaddress = "[::]:443"; - ldapbindaddress = "[::1]:636"; - tls_chain = "${certsPath}/snakeoil.crt"; - tls_key = "${certsPath}/snakeoil.key"; + meta.maintainers = with pkgs.lib.maintainers; [ + Flakebi + oddlama + ]; + + nodes.server = + { pkgs, ... }: + { + services.kanidm = { + server = { + enable = true; + address = "[::]"; + port = 443; + settings = { + origin = "https://${serverDomain}"; + domain = serverDomain; + ldapbindaddress = "[::1]:636"; + tls_chain = "${certsPath}/snakeoil.crt"; + tls_key = "${certsPath}/snakeoil.key"; + }; + }; }; - }; - security.pki.certificateFiles = [ certs.ca.cert ]; + security.pki.certificateFiles = [ certs.ca.cert ]; - networking.hosts."::1" = [ serverDomain ]; - networking.firewall.allowedTCPPorts = [ 443 ]; + networking.hosts."::1" = [ serverDomain ]; + networking.firewall.allowedTCPPorts = [ 443 ]; - users.users.kanidm.shell = pkgs.bashInteractive; + users.users.kanidm.shell = pkgs.bashInteractive; - environment.systemPackages = with pkgs; [ kanidm openldap ripgrep ]; - }; + environment.systemPackages = with pkgs; [ + kanidm + openldap + ripgrep + ]; + }; - nodes.client = { nodes, ... }: { - services.kanidm = { - enableClient = true; - clientSettings = { - uri = "https://${serverDomain}"; - verify_ca = true; - verify_hostnames = true; - }; - enablePam = true; - unixSettings = { - pam_allowed_login_groups = [ "shell" ]; + nodes.client = + { nodes, ... }: + { + services.kanidm = { + client = { + enable = true; + settings = { + uri = "https://${serverDomain}"; + verify_ca = true; + verify_hostnames = true; + }; + }; + unix = { + enable = true; + settings = { + pam_allowed_login_groups = [ "shell" ]; + }; + }; }; - }; - networking.hosts."${nodes.server.networking.primaryIPAddress}" = [ serverDomain ]; + networking.hosts."${nodes.server.networking.primaryIPAddress}" = [ serverDomain ]; - security.pki.certificateFiles = [ certs.ca.cert ]; - }; + security.pki.certificateFiles = [ certs.ca.cert ]; + }; - testScript = { nodes, ... }: + testScript = + { nodes, ... }: let - ldapBaseDN = builtins.concatStringsSep "," (map (s: "dc=" + s) (pkgs.lib.splitString "." serverDomain)); + ldapBaseDN = builtins.concatStringsSep "," ( + map (s: "dc=" + s) (pkgs.lib.splitString "." serverDomain) + ); # We need access to the config file in the test script. - filteredConfig = pkgs.lib.converge - (pkgs.lib.filterAttrsRecursive (_: v: v != null)) - nodes.server.services.kanidm.serverSettings; + filteredConfig = pkgs.lib.converge (pkgs.lib.filterAttrsRecursive ( + _: v: v != null + )) nodes.server.services.kanidm.server.settings; serverConfigFile = (pkgs.formats.toml { }).generate "server.toml" filteredConfig; in '' @@ -133,4 +155,5 @@ import ./make-test-python.nix ({ pkgs, ... }: server.shutdown() client.shutdown() ''; - }) + } +)