{ npins, sopsSecrets, machineConfig, config, lib, pkgs, ... }: { options.zpha.configure.mailServer.enable = lib.mkEnableOption ""; imports = (lib.mkIf config.zpha.configure.mailServer.enable [ (import npins.simpleNixosMailserver) ]).content; config = lib.mkIf config.zpha.configure.mailServer.enable ( let hostName = config.networking.fqdn; ip6Address = machineConfig.networking.ip6Address; ip4Address = machineConfig.networking.ip4Address; primaryDomain = "zaphyra.eu"; primaryDomainDkimKey = "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMuEtG24S6ksVx04avtjwIrfijZvQMxe44HrAXjW+Qe7ZbBHtS+q8alvL21zHbe4VgAOTNZ+fCnqSif4TFaOQnwuGwWke5SRBHV6RmWLaJUnN7krjFj+oNmKnl5M3GPI62shhk4OlMgAdDrH/JApd4XTqR3m0U/8rXqPumfbHhzwIDAQAB"; extraDomains = { "katja.wtf" = "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC56L/GDEY0hTvcZjjCpk3/3c4qAmGAQR06tVpgz7gHs0kMPiGhpg3gDv8kCOu4l3C96oT6eaQoyLcC+ZhJT4ribZaNSD+7lkXk23s4LecklBQxLAjvLrc0GQ9zYp8/Qg4g+Wo9fHR3Lum4tqyyFuT/P21knw+nDWxvz3d0Y4XNVwIDAQAB"; "ctu.cx" = "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOuE5vBNP0L4i3OxcFdFbTJ/c8o58CL+cMHBh8lAZej1nSYOPBdpfJRpWiHduWu8cLWNu62nDeY9IGGnE6g9o6+6sMT51NdoY7FFcNNjhm0EoZVDaB1Ffy74ycIDAwuNfp8kpKFsxWMSs1CFy6IRDIIzaQc9JAIoBUBbN5rP2DcwIDAQAB"; "ctucx.de" = "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCg3pBG8oH8h0w5YrZ7Dpmtk+/XqE9HElWeF1SWMo86aVLkbsMKjY0WbfAq5YfEdSr/pQrILC+oAt/q6TuLzABYd7cLzK7KgdIX2SuYvujmHqzOOn1huAkzQU0wJMnMYx/0wCFMnVHXsWY9UF2zHDhYu8Jo9vuwMPwGG9u1qnfdCQIDAQAB"; "thein.ovh" = "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYogCqmPNomxG4KyZGsfpefFNPS5lY9aRm7TjiONKKPKQFb4oFfUBacurfL+cdGhX6CBnRr6IUXZ37e+ptOyWNFfG1e5R7dJeRdmCZvsn2DRbxCEeGA6gjl3hmRIjg3HUCWjWlzjRXV4Qke/7Q1y1lfivOrgU72bLw/V7BEi1OZQIDAQAB"; }; mailAutoConfig = '' ${primaryDomain} ${hostName} ${hostName} ${hostName} 993 SSL password-cleartext %EMAILADDRESS% ${hostName} 465 SSL password-cleartext %EMAILADDRESS% ''; in { dns.zones = with pkgs.dnsNix.combinators; let TXT = [ "v=spf1 a mx ip4:${ip4Address} +ip6:${ip6Address} ~all" ]; DMARC = "v=DMARC1; p=none"; MX = with mx; [ (mx 10 "${hostName}.") ]; in { "${primaryDomain}" = { inherit MX TXT; SRV = [ { proto = "tcp"; service = "imaps"; priority = 0; weight = 1; port = 993; target = "${hostName}."; } { proto = "tcp"; service = "imap"; priority = 0; weight = 1; port = 143; target = "${hostName}."; } { proto = "tcp"; service = "submission"; priority = 0; weight = 1; port = 587; target = "${hostName}."; } ]; subdomains = { autoconfig.CNAME = [ "${hostName}." ]; _dmarc.TXT = [ DMARC ]; "${config.mailserver.dkimSelector}._domainkey".TXT = [ primaryDomainDkimKey ]; }; }; } // (lib.mapAttrs (_domain: dkimKey: { inherit MX TXT; subdomains = { _dmarc.TXT = [ DMARC ]; "${config.mailserver.dkimSelector}._domainkey".TXT = [ dkimKey ]; }; }) extraDomains); sops.secrets = { "restic/mailserver/repositoryPassword" = { }; "restic/mailserver/sshPrivateKey" = { }; "mailPasswords/katja@zaphyra.eu" = { }; "mailPasswords/gts@zaphyra.eu" = { }; "mailPasswords/vaultwarden@zaphyra.eu" = { }; "sieveScripts/katja@zaphyra.eu.sieve" = { sopsFile = sopsSecrets.zaphyra.sieve; key = "katja@zaphyra.eu"; restartUnits = [ "dovecot2.service" ]; owner = "virtualMail"; group = "virtualMail"; path = "/etc/dovecot/sieve/katja-zaphyra-eu.sieve"; }; }; systemd.services.dovecot.after = [ "sops-install-secrets.service" ]; security.acme.certs."${hostName}".reloadServices = [ "postfix.service" "dovecot.service" ]; common = { configure.persist.system.dirs = [ "/var/lib/dhparams" "/var/lib/dovecot" "/var/lib/postfix" { directory = "/var/lib/dkimKeys"; mode = "0700"; user = "rspamd"; group = "rspamd"; } { directory = "/var/lib/mailboxes"; mode = "0700"; user = "virtualMail"; group = "virtualMail"; } { directory = "/var/lib/redis-rspamd"; mode = "0700"; user = "redis-rspamd"; group = "redis-rspamd"; } { directory = "/var/lib/rspamd"; mode = "0700"; user = "rspamd"; group = "rspamd"; } { directory = "/var/lib/sieve"; mode = "0770"; user = "virtualMail"; group = "virtualMail"; } ]; services.resticBackup.mailserver = { enable = true; targets = [ "isodon.fc9f.de" ]; sshKeyFile = config.sops.secrets."restic/mailserver/sshPrivateKey".path; passwordFile = config.sops.secrets."restic/mailserver/repositoryPassword".path; paths = [ "/var/lib/mailboxes" "/var/lib/dkimKeys" "/var/lib/sieve" ]; }; }; services = { dovecot2 = { pluginSettings.sieve_global = "/etc/dovecot/sieve"; sieve.extensions = [ "editheader" ]; }; nginx.virtualHosts."autoconfig.${primaryDomain}" = { useACMEHost = "${config.networking.fqdn}"; forceSSL = true; locations."= /mail/config-v1.1.xml".return = "200 '${mailAutoConfig}'"; }; }; mailserver = { enable = true; stateVersion = 3; openFirewall = true; localDnsResolver = false; virusScanning = false; certificateScheme = "acme"; enableManageSieve = true; enableSubmission = true; enableSubmissionSsl = true; enableImap = true; enableImapSsl = true; enablePop3 = false; enablePop3Ssl = false; fullTextSearch.enable = true; dmarcReporting.enable = true; indexDir = "/var/lib/dovecot/indices"; mailDirectory = "/var/lib/mailboxes"; sieveDirectory = "/var/lib/sieve"; dkimKeyDirectory = "/var/lib/dkimKeys"; fqdn = hostName; systemDomain = primaryDomain; systemName = "zaphyra-mail"; domains = [ primaryDomain ] ++ (lib.attrNames extraDomains); loginAccounts = { "katja@zaphyra.eu" = { hashedPasswordFile = config.sops.secrets."mailPasswords/katja@zaphyra.eu".path; sieveScript = '' require ["include"]; include :global "katja-zaphyra-eu"; ''; aliases = [ "@zaphyra.eu" "@ctu.cx" "@ctucx.de" "@thein.ovh" "@katja.wtf" ]; }; "gts@zaphyra.eu" = { hashedPasswordFile = config.sops.secrets."mailPasswords/gts@zaphyra.eu".path; sendOnly = true; }; "vaultwarden@zaphyra.eu" = { hashedPasswordFile = config.sops.secrets."mailPasswords/vaultwarden@zaphyra.eu".path; sendOnly = true; }; }; }; } ); }