diff --git a/default.nix b/default.nix index ad3164e..d8c39d0 100644 --- a/default.nix +++ b/default.nix @@ -319,7 +319,11 @@ in ] ''; description = '' - URIs where your LDAP server can be reached + List of LDAP server URIs. Multiple can be specified. + + Use `ldaps://` for implicit TLS or `ldap://` for a plain connection. See + also {option}`mailserver.ldap.startTls` to enable StartTLS on plain + connections. ''; }; @@ -327,16 +331,16 @@ in type = types.bool; default = false; description = '' - Whether to enable StartTLS upon connection to the server. + Whether to enable StartTLS on ``ldap://`` connections. ''; }; - tlsCAFile = mkOption { + caFile = mkOption { type = types.path; default = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - defaultText = literalMD "see [source](https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/blob/master/default.nix)"; + defaultText = lib.literalExpression "\${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; description = '' - Certificate trust anchors used to verify the LDAP server certificate. + Bundle of CA certificates used to authenticate the LDAP server certificate. ''; }; @@ -345,37 +349,44 @@ in type = types.str; example = "cn=mail,ou=accounts,dc=example,dc=com"; description = '' - Distinguished name used by the mail server to do lookups - against the LDAP servers. + DN used to bind against the LDAP server. + + The server uses this account to lookup and filter accounts. ''; }; passwordFile = mkOption { - type = types.str; + type = types.pathWith { inStore = false; }; example = "/run/my-secret"; description = '' - A file containing the password required to authenticate against the LDAP servers. + File containing the password required to bind against the LDAP server. ''; }; }; - searchBase = mkOption { + base = mkOption { type = types.str; example = "ou=people,ou=accounts,dc=example,dc=com"; description = '' - Base DN at below which to search for users accounts. + Base DN below which user accounts are searched for. ''; }; - searchScope = mkOption { + scope = mkOption { type = types.enum [ - "sub" "base" "one" + "sub" ]; default = "sub"; description = '' - Search scope below which users accounts are looked for. + Search scope relative to the {option}`mailserver.ldap.base`. + + - base: Only the exact Base DN + - one: Immediate child entries of the Base DN, but not the Base DN itself. + - sub: Base DN and all descendant entries at any depth. + + In practice only `one` or `sub` are suitable for multiple LDAP users. ''; }; @@ -395,6 +406,17 @@ in ''; }; + username = mkOption { + type = types.str; + default = "uid"; + example = "name"; + description = '' + The LDAP attribute referencing the username used to login with. + + Typically the `uid` attribute which is part of the `inetOrgPerson` schema. + ''; + }; + password = mkOption { type = types.str; default = "userPassword"; @@ -405,6 +427,19 @@ in Typically the `userPassword` attribute which is part of the `inetOrgPerson` schema. ''; }; + + mail = mkOption { + type = types.str; + default = "mail"; + example = "maildrop"; + description = '' + The attribute name used for looking up accounts by mail address. + + Typically this can be the `mail` attribute from the `inetOrgPerson` + schema, or the `maildrop` attribute from the unofficial Postfix + schema. + ''; + }; }; dovecot = { @@ -413,11 +448,12 @@ in default = "mail=%{user}"; example = "(&(objectClass=inetOrgPerson)(mail=%{user}))"; description = '' - Filter for user lookups in Dovecot. + LDAP filter used for LMTP delivery from Postfix and post-login + information construction, like the home directory. - See the user_filter reference at - https://doc.dovecot.org/2.3/configuration_manual/authentication/ldap_settings_auth/#user-filter - in the Dovecot manual. + See the [user_filter] reference at in the Dovecot manual. + + [user_filter]: https://doc.dovecot.org/2.3/configuration_manual/authentication/ldap_settings_auth/#user-filter ''; }; @@ -426,11 +462,12 @@ in default = "mail=%{user}"; example = "(&(objectClass=inetOrgPerson)(mail=%{user}))"; description = '' - Filter for password lookups in Dovecot. + LDAP filter used to restrict which users are eligible to + authenticate against Dovecot. - See the pass_filter reference for - https://doc.dovecot.org/2.3/configuration_manual/authentication/ldap_settings_auth/#pass-filter - in the Dovecot manual. + See the [pass_filter] reference in the Dovecot manual. + + [pass_filter]: https://doc.dovecot.org/2.3/configuration_manual/authentication/ldap_settings_auth/#pass-filter ''; }; }; @@ -438,29 +475,14 @@ in postfix = { filter = mkOption { type = types.str; - default = "mail=%s"; + default = with cfg.ldap.attributes; "${mail}=%s"; + defaultText = lib.literalExpression '' + with config.mailserver.ldap.attributes; "''${mail}=%s"; + ''; example = "(&(objectClass=inetOrgPerson)(mail=%s))"; description = '' - LDAP filter used to search for an account by mail, where - `%s` is a substitute for the address in - question. - ''; - }; - - uidAttribute = mkOption { - type = types.str; - default = "mail"; - example = "uid"; - description = '' - The LDAP attribute referencing the account name for a user. - ''; - }; - - mailAttribute = mkOption { - type = types.str; - default = "mail"; - description = '' - The LDAP attribute holding mail addresses for a user. + LDAP filter used to search for an account by mail, where `%s` is a + substitute for the address in question. ''; }; }; @@ -1640,5 +1662,16 @@ in (mkRemovedOptionModule [ "mailserver" "ldap" "dovecot" "passAttrs" ] '' The pass_attrs field is now used internally. You can customize the `mailserver.ldap.attributes.password` field instead. '') + (mkRenamedOptionModule [ "mailserver" "ldap" "tlsCAFile" ] [ "mailserver" "ldap" "caFile" ]) + (mkRenamedOptionModule [ "mailserver" "ldap" "searchBase" ] [ "mailserver" "ldap" "base" ]) + (mkRenamedOptionModule [ "mailserver" "ldap" "searchScope" ] [ "mailserver" "ldap" "scope" ]) + (mkRenamedOptionModule + [ "mailserver" "ldap" "postfix" "uidAttribute" ] + [ "mailserver" "ldap" "attributes" "username" ] + ) + (mkRenamedOptionModule + [ "mailserver" "ldap" "postfix" "mailAttribute" ] + [ "mailserver" "ldap" "attributes" "mail" ] + ) ]; } diff --git a/mail-server/dovecot.nix b/mail-server/dovecot.nix index 148c97d..124ecf6 100644 --- a/mail-server/dovecot.nix +++ b/mail-server/dovecot.nix @@ -71,12 +71,12 @@ let tls = yes ''} tls_require_cert = hard - tls_ca_cert_file = ${cfg.ldap.tlsCAFile} + tls_ca_cert_file = ${cfg.ldap.caFile} dn = ${cfg.ldap.bind.dn} sasl_bind = no auth_bind = yes - base = ${cfg.ldap.searchBase} - scope = ${mkLdapSearchScope cfg.ldap.searchScope} + base = ${cfg.ldap.base} + scope = ${mkLdapSearchScope cfg.ldap.scope} user_attrs = \ ${ldapUuidAttribute}=${ldapUuidAttribute}, \ =home=/var/vmail/ldap/%{ldap:${ldapUuidAttribute}}, \ diff --git a/mail-server/postfix.nix b/mail-server/postfix.nix index d860cbd..bf51b63 100644 --- a/mail-server/postfix.nix +++ b/mail-server/postfix.nix @@ -209,11 +209,11 @@ let server_host = ${lib.concatStringsSep " " cfg.ldap.uris} start_tls = ${if cfg.ldap.startTls then "yes" else "no"} version = 3 - tls_ca_cert_file = ${cfg.ldap.tlsCAFile} + tls_ca_cert_file = ${cfg.ldap.caFile} tls_require_cert = yes - search_base = ${cfg.ldap.searchBase} - scope = ${cfg.ldap.searchScope} + search_base = ${cfg.ldap.base} + scope = ${cfg.ldap.scope} bind = yes bind_dn = ${cfg.ldap.bind.dn} @@ -222,7 +222,7 @@ let ldapSenderLoginMap = pkgs.writeText "ldap-sender-login-map.cf" '' ${commonLdapConfig} query_filter = ${cfg.ldap.postfix.filter} - result_attribute = ${cfg.ldap.postfix.mailAttribute} + result_attribute = ${cfg.ldap.attributes.mail} ''; ldapSenderLoginMapFile = "/run/postfix/ldap-sender-login-map.cf"; appendPwdInSenderLoginMap = appendLdapBindPwd { @@ -236,7 +236,7 @@ let ldapVirtualMailboxMap = pkgs.writeText "ldap-virtual-mailbox-map.cf" '' ${commonLdapConfig} query_filter = ${cfg.ldap.postfix.filter} - result_attribute = ${cfg.ldap.postfix.uidAttribute} + result_attribute = ${cfg.ldap.attributes.username} ''; ldapVirtualMailboxMapFile = "/run/postfix/ldap-virtual-mailbox-map.cf"; appendPwdInVirtualMailboxMap = appendLdapBindPwd { diff --git a/tests/ldap.nix b/tests/ldap.nix index d2e89fa..7402a67 100644 --- a/tests/ldap.nix +++ b/tests/ldap.nix @@ -110,8 +110,8 @@ in dn = "cn=mail,dc=example"; passwordFile = "/etc/bind-password"; }; - searchBase = "ou=users,dc=example"; - searchScope = "sub"; + base = "ou=users,dc=example"; + scope = "sub"; }; forwards = {