Files
nixos/hosts/mail/modules/dovecot.nix

267 lines
7.0 KiB
Nix

{ pkgs
, config
, ...
}:
let
domain = config.networking.domain;
# domain = "cloonar.com";
ldapConfig = pkgs.writeText "dovecot-ldap.conf" ''
hosts = ldap.cloonar.com
tls = yes
dn = "cn=vmail,ou=system,ou=users,dc=cloonar,dc=com"
dnpass = "@ldap-password@"
auth_bind = no
ldap_version = 3
base = ou=users,dc=%Dd
user_filter = (&(objectClass=mailAccount)(mail=%u))
user_attrs = \
quota=quota_rule=*:bytes=%$, \
=home=/var/vmail/%d/%n/, \
=mail=maildir:/var/vmail/%d/%n/Maildir
pass_attrs = mail=user,userPassword=password
pass_filter = (&(objectClass=mailAccount)(mail=%u))
iterate_attrs = =user=%{ldap:mail}
iterate_filter = (objectClass=mailAccount)
scope = subtree
default_pass_scheme = CRYPT
'';
doveSync = pkgs.writeShellScriptBin "dove-sync.sh" ''
#!/usr/bin/env bash
SERVER=''${1}
if [ -z "$SERVER" ]; then
echo "use as dove-sync.sh host.example.com"
exit 1
fi
doveadm user *@cloonar.com | while read user; do
doveadm -v sync -u $user $SERVER
done
doveadm user *@optiprot.eu | while read user; do
doveadm -v sync -u $user $SERVER
done
doveadm user *@superbros.tv | while read user; do
doveadm -v sync -u $user $SERVER
done
doveadm user *@ghetto.at | while read user; do
doveadm -v sync -u $user $SERVER
done
doveadm user *@szaku-consulting.at | while read user; do
doveadm -v sync -u $user $SERVER
done
doveadm user *@korean-skin.care | while read user; do
doveadm -v sync -u $user $SERVER
done
'';
quotaWarning = pkgs.writeShellScriptBin "quota-warning.sh" ''
#!/usr/bin/env bash
PERCENT=''${1}
USER=''${2}
cat << EOF | /usr/lib/dovecot/deliver -d ''${USER} -o "plugin/quota=dict:User quota::noenforcing:proxy::quotadict"
From: no-reply@$(hostname -f)
Subject: Warning: Your mailbox is now ''${PERCENT}% full.
Your mailbox is now ''${PERCENT}% full, please clean up some mails for further incoming mails.
EOF
if [ ''${PERCENT} -ge 95 ]; then
DOMAIN="$(echo ''${USER} | awk -F'@' '{print $2}')"
cat << EOF | /usr/lib/dovecot/deliver -d postmaster@''${DOMAIN} -o "plugin/quota=dict:User quota::noenforcing:proxy::quotadict"
From: no-reply@$(hostname -f)
Subject: Mailbox Quota Warning: ''${PERCENT}% full, ''${USER}
Mailbox (''${USER}) is now ''${PERCENT}% full, please clean up some mails for
further incoming mails.
EOF
fi
'';
in
{
environment.systemPackages = with pkgs; [
doveSync
];
services.dovecot2 = {
enable = true;
enableImap = true;
enableLmtp = true;
enablePAM = false;
mailLocation = "maildir:/var/vmail/%d/%n/Maildir";
mailUser = "vmail";
mailGroup = "vmail";
extraConfig = ''
ssl = yes
ssl_cert = </var/lib/acme/imap.${domain}/fullchain.pem
ssl_key = </var/lib/acme/imap.${domain}/key.pem
ssl_min_protocol = TLSv1.2
ssl_cipher_list = EECDH+AESGCM:EDH+AESGCM
ssl_prefer_server_ciphers = yes
ssl_dh=<${config.security.dhparams.params.dovecot2.path}
mail_plugins = virtual fts fts_lucene quota acl
service lmtp {
user = vmail
unix_listener /var/lib/postfix/queue/private/dovecot-lmtp {
group = postfix
mode = 0600
user = postfix
}
}
service doveadm {
inet_listener {
port = 4170
ssl = yes
}
}
protocol imap {
mail_plugins = $mail_plugins imap_quota imap_acl
}
protocol lmtp {
postmaster_address=postmaster@${domain}
hostname=mail.cloonar.com
mail_plugins = $mail_plugins sieve
}
service auth {
unix_listener auth-userdb {
mode = 0640
user = vmail
group = vmail
}
# Postfix smtp-auth
unix_listener /var/lib/postfix/queue/private/auth {
mode = 0666
user = postfix
group = postfix
}
}
userdb {
args = /run/dovecot2/ldap.conf
driver = ldap
}
passdb {
args = /run/dovecot2/ldap.conf
driver = ldap
}
service imap-login {
client_limit = 1000
service_count = 0
inet_listener imaps {
port = 993
}
}
service managesieve-login {
inet_listener sieve {
port = 4190
}
}
service quota-warning {
executable = script ${quotaWarning}/bin/quota-warning.sh
unix_listener quota-warning {
user = vmail
group = vmail
mode = 0660
}
}
service quota-status {
# '-p <protocol>'. Currently only 'postfix' protocol is supported.
executable = quota-status -p postfix
client_limit = 1
inet_listener {
address = 127.0.0.1
port = 12340
}
}
protocol sieve {
managesieve_logout_format = bytes ( in=%i : out=%o )
}
plugin {
sieve_dir = /var/vmail/%d/%n/sieve/scripts/
sieve = /var/vmail/%d/%n/sieve/active-script.sieve
sieve_extensions = +vacation-seconds +editheader
sieve_vacation_min_period = 1min
fts = lucene
fts_lucene = whitespace_chars=@.
quota_warning = storage=100%% quota-warning 100 %u
quota_warning2 = storage=95%% quota-warning 95 %u
quota_warning3 = storage=90%% quota-warning 90 %u
quota_warning4 = storage=85%% quota-warning 85 %u
quota_grace = 10%%
quota_status_success = DUNNO
quota_status_nouser = DUNNO
quota_status_overquota = "552 5.2.2 Mailbox is full"
}
# If you have Dovecot v2.2.8+ you may get a significant performance improvement with fetch-headers:
imapc_features = $imapc_features fetch-headers
# Read multiple mails in parallel, improves performance
mail_prefetch_count = 20
'';
modules = [
pkgs.dovecot_pigeonhole
];
protocols = [
"sieve"
];
};
users.users.vmail = {
home = "/var/vmail";
createHome = true;
isSystemUser = true;
uid = 1000;
shell = "/run/current-system/sw/bin/nologin";
};
security.dhparams = {
enable = true;
params.dovecot2 = { };
};
sops.secrets.dovecot-ldap-password = { };
systemd.services.dovecot2.preStart = ''
sed -e "s/@ldap-password@/$(cat ${config.sops.secrets.dovecot-ldap-password.path})/" ${ldapConfig} > /run/dovecot2/ldap.conf
'';
systemd.services.dovecot2 = {
wants = [ "acme-imap.${domain}.service" ];
after = [ "acme-imap.${domain}.service" ];
};
users.groups.acme.members = [ "openldap" ];
/* trigger the actual certificate generation for your hostname */
security.acme.certs."imap.${domain}" = {
extraDomainNames = [
"imap-test.${domain}"
"imap-02.${domain}"
];
postRun = "sleep 2 && systemctl restart dovecot2.service";
};
networking.firewall.allowedTCPPorts = [
143 # imap
993 # imaps
4190 # sieve
];
}