{ 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 *@szaku-consulting.at | while read user; do doveadm -v sync -u $user $SERVER done doveadm user *@scana11y.com | 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 dovecot_pigeonhole ]; services.dovecot2 = { enable = true; enableImap = true; enableLmtp = true; enablePAM = false; mailLocation = "maildir:/var/vmail/%d/%n/Maildir"; mailUser = "vmail"; mailGroup = "vmail"; sieve.extensions = [ "copy" "editheader" "relational" "reject" "fileinto" "imap4flags" "vacation-seconds" ]; extraConfig = '' ssl = yes ssl_cert = '. 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 ''; 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 = "systemctl --no-block restart dovecot2.service"; }; networking.firewall.allowedTCPPorts = [ 143 # imap 993 # imaps 4190 # sieve ]; }