From 8e9b074467006c76768efe04cf1fb1ef9d652c67 Mon Sep 17 00:00:00 2001 From: sefidel Date: Wed, 24 Jan 2024 13:29:27 +0900 Subject: initial commit --- modules/services/nixos-mailserver.nix | 159 ++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 modules/services/nixos-mailserver.nix (limited to 'modules/services/nixos-mailserver.nix') diff --git a/modules/services/nixos-mailserver.nix b/modules/services/nixos-mailserver.nix new file mode 100644 index 0000000..2c78780 --- /dev/null +++ b/modules/services/nixos-mailserver.nix @@ -0,0 +1,159 @@ +{ inputs, config, lib, ... }: + +with lib; +let + cfg = config.modules.services.nixos-mailserver; +in +{ + imports = [ inputs.nixos-mailserver.nixosModules.mailserver ]; + + options.modules.services.nixos-mailserver = { + enable = mkEnableOption "nixos-mailserver"; + webmail = { + enable = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Whether to enable roundcube webmail"; + }; + domain = mkOption { type = types.str; }; + realHost = mkOption { type = types.str; }; + }; + }; + + config = mkIf cfg.enable { + sops.secrets.sefidel-imap-pass = { + mode = "0440"; + owner = "dovecot2"; + group = "dovecot2"; + }; + sops.secrets.system-imap-pass = { + mode = "0440"; + owner = "dovecot2"; + group = "dovecot2"; + }; + sops.secrets.internal-imap-pass = { + mode = "0440"; + owner = "dovecot2"; + group = "dovecot2"; + }; + + systemd.services.dovecot2 = { + serviceConfig.SupplementaryGroups = [ "acme" ]; + }; + + services.postfix = { + dnsBlacklists = [ + # TODO: add sources + "b.barracudacentral.org" + "bl.spamcop.net" + ]; + dnsBlacklistOverrides = '' + exotic.sh OK + sefidel.net OK + sefidel.com OK + 192.168.0.0/16 OK + ''; + }; + + # HACK: nixos-mailserver sets up reload hook on 'fqdn', which is 'mail.exotic.sh'. + # Since our cert is a wildcard cert with domain 'exotic.sh', it is excluded from the hook. + security.acme.certs."exotic.sh".reloadServices = [ + "postfix.service" + "dovecot2.service" + ]; + + mailserver = { + enable = true; + fqdn = "mail.exotic.sh"; + domains = [ "exotic.sh" "nand.moe" "sefidel.com" "sefidel.net" ]; + mailboxes = { + Trash = { + auto = "no"; + specialUse = "Trash"; + }; + Junk = { + auto = "subscribe"; + specialUse = "Junk"; + }; + Drafts = { + auto = "subscribe"; + specialUse = "Drafts"; + }; + Sent = { + auto = "subscribe"; + specialUse = "Sent"; + }; + }; + + loginAccounts = { + "contact@sefidel.com" = { + catchAll = [ "sefidel.com" ]; + hashedPasswordFile = config.sops.secrets.sefidel-imap-pass.path; + }; + "contact@sefidel.net" = { + aliases = [ "sefidel" "dev@sefidel.net" "social@sefidel.net" "media@sefidel.net" "public@sefidel.net" "admin" "admin@sefidel.net" "postmaster" "postmaster@sefidel.net" ]; + hashedPasswordFile = config.sops.secrets.sefidel-imap-pass.path; + }; + "sef@exotic.sh" = { + aliases = [ "sef" "sefidel" "sefidel@exotic.sh" "admin" "admin@exotic.sh" "postmaster" "postmaster@exotic.sh" "admin@nand.moe" "postmaster@nand.moe" ]; + hashedPasswordFile = config.sops.secrets.sefidel-imap-pass.path; + }; + "system@exotic.sh" = { + aliases = [ "system" "system@nand.moe" ]; + hashedPasswordFile = config.sops.secrets.system-imap-pass.path; + }; + "internal@exotic.sh" = { + aliases = [ "internal" ]; + hashedPasswordFile = config.sops.secrets.internal-imap-pass.path; + }; + }; + localDnsResolver = false; + certificateScheme = "manual"; + certificateFile = "${config.security.acme.certs."exotic.sh".directory}/cert.pem"; + keyFile = "${config.security.acme.certs."exotic.sh".directory}/key.pem"; + enableImap = true; + enableImapSsl = true; + enableSubmission = true; + enableSubmissionSsl = true; + virusScanning = false; + }; + + services.roundcube = mkIf cfg.webmail.enable { + enable = true; + hostName = cfg.webmail.realHost; + database.host = "localhost"; # use localDB, pgsql db/user creation is done automatically. + + plugins = [ + "archive" + "enigma" + "help" + "markasjunk" + "vcard_attachments" + "zipdownload" + ]; + + extraConfig = '' + # STARTTLS required for authn, therefore the domain must match the SSL cert. + $config['smtp_server'] = 'tls://${config.mailserver.fqdn}'; + ''; + }; + + services.nginx.virtualHosts.${cfg.webmail.realHost} = { + enableACME = mkForce false; # conflicts with useACMEHost + forceSSL = true; + useACMEHost = cfg.webmail.domain; + }; + + modules.persistence.directories = [ + "/var/lib/dovecot" + "/var/lib/rspamd" + "/var/lib/redis-rspamd" + "/var/vmail" + "/var/dkim" + "/var/sieve" + "/var/spool/mail" + ]; + + networking.firewall.allowedTCPPorts = [ 143 993 465 587 ]; + }; +} -- cgit 1.4.1