Add support for LDAP users
Allow configuring lookups for users and their mail addresses from an LDAP directory. The LDAP username will be used as an accountname as opposed to the email address used as the `loginName` for declarative accounts. Mailbox for LDAP users will be stored below `/var/vmail/ldap/<account>`. Configuring domains is out of scope, since domains require further configuration within the NixOS mailserver construct to set up all related services accordingly. Aliases can already be configured using `mailserver.forwards` but could be supported using LDAP at a later point.
This commit is contained in:
parent
d460e9ff62
commit
08f077c5ca
3 changed files with 235 additions and 2 deletions
|
@ -99,6 +99,12 @@ let
|
|||
# The assertion garantees there is exactly one Junk mailbox.
|
||||
junkMailboxName = if junkMailboxNumber == 1 then builtins.elemAt junkMailboxes 0 else "";
|
||||
|
||||
mkLdapSearchScope = scope: (
|
||||
if scope == "sub" then "subtree"
|
||||
else if scope == "one" then "onelevel"
|
||||
else scope
|
||||
);
|
||||
|
||||
in
|
||||
{
|
||||
config = with cfg; lib.mkIf enable {
|
||||
|
@ -236,6 +242,19 @@ in
|
|||
default_fields = uid=${builtins.toString cfg.vmailUID} gid=${builtins.toString cfg.vmailUID} home=${cfg.mailDirectory}
|
||||
}
|
||||
|
||||
${lib.optionalString cfg.ldap.enable ''
|
||||
passdb {
|
||||
driver = ldap
|
||||
args = /etc/dovecot/dovecot-ldap.conf.ext
|
||||
}
|
||||
|
||||
userdb {
|
||||
driver = ldap
|
||||
args = /etc/dovecot/dovecot-ldap.conf.ext
|
||||
default_fields = home=/var/vmail/ldap/%u uid=${toString cfg.vmailUID} gid=${toString cfg.vmailUID}
|
||||
}
|
||||
''}
|
||||
|
||||
service auth {
|
||||
unix_listener auth {
|
||||
mode = 0660
|
||||
|
@ -298,6 +317,37 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
environment.etc = lib.optionalAttrs (cfg.ldap.enable) {
|
||||
"dovecot/dovecot-ldap.conf.ext" = {
|
||||
mode = "0600";
|
||||
uid = config.ids.uids.dovecot2;
|
||||
gid = config.ids.gids.dovecot2;
|
||||
text = ''
|
||||
ldap_version = 3
|
||||
uris = ${lib.concatStringsSep " " cfg.ldap.uris}
|
||||
${lib.optionalString cfg.ldap.startTls ''
|
||||
tls = yes
|
||||
''}
|
||||
tls_require_cert = hard
|
||||
tls_ca_cert_file = ${cfg.ldap.tlsCAFile}
|
||||
dn = ${cfg.ldap.bind.dn}
|
||||
dnpass = ${cfg.ldap.bind.password}
|
||||
sasl_bind = no
|
||||
auth_bind = yes
|
||||
base = ${cfg.ldap.searchBase}
|
||||
scope = ${mkLdapSearchScope cfg.ldap.searchScope}
|
||||
${lib.optionalString (cfg.ldap.dovecot.userAttrs != "") ''
|
||||
user_attrs = ${cfg.ldap.dovecot.user_attrs}
|
||||
''}
|
||||
user_filter = ${cfg.ldap.dovecot.userFilter}
|
||||
${lib.optionalString (cfg.ldap.dovecot.passAttrs != "") ''
|
||||
pass_attrs = ${cfg.ldap.dovecot.passAttrs}
|
||||
''}
|
||||
pass_filter = ${cfg.ldap.dovecot.passFilter}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.dovecot2 = {
|
||||
preStart = ''
|
||||
${genPasswdScript}
|
||||
|
|
|
@ -133,11 +133,40 @@ let
|
|||
smtpd_sasl_security_options = "noanonymous";
|
||||
smtpd_sasl_local_domain = "$myhostname";
|
||||
smtpd_client_restrictions = "permit_sasl_authenticated,reject";
|
||||
smtpd_sender_login_maps = "hash:/etc/postfix/vaccounts";
|
||||
smtpd_sender_login_maps = "hash:/etc/postfix/vaccounts${lib.optionalString cfg.ldap.enable ",ldap:${ldapSenderLoginMap}"}";
|
||||
smtpd_sender_restrictions = "reject_sender_login_mismatch";
|
||||
smtpd_recipient_restrictions = "reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject";
|
||||
cleanup_service_name = "submission-header-cleanup";
|
||||
};
|
||||
|
||||
commonLdapConfig = lib.optionalString (cfg.ldap.enable) ''
|
||||
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_require_cert = yes
|
||||
|
||||
search_base = ${cfg.ldap.searchBase}
|
||||
scope = ${cfg.ldap.searchScope}
|
||||
|
||||
bind = yes
|
||||
bind_dn = ${cfg.ldap.bind.dn}
|
||||
bind_pw = ${cfg.ldap.bind.password}
|
||||
'';
|
||||
|
||||
ldapSenderLoginMap = lib.optionalString (cfg.ldap.enable)
|
||||
(pkgs.writeText "ldap-sender-login-map.cf" ''
|
||||
${commonLdapConfig}
|
||||
query_filter = ${cfg.ldap.postfix.filter}
|
||||
result_attribute = ${cfg.ldap.postfix.uidAttribute}
|
||||
'');
|
||||
|
||||
ldapVirtualMailboxMap = lib.optionalString (cfg.ldap.enable)
|
||||
(pkgs.writeText "ldap-virtual-mailbox-map.cf" ''
|
||||
${commonLdapConfig}
|
||||
query_filter = ${cfg.ldap.postfix.filter}
|
||||
result_attribute = ${cfg.ldap.postfix.uidAttribute}
|
||||
'');
|
||||
in
|
||||
{
|
||||
config = with cfg; lib.mkIf enable {
|
||||
|
@ -170,7 +199,11 @@ in
|
|||
virtual_gid_maps = "static:5000";
|
||||
virtual_mailbox_base = mailDirectory;
|
||||
virtual_mailbox_domains = vhosts_file;
|
||||
virtual_mailbox_maps = mappedFile "valias";
|
||||
virtual_mailbox_maps = [
|
||||
(mappedFile "valias")
|
||||
] ++ lib.optionals (cfg.ldap.enable) [
|
||||
"ldap:${ldapVirtualMailboxMap}"
|
||||
];
|
||||
virtual_transport = "lmtp:unix:/run/dovecot2/dovecot-lmtp";
|
||||
# Avoid leakage of X-Original-To, X-Delivered-To headers between recipients
|
||||
lmtp_destination_recipient_limit = "1";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue