diff --git a/sp-modules/auth/flake.nix b/sp-modules/auth/flake.nix index 29d43bf..f0a901a 100644 --- a/sp-modules/auth/flake.nix +++ b/sp-modules/auth/flake.nix @@ -35,8 +35,6 @@ (nixos-unstable.legacyPackages.x86_64-linux.path + /nixos/modules/services/security/oauth2-proxy-nginx.nix) ./module.nix - ./ldap-postfix.nix - ./ldap-dovecot.nix ]; nixpkgs.overlays = [ self.overlays.default ]; diff --git a/sp-modules/auth/module.nix b/sp-modules/auth/module.nix index 063dbfd..1e32ce4 100644 --- a/sp-modules/auth/module.nix +++ b/sp-modules/auth/module.nix @@ -1,14 +1,12 @@ -{ config, lib, pkgs, ... }@nixos-args: +{ config, lib, pkgs, ... }: let - inherit (import ./common.nix nixos-args) - auth-fqdn - cfg - domain - kanidm_ldap_port - ldap_base_dn - passthru - ; + passthru = config.passthru.selfprivacy.auth; + cfg = config.selfprivacy.modules.auth; + domain = config.selfprivacy.domain; + kanidm-bind-address = "127.0.0.1:3013"; + + # lua stuff for debugging only lua_core_path = "${pkgs.luajitPackages.lua-resty-core}/lib/lua/5.1/?.lua"; lua_lrucache_path = "${pkgs.luajitPackages.lua-resty-lrucache}/lib/lua/5.1/?.lua"; lua_path = "${lua_core_path};${lua_lrucache_path};"; @@ -34,6 +32,9 @@ in # FIXME revise this: maybe kanidm must not have access to a public TLS users.groups."acmereceivers".members = [ "kanidm" ]; + # for ExecStartPost scripts to have access to /run/keys/* + users.groups.keys.members = [ "kanidm" ]; + services.kanidm = { enableServer = true; @@ -46,7 +47,7 @@ in # included if it is non-standard (any port except 443). This must match or # be a descendent of the domain name you configure above. If these two # items are not consistent, the server WILL refuse to start! - origin = "https://" + auth-fqdn; + origin = "https://" + passthru.auth-fqdn; # TODO revise this: maybe kanidm must not have access to a public TLS tls_chain = @@ -55,9 +56,9 @@ in "${config.security.acme.certs.${domain}.directory}/key.pem"; # nginx should proxy requests to it - bindaddress = passthru.kanidm-bind-address; + bindaddress = kanidm-bind-address; - ldapbindaddress = "127.0.0.1:${toString kanidm_ldap_port}"; + ldapbindaddress = "127.0.0.1:${toString passthru.ldap-port}"; # kanidm is behind a proxy trust_x_forward_for = true; @@ -70,7 +71,7 @@ in }; enableClient = true; clientSettings = { - uri = "https://" + auth-fqdn; + uri = "https://" + passthru.auth-fqdn; verify_ca = false; # FIXME verify_hostnames = false; # FIXME }; @@ -79,19 +80,21 @@ in services.nginx = { enable = true; additionalModules = - lib.lists.optional cfg.debug pkgs.nginxModules.lua; - commonHttpConfig = lib.strings.optionalString cfg.debug '' + lib.mkIf cfg.debug pkgs.nginxModules.lua; + commonHttpConfig = lib.mkIf cfg.debug '' log_format kanidm escape=none '$request $status\n' '[Request body]: $request_body\n' '[Header]: $resp_header\n' '[Response Body]: $resp_body\n\n'; lua_package_path "${lua_path}"; ''; - virtualHosts.${auth-fqdn} = { + virtualHosts.${passthru.auth-fqdn} = { useACMEHost = domain; forceSSL = true; locations."/" = { - extraConfig = lib.strings.optionalString cfg.debug '' + # be aware that such logging mechanism breaks Kanidm authentication + # (but authorization works) + extraConfig = lib.mkIf cfg.debug '' access_log /var/log/nginx/kanidm.log kanidm; lua_need_request_body on; @@ -120,43 +123,27 @@ in end '; ''; - proxyPass = "https://${passthru.kanidm-bind-address}"; + proxyPass = "https://${kanidm-bind-address}"; }; }; }; - # TODO move to mailserver module everything below - mailserver.debug = cfg.debug; # FIXME - mailserver.mailDirectory = "/var/vmail"; - - mailserver.loginAccounts = lib.mkForce { }; - mailserver.extraVirtualAliases = lib.mkForce { }; - # LDAP is needed for Postfix to query Kanidm about email address ownership. - # LDAP is needed for Dovecot also. - mailserver.ldap = { - enable = false; - # bind.dn = "uid=mail,ou=persons," + ldap_base_dn; - bind.dn = "dn=token"; - # TODO change in this file should trigger system restart dovecot - bind.passwordFile = "/run/keys/dovecot/kanidm-service-account-token"; # FIXME - - # searchBase = "ou=persons," + ldap_base_dn; - searchBase = ldap_base_dn; # TODO refine this - - # NOTE: 127.0.0.1 instead of localhost does not work for unknown reason - uris = [ "ldaps://localhost:${toString kanidm_ldap_port}" ]; - }; - - environment.systemPackages = lib.lists.optionals cfg.debug [ - pkgs.shelldap - pkgs.openldap - ]; - - passthru.selfprivacy.auth = { - kanidm-bind-address = "127.0.0.1:3013"; + passthru.selfprivacy.auth = rec { + auth-fqdn = cfg.subdomain + "." + domain; oauth2-introspection-url = client_id: client_secret: "https://${client_id}:${client_secret}@${auth-fqdn}/oauth2/token/introspect"; - oauth2-discovery-url = client_id: "https://${auth-fqdn}/oauth2/openid/${client_id}/.well-known/openid-configuration"; + oauth2-discovery-url = client_id: + "https://${auth-fqdn}/oauth2/openid/${client_id}/.well-known/openid-configuration"; + oauth2-provider-name = "kanidm"; + oauth2-systemd-service = "kanidm.service"; + + # e.g. "dc=mydomain,dc=com" + ldap-base-dn = + lib.strings.concatMapStringsSep + "," + (x: "dc=" + x) + (lib.strings.splitString "." domain); + ldap-port = 3636; }; }; } diff --git a/sp-modules/roundcube/config-paths-needed.json b/sp-modules/roundcube/config-paths-needed.json index f017fdd..f40e8f4 100644 --- a/sp-modules/roundcube/config-paths-needed.json +++ b/sp-modules/roundcube/config-paths-needed.json @@ -1,7 +1,9 @@ [ + ["mailserver", "fqdn"], + ["passthru", "selfprivacy", "auth", "auth-fqdn"], + ["passthru", "selfprivacy", "auth", "oauth2-provider-name"], ["selfprivacy", "domain"], - ["selfprivacy", "modules", "roundcube"], ["selfprivacy", "modules", "auth"], - ["service", "kanidm"], - ["mailserver", "fqdn"] + ["selfprivacy", "modules", "roundcube"], + ["service", "kanidm"] ] diff --git a/sp-modules/roundcube/module.nix b/sp-modules/roundcube/module.nix index a2b60df..a2ca800 100644 --- a/sp-modules/roundcube/module.nix +++ b/sp-modules/roundcube/module.nix @@ -2,82 +2,10 @@ let domain = config.selfprivacy.domain; cfg = config.selfprivacy.modules.roundcube; - auth-module = config.selfprivacy.modules.auth; - auth-fqdn = auth-module.subdomain + "." + domain; + is-auth-enabled = config.selfprivacy.modules.auth.enable; + auth-passthru = config.passthru.selfprivacy.auth; + auth-fqdn = auth-passthru.auth-fqdn; oauth-client-id = "roundcube"; - dovecot-service-account-name = "dovecot-service-account"; - postfix-service-account-name = "postfix-service-account"; - dovecot-service-account-token-name = "dovecot-service-account-token"; - postfix-service-account-token-name = "postfix-service-account-token"; - # dovecot-service-account-token-fp = "/run/kanidm/token/dovecot"; - dovecot-service-account-token-fp = - "/run/keys/dovecot/kanidm-service-account-token"; - postfix-service-account-token-fp = - "/run/keys/postfix/kanidm-service-account-token"; - dovecot-group = "dovecot2"; # FIXME - postfix-group = "postfix"; # FIXME - # FIXME use usernames and groups from `config` - # FIXME dependency on dovecot2 and postfix - # set-group-ID bit allows for kanidm user to create files, - # which inherit directory group (.e.g dovecot, postfix) - kanidmExecStartPostScriptRoot = pkgs.writeShellScript - "roundcube-kanidm-ExecStartPost-root-script.sh" - '' - mkdir -p -v --mode=u+rwx,g+rs,g-w,o-rwx /run/keys/dovecot - chown kanidm:dovecot2 /run/keys/dovecot - - mkdir -p -v --mode=u+rwx,g+rs,g-w,o-rwx /run/keys/postfix - chown kanidm:postfix /run/keys/postfix - ''; - # FIXME parameterize names like "dovecot2" group - kanidmExecStartPostScript = pkgs.writeShellScript - "roundcube-kanidm-ExecStartPost-script.sh" - '' - export HOME=$RUNTIME_DIRECTORY/client_home - readonly KANIDM="${pkgs.kanidm}/bin/kanidm" - - # get Kanidm service account for Dovecot - KANIDM_SERVICE_ACCOUNT="$($KANIDM service-account list --name idm_admin | grep -E "^name: ${dovecot-service-account-name}$")" - echo KANIDM_SERVICE_ACCOUNT: "$KANIDM_SERVICE_ACCOUNT" - if [ -n "$KANIDM_SERVICE_ACCOUNT" ] - then - echo "kanidm service account \"${dovecot-service-account-name}\" is found" - else - echo "kanidm service account \"${dovecot-service-account-name}\" is not found" - echo "creating new kanidm service account \"${dovecot-service-account-name}\"" - if $KANIDM service-account create --name idm_admin ${dovecot-service-account-name} ${dovecot-service-account-name} idm_admin - then - "kanidm service account \"${dovecot-service-account-name}\" created" - else - echo "error: cannot create kanidm service account \"${dovecot-service-account-name}\"" - exit 1 - fi - fi - - # add Kanidm service account to `idm_mail_servers` group - $KANIDM group add-members idm_mail_servers ${dovecot-service-account-name} - - # create a new read-only token for Dovecot - if ! KANIDM_SERVICE_ACCOUNT_TOKEN_JSON="$($KANIDM service-account api-token generate --name idm_admin ${dovecot-service-account-name} ${dovecot-service-account-token-name} --output json)" - then - echo "error: kanidm CLI returns an error when trying to generate service-account api-token" - exit 1 - fi - if ! KANIDM_SERVICE_ACCOUNT_TOKEN="$(echo "$KANIDM_SERVICE_ACCOUNT_TOKEN_JSON" | ${lib.getExe pkgs.jq} -r .result)" - then - echo "error: cannot get service-account API token from JSON" - exit 1 - fi - - # if ! printf "%s\n" "$KANIDM_SERVICE_ACCOUNT_TOKEN" > ${dovecot-service-account-token-fp} - if ! install --mode=640 \ - <(printf "%s" "$KANIDM_SERVICE_ACCOUNT_TOKEN") \ - ${dovecot-service-account-token-fp} - then - echo "error: cannot write token to \"${dovecot-service-account-token-fp}\"" - exit 1 - fi - ''; in { options.selfprivacy.modules.roundcube = { @@ -105,115 +33,44 @@ in }; config = lib.mkIf cfg.enable { - # FIXME get user names from `config` - # in order to allow access below /run/keys - users.groups.keys.members = [ "kanidm" "dovecot2" "postfix" ]; services.roundcube = { enable = true; - # package = pkgs.roundcube.overrideAttrs (_: rec { - # version = "1.6.9"; - # src = pkgs.fetchurl { - # url = "https://github.com/roundcube/roundcubemail/releases/download/${version}/roundcubemail-${version}-complete.tar.gz"; - # sha256 = "sha256-thpfXCL4kMKZ6TWqz88IcGdpkNiuv/DWzf8HW/F8708="; - # }; - # # src = pkgs.fetchurl { - # # url = "https://github.com/roundcube/roundcubemail/archive/master/3a6e25a5b386e0d87427b934ccd2e0e282e0a74e.tar.gz"; - # # sha256 = "sha256-EpEI4E+r3reYbI/5rquia+zgz1+6k49lPChlp4QiZTE="; - # # }; - # postFixup = '' - # cp -v ${/data/sp/roundcubemail-1.6.9/program/include/rcmail_oauth.php} $out/program/include/rcmail_oauth.php - # cp -v ${/data/sp/roundcubemail-1.6.9/program/actions/login/oauth.php} $out/program/actions/login/oauth.php - # rm -r $out/program/localization/* - # ''; - # }); - # package = pkgs.runCommandNoCCLocal "roundcube-debug" {} '' - # cp -r --no-preserve=all ${pkgs.roundcube} $out - # cp -v ${/data/sp/roundcubemail-1.6.8/plugins/debug_logger/debug_logger.php} $out/plugins/debug_logger/debug_logger.php - # cp -v ${/data/sp/roundcubemail-1.6.8/program/include/rcmail_oauth.php} $out/program/include/rcmail_oauth.php - # ''; # this is the url of the vhost, not necessarily the same as the fqdn of # the mailserver hostName = "${cfg.subdomain}.${config.selfprivacy.domain}"; - # plugins = [ "debug_logger" ]; extraConfig = '' # starttls needed for authentication, so the fqdn required to match # the certificate $config['smtp_host'] = "tls://${config.mailserver.fqdn}"; - # $config['smtp_user'] = "%u"; - # $config['smtp_pass'] = "%p"; - '' + lib.strings.optionalString auth-module.enable '' + $config['smtp_user'] = "%u"; + $config['smtp_pass'] = "%p"; + '' + lib.strings.optionalString is-auth-enabled '' $config['oauth_provider'] = 'generic'; - $config['oauth_provider_name'] = 'kanidm'; # FIXME + $config['oauth_provider_name'] = '${auth-passthru.oauth2-provider-name}'; $config['oauth_client_id'] = '${oauth-client-id}'; $config['oauth_client_secret'] = 'VERYSTRONGSECRETFORROUNDCUBE'; # FIXME - $config['oauth_auth_uri'] = 'https://${auth-fqdn}/ui/oauth2'; $config['oauth_token_uri'] = 'https://${auth-fqdn}/oauth2/token'; $config['oauth_identity_uri'] = 'https://${auth-fqdn}/oauth2/openid/${oauth-client-id}/userinfo'; - $config['oauth_scope'] = 'email profile openid'; - # $config['oauth_scope'] = 'email openid dovecotprofile'; + $config['oauth_scope'] = 'email profile openid'; # FIXME $config['oauth_auth_parameters'] = []; $config['oauth_identity_fields'] = ['email']; - $config['oauth_login_redirect'] = false; + $config['oauth_login_redirect'] = true; $config['auto_create_user'] = true; - - $config['log_dir'] = '/tmp/roundcube'; - $config['log_driver'] = 'stdout'; - $config['log_errors'] = 1; - // Log SQL queries to /sql or to syslog - $config['sql_debug'] = true; - - // Log IMAP conversation to /imap or to syslog - $config['imap_debug'] = true; - $config['log_debug'] = true; - $config['oauth_debug'] = true; - - // Log LDAP conversation to /ldap or to syslog - $config['ldap_debug'] = true; - - // Log SMTP conversation to /smtp or to syslog - $config['smtp_debug'] = true; - - $config['debug_logger']['master'] = 'master'; - $config['debug_logger']['oauth'] = 'oauth'; - $config['debug_logger']['imap'] = 'imap'; - $config['debug_logger']['log'] = 'log'; - $config['debug_logger']['smtp'] = 'smtp'; - - $config['oauth_verify_peer'] = false; - $config['log_logins'] = true; - $config['log_session'] = true; - # $config['oauth_pkce'] = 'S256'; + $config['oauth_verify_peer'] = false; # FIXME + # $config['oauth_pkce'] = 'S256'; # FIXME ''; }; + services.nginx.virtualHosts."${cfg.subdomain}.${domain}" = { forceSSL = true; useACMEHost = domain; enableACME = false; - # extraConfig = '' - # add_header X-Frame-Options DENY; - # add_header X-Content-Type-Options nosniff; - # add_header X-XSS-Protection "1; mode=block"; - # ''; - }; - systemd = { - services = { - phpfpm-roundcube.serviceConfig = { - Slice = lib.mkForce "roundcube.slice"; - StandardError = "journal"; - StandardOutput = "journal"; - }; - kanidm.serviceConfig.ExecStartPost = lib.mkAfter [ - ("+" + kanidmExecStartPostScriptRoot) - kanidmExecStartPostScript - ]; - }; - slices.roundcube = { - description = "Roundcube service slice"; - }; }; - services.kanidm.provision = lib.mkIf auth-module.enable { + systemd.slices.roundcube.description = "Roundcube service slice"; + + services.kanidm.provision = lib.mkIf is-auth-enabled { groups.roundcube_users.present = true; systems.oauth2.roundcube = { displayName = "Roundcube"; @@ -228,7 +85,7 @@ in "profile" "openid" ]; - # scopeMaps.roundcube_users = [ + # scopeMaps."sp.roundcube.users" = [ # "email" # "openid" # "dovecotprofile" @@ -238,7 +95,7 @@ in # claimMaps.groups = { # joinType = "array"; # valuesByGroup = { - # "sp.roundcube.admin" = [ "admin" ]; + # "sp.roundcube.admins" = [ "admin" ]; # }; # }; }; diff --git a/sp-modules/auth/common.nix b/sp-modules/simple-nixos-mailserver/common.nix similarity index 63% rename from sp-modules/auth/common.nix rename to sp-modules/simple-nixos-mailserver/common.nix index 91f0f0c..d7544e6 100644 --- a/sp-modules/auth/common.nix +++ b/sp-modules/simple-nixos-mailserver/common.nix @@ -1,18 +1,8 @@ -{ config, lib, pkgs, ... }: +{ config, pkgs, ... }: rec { + auth-passthru = config.passthru.selfprivacy.auth; domain = config.selfprivacy.domain; - cfg = config.selfprivacy.modules.auth; - passthru = config.passthru.selfprivacy.auth; - auth-fqdn = cfg.subdomain + "." + domain; - - kanidm_ldap_port = 3636; - - # e.g. "dc=mydomain,dc=com" - ldap_base_dn = - lib.strings.concatMapStringsSep - "," - (x: "dc=" + x) - (lib.strings.splitString "." domain); + is-auth-enabled = config.selfprivacy.modules.auth.enable; appendLdapBindPwd = { name, file, prefix, suffix ? "", passwordFile, destination }: diff --git a/sp-modules/simple-nixos-mailserver/config-paths-needed.json b/sp-modules/simple-nixos-mailserver/config-paths-needed.json index 9341829..1c1df79 100644 --- a/sp-modules/simple-nixos-mailserver/config-paths-needed.json +++ b/sp-modules/simple-nixos-mailserver/config-paths-needed.json @@ -1,8 +1,11 @@ [ [ "mailserver" ], + [ "passthru", "selfprivacy", "auth" ], [ "security", "acme", "certs" ], [ "selfprivacy", "domain" ], [ "selfprivacy", "hashedMasterPassword" ], + [ "selfprivacy", "modules", "auth", "enable" ], + [ "selfprivacy", "modules", "simple-nixos-mailserver" ], [ "selfprivacy", "useBinds" ], [ "selfprivacy", "username" ], [ "selfprivacy", "users" ], @@ -11,6 +14,5 @@ [ "services", "postfix", "group" ], [ "services", "postfix", "user" ], [ "services", "redis" ], - [ "services", "rspamd" ], - [ "selfprivacy", "modules", "simple-nixos-mailserver" ] + [ "services", "rspamd" ] ] diff --git a/sp-modules/simple-nixos-mailserver/config.nix b/sp-modules/simple-nixos-mailserver/config.nix index 984289f..c7da54d 100644 --- a/sp-modules/simple-nixos-mailserver/config.nix +++ b/sp-modules/simple-nixos-mailserver/config.nix @@ -1,6 +1,71 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let sp = config.selfprivacy; + + inherit (import ./common.nix {inherit config pkgs;}) + auth-passthru + domain + is-auth-enabled + ; + + mailserver-service-account-name = "sp.mailserver.service-account"; + mailserver-service-account-token-name = "mailserver-service-account-token"; + mailserver-service-account-token-fp = + "/run/keys/mailserver/kanidm-service-account-token"; # FIXME sync with auth module + kanidmExecStartPostScriptRoot = pkgs.writeShellScript + "mailserver-kanidm-ExecStartPost-root-script.sh" + '' + # set-group-ID bit allows for kanidm user to create files, + mkdir -p -v --mode=u+rwx,g+rs,g-w,o-rwx /run/keys/mailserver + chown kanidm:kanidm /run/keys/mailserver + ''; + kanidmExecStartPostScript = pkgs.writeShellScript + "mailserver-kanidm-ExecStartPost-script.sh" + '' + export HOME=$RUNTIME_DIRECTORY/client_home + readonly KANIDM="${pkgs.kanidm}/bin/kanidm" + + # get Kanidm service account for mailserver + KANIDM_SERVICE_ACCOUNT="$($KANIDM service-account list --name idm_admin | grep -E "^name: ${mailserver-service-account-name}$")" + echo KANIDM_SERVICE_ACCOUNT: "$KANIDM_SERVICE_ACCOUNT" + if [ -n "$KANIDM_SERVICE_ACCOUNT" ] + then + echo "kanidm service account \"${mailserver-service-account-name}\" is found" + else + echo "kanidm service account \"${mailserver-service-account-name}\" is not found" + echo "creating new kanidm service account \"${mailserver-service-account-name}\"" + if $KANIDM service-account create --name idm_admin ${mailserver-service-account-name} ${mailserver-service-account-name} idm_admin + then + "kanidm service account \"${mailserver-service-account-name}\" created" + else + echo "error: cannot create kanidm service account \"${mailserver-service-account-name}\"" + exit 1 + fi + fi + + # add Kanidm service account to `idm_mail_servers` group + $KANIDM group add-members idm_mail_servers ${mailserver-service-account-name} + + # create a new read-only token for mailserver + if ! KANIDM_SERVICE_ACCOUNT_TOKEN_JSON="$($KANIDM service-account api-token generate --name idm_admin ${mailserver-service-account-name} ${mailserver-service-account-token-name} --output json)" + then + echo "error: kanidm CLI returns an error when trying to generate service-account api-token" + exit 1 + fi + if ! KANIDM_SERVICE_ACCOUNT_TOKEN="$(echo "$KANIDM_SERVICE_ACCOUNT_TOKEN_JSON" | ${lib.getExe pkgs.jq} -r .result)" + then + echo "error: cannot get service-account API token from JSON" + exit 1 + fi + + if ! install --mode=640 \ + <(printf "%s" "$KANIDM_SERVICE_ACCOUNT_TOKEN") \ + ${mailserver-service-account-token-fp} + then + echo "error: cannot write token to \"${mailserver-service-account-token-fp}\"" + exit 1 + fi + ''; in lib.mkIf sp.modules.simple-nixos-mailserver.enable { @@ -42,7 +107,7 @@ lib.mkIf sp.modules.simple-nixos-mailserver.enable # A list of all login accounts. To create the password hashes, use # mkpasswd -m sha-512 "super secret password" - loginAccounts = { + loginAccounts = lib.mkIf (!is-auth-enabled) ({ "${sp.username}@${sp.domain}" = { hashedPassword = sp.hashedMasterPassword; sieveScript = '' @@ -69,9 +134,9 @@ lib.mkIf sp.modules.simple-nixos-mailserver.enable ''; }; }) - sp.users); + sp.users)); - extraVirtualAliases = { + extraVirtualAliases = lib.mkIf (!is-auth-enabled) { "admin@${sp.domain}" = "${sp.username}@${sp.domain}"; }; @@ -90,6 +155,26 @@ lib.mkIf sp.modules.simple-nixos-mailserver.enable enableManageSieve = true; virusScanning = false; + + mailDirectory = "/var/vmail"; + + # LDAP is needed for Postfix to query Kanidm about email address ownership. + # LDAP is needed for Dovecot also. + ldap = lib.mkIf is-auth-enabled { + # false; otherwise, simple-nixos-mailserver enables auth via LDAP + enable = false; + + # bind.dn = "uid=mail,ou=persons," + ldap_base_dn; + bind.dn = "dn=token"; + # TODO change in this file should trigger system restart dovecot + bind.passwordFile = "/run/keys/mailserver/kanidm-service-account-token"; # FIXME + + # searchBase = "ou=persons," + ldap_base_dn; + searchBase = auth-passthru.ldap-base-dn; # TODO refine this + + # NOTE: 127.0.0.1 instead of localhost doesn't work (maybe because of TLS) + uris = [ "ldaps://localhost:${toString auth-passthru.ldap-port}" ]; + }; }; systemd = { @@ -99,6 +184,15 @@ lib.mkIf sp.modules.simple-nixos-mailserver.enable rspamd.serviceConfig.Slice = "simple_nixos_mailserver.slice"; redis-rspamd.serviceConfig.Slice = "simple_nixos_mailserver.slice"; opendkim.serviceConfig.Slice = "simple_nixos_mailserver.slice"; + # FIXME set auth module option instead + kanidm.serviceConfig.ExecStartPost = + lib.mkIf is-auth-enabled + (lib.mkAfter + [ + ("+" + kanidmExecStartPostScriptRoot) + kanidmExecStartPostScript + ] + ); }; slices."simple_nixos_mailserver" = { name = "simple_nixos_mailserver.slice"; diff --git a/sp-modules/simple-nixos-mailserver/flake.nix b/sp-modules/simple-nixos-mailserver/flake.nix index abff9aa..ebc9a0e 100644 --- a/sp-modules/simple-nixos-mailserver/flake.nix +++ b/sp-modules/simple-nixos-mailserver/flake.nix @@ -10,6 +10,8 @@ mailserver.nixosModules.default ./options.nix ./config.nix + ./ldap-postfix.nix + ./ldap-dovecot.nix ]; }; configPathsNeeded = diff --git a/sp-modules/auth/ldap-dovecot.nix b/sp-modules/simple-nixos-mailserver/ldap-dovecot.nix similarity index 89% rename from sp-modules/auth/ldap-dovecot.nix rename to sp-modules/simple-nixos-mailserver/ldap-dovecot.nix index ee6ae92..4a22442 100644 --- a/sp-modules/auth/ldap-dovecot.nix +++ b/sp-modules/simple-nixos-mailserver/ldap-dovecot.nix @@ -4,7 +4,7 @@ let appendLdapBindPwd cfg domain - passthru + auth-passthru ; ldapConfFile = "/run/dovecot2/dovecot-ldap.conf.ext"; # FIXME get "dovecot2" from `config` @@ -46,21 +46,20 @@ let name = "dovecot-oauth2.conf.ext"; text = '' introspection_mode = post - introspection_url = ${passthru.oauth2-introspection-url "roundcube" "VERYSTRONGSECRETFORROUNDCUBE"} + introspection_url = ${auth-passthru.oauth2-introspection-url "roundcube" "VERYSTRONGSECRETFORROUNDCUBE"} client_id = roundcube client_secret = VERYSTRONGSECRETFORROUNDCUBE # FIXME username_attribute = username - # scope = email groups profile openid dovecotprofile scope = email profile openid tls_ca_cert_file = /etc/ssl/certs/ca-certificates.crt active_attribute = active active_value = true - openid_configuration_url = ${passthru.oauth2-discovery-url "roundcube"} - debug = ${if cfg.debug then "yes" else "no"} + openid_configuration_url = ${auth-passthru.oauth2-discovery-url "roundcube"} + debug = "no" ''; }; in -{ +lib.mkIf config.selfprivacy.modules.auth.enable { mailserver.ldap = { # note: in `ldapsearch` first comes filter, then attributes dovecot.userAttrs = "+"; # all operational attributes @@ -121,6 +120,9 @@ in systemd.services.dovecot2 = { # TODO does it merge with existing preStart? preStart = setPwdInLdapConfFile + "\n"; + # FIXME pass dependant services to auth module option instead + wants = [ "kanidm.service" ]; + after = [ "kanidm.service" ]; }; # does it merge with existing restartTriggers? diff --git a/sp-modules/auth/ldap-postfix.nix b/sp-modules/simple-nixos-mailserver/ldap-postfix.nix similarity index 90% rename from sp-modules/auth/ldap-postfix.nix rename to sp-modules/simple-nixos-mailserver/ldap-postfix.nix index 0739f44..217f9bf 100644 --- a/sp-modules/auth/ldap-postfix.nix +++ b/sp-modules/simple-nixos-mailserver/ldap-postfix.nix @@ -2,6 +2,7 @@ let inherit (import ./common.nix nixos-args) appendLdapBindPwd + auth-passthru ; cfg = config.mailserver; @@ -49,7 +50,7 @@ let destination = ldapVirtualMailboxMapFile; }; in -{ +lib.mkIf config.selfprivacy.modules.auth.enable { mailserver.ldap = { postfix.mailAttribute = "mail"; postfix.uidAttribute = "uid"; @@ -59,7 +60,10 @@ in ${appendPwdInVirtualMailboxMap} ${appendPwdInSenderLoginMap} ''; - restartTriggers = [ appendPwdInVirtualMailboxMap appendPwdInSenderLoginMap ]; + restartTriggers = + [ appendPwdInVirtualMailboxMap appendPwdInSenderLoginMap ]; + wants = [ auth-passthru.oauth2-systemd-service ]; + after = [ "kanidm.service" ]; }; services.postfix = { # the list should be merged with other options from nixos-mailserver