{ inputs, pkgs, config, ... }: let mailAutoConfig = '' ctu.cx ${config.networking.fqdn} ${config.networking.domain} ${config.networking.fqdn} 993 SSL password-cleartext %EMAILADDRESS% ${config.networking.fqdn} 465 SSL password-cleartext %EMAILADDRESS% ''; in { imports = [ inputs.simple-nixos-mailserver.nixosModule ]; age.secrets.restic-mail.file = ./. + "/../../../secrets/${config.networking.hostName}/restic/mail.age"; age.secrets.mail-password-katja.file = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-katja-ctu.cx.age"; age.secrets.mail-password-gts.file = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-gts-ctu.cx.age"; age.secrets.mail-password-gts-zug.file = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-gts-zuggeschmack.de.age"; age.secrets.mail-password-info-zug.file = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-info-zuggeschmack.de.age"; age.secrets.mail-password-vaultwarden.file = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-vaultwarden-ctu.cx.age"; dns.zones = with pkgs.dns.lib.combinators; let TXT = [ "v=spf1 a mx ip4:${config.networking.primaryIP4} +ip6:${config.networking.primaryIP} ~all" ]; DMARC = "v=DMARC1; p=none"; MX = with mx; [ (mx 10 "${config.networking.fqdn}.") ]; in { "ctu.cx" = { inherit MX TXT; SRV = [ { proto = "tcp"; service = "imaps"; priority = 0; weight = 1; port = 993; target = "${config.networking.fqdn}."; } { proto = "tcp"; service = "imap"; priority = 0; weight = 1; port = 143; target = "${config.networking.fqdn}."; } { proto = "tcp"; service = "submission"; priority = 0; weight = 1; port = 587; target = "${config.networking.fqdn}."; } ]; subdomains = { autoconfig.CNAME = [ config.networking.hostName ]; _dmarc.TXT = [ DMARC ]; "mail._domainkey".TXT = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKryfX99NkcU5Xe4AmG+kO/sfuYSXk5RqJhzxS4uMqERE8UszgEGdteXcD8pqON2MfDmA3G6cA+Oa+N4tIWdIYNwTISVXXMGdHvjFIsVUEW0turM104tXESELaPRntkCvDBk/yOgsBDRZQHSx5MdGwpzeRC8TLdCbalh3W0jp5PQIDAQAB" ]; }; }; "ctucx.de" = { inherit MX TXT; subdomains = { _dmarc.TXT = [ DMARC ]; "mail._domainkey".TXT = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5fu690bKYCZLPAFfQQK+nl+aAmtetaWBKCWzGj6pt7HjpFjystgtgnQ6+DZLFXWUp8GRfMEycySB5kQULtYtSMUmx0gQBnTTLsRj+e55/CYUllLV6YXb5uca7LuVhlWPpH3sCr6TvC2VFWe4t0UC3uIXhYPrCm6p8OE7g+TdHHwIDAQAB" ]; }; }; "zuggeschmack.de" = { inherit MX TXT; subdomains = { _dmarc.TXT = [ DMARC ]; "mail._domainkey".TXT = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDf0PX32wWq068cThCnAaX1RJMBiMo6pGfT/VOp9/IzXWmNO2aSyWEFp5lVwYFJnlGX1Sg1uvThICVDiscOqG5jBUAc0gl3SPEBFJ0cqLl7CYhD3Nkvgc8+7zn4huKvFGYXRSDqQm+AL4SSEjZ8hF+N9bGxt0bYu2WlGwZX8mTptwIDAQAB" ]; }; }; "thein.ovh" = { inherit MX TXT; subdomains = { _dmarc.TXT = [ DMARC ]; "mail._domainkey".TXT = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8oumqNkHboF/S4dnKue+hEC3V226ToMmL/fmXqbAhsW88m+jUuLgZE8Nl7kc/lzD9yY7JmCXcWFzoLJWE8xusfmT1yMOW9sQmee7g0tHsm1fVqFMUetmC4+QuqAdvjIGU5QndjdWHP/gssIoLPT7lCNUL4/lkaPmFiiDyvaMpkQIDAQAB" ]; }; }; "flauschehorn.sexy" = { inherit MX TXT; subdomains = { _dmarc.TXT = [ DMARC ]; "mail._domainkey".TXT = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvEPR8068KtlsiWiexSPWqagKmd07ggGvDcYICzOvhxVB0MDrn+/VYIXEbVX0Y9z60oT1ynjkhFjDWEofk11EoXwrg7xjkqZuszDrhdYqUnoLrzlugmnK4jXO3cAD0qeblX0rDmu30cmPP1Aj21tLTU6loYpORY+y4VaVfwtHswwIDAQAB" ]; }; }; }; security.acme.certs."${config.networking.fqdn}".reloadServices = [ "postfix.service" "dovecot2.service" ]; services.nginx = { enable = true; virtualHosts = { "${config.networking.fqdn}" = { enableACME = true; forceSSL = true; }; "autoconfig.ctu.cx" = { enableACME = true; forceSSL = true; locations."= /mail/config-v1.1.xml".return = "200 '${mailAutoConfig}'"; }; }; }; services.redis.servers.rspamd.bind = "::1"; services.dovecot2.sieve.extensions = [ "editheader" ]; mailserver = { enable = true; fqdn = config.networking.fqdn; openFirewall = true; localDnsResolver = false; virusScanning = false; redis.address = "[::1]"; certificateScheme = "manual"; certificateFile = "${config.security.acme.certs.${config.networking.fqdn}.directory}/fullchain.pem"; keyFile = "${config.security.acme.certs.${config.networking.fqdn}.directory}/key.pem"; enableManageSieve = true; enableSubmission = true; enableSubmissionSsl = true; enableImap = true; enableImapSsl = true; enablePop3 = false; enablePop3Ssl = false; mailDirectory = "/var/lib/mailboxes"; sieveDirectory = "/var/lib/sieve"; dkimKeyDirectory = "/var/lib/dkimKeys"; domains = [ "ctu.cx" "ctucx.de" "thein.ovh" "flauschehorn.sexy" "zuggeschmack.de" ]; loginAccounts = { "katja@ctu.cx" = { hashedPasswordFile = config.age.secrets.mail-password-katja.path; sieveScript = builtins.readFile ./rules-katja.sieve; aliases = [ "@ctu.cx" "@ctucx.de" "@thein.ovh" ]; }; "vaultwarden@ctu.cx" = { hashedPasswordFile = config.age.secrets.mail-password-vaultwarden.path; }; "gts@ctu.cx" = { hashedPasswordFile = config.age.secrets.mail-password-gts.path; }; "gts@zuggeschmack.de" = { hashedPasswordFile = config.age.secrets.mail-password-gts-zug.path; }; "info@zuggeschmack.de" = { hashedPasswordFile = config.age.secrets.mail-password-info-zug.path; aliases = [ "@zuggeschmack.de" ]; }; }; }; restic-backups.mail = { passwordFile = config.age.secrets.restic-mail.path; paths = [ "/var/lib/mailboxes" "/var/lib/dkimKeys" "/var/lib/sieve" ]; }; }