Self-host your own digital island
1{ config, lib, ... }: 2 3let 4 cfg = config.eilean; 5 domain = config.networking.domain; 6in { 7 options.eilean.mailserver.enable = lib.mkEnableOption "mailserver"; 8 9 config = lib.mkIf cfg.mailserver.enable { 10 mailserver = { 11 enable = true; 12 fqdn = "mail.${domain}"; 13 domains = [ "${domain}" ]; 14 15 # A list of all login accounts. To create the password hashes, use 16 # nix run nixpkgs.apacheHttpd -c htpasswd -nbB "" "super secret password" | cut -d: -f2 17 loginAccounts = { 18 "${cfg.username}@${domain}" = { 19 hashedPasswordFile = "${config.eilean.secretsDir}/email-pswd"; 20 aliases = [ 21 "dns@${domain}" 22 "postmaster@${domain}" 23 ]; 24 }; 25 "misc@${domain}" = { 26 hashedPasswordFile = "${config.eilean.secretsDir}/email-pswd"; 27 aliases = [ 28 "git@${domain}" 29 "mastodon@${domain}" 30 ]; 31 catchAll = [ "${domain}" ]; 32 }; 33 }; 34 35 # Use Let's Encrypt certificates. Note that this needs to set up a stripped 36 # down nginx and opens port 80. 37 certificateScheme = 3; 38 39 localDnsResolver = false; 40 }; 41 42 services.nginx.virtualHosts."${config.mailserver.fqdn}".extraConfig = '' 43 return 301 $scheme://${domain}$request_uri; 44 ''; 45 46 dns.records = [ 47 { 48 name = "mail"; 49 type = "A"; 50 data = cfg.serverIpv4; 51 } 52 { 53 name = "mail"; 54 type = "AAAA"; 55 data = cfg.serverIpv6; 56 } 57 { 58 name = "@"; 59 type = "MX"; 60 data = "10 mail"; 61 } 62 { 63 name = "@"; 64 type = "TXT"; 65 data = "\"v=spf1 a:mail.${config.networking.domain} -all\""; 66 } 67 { 68 name = "mail._domainkey"; 69 ttl = 10800; 70 type = "TXT"; 71 data = "\"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6YmYYvoFF7VqtGcozpVQa78aaGgZdvc5ZIHqzmkKdCBEyDF2FRbCEK4s2AlC8hhc8O4mSSe3S4AzEhlRgHXbU22GBaUZ3s2WHS8JJwZvWeTjsbXQwjN/U7xpkqXPHLH9IVfOJbHlp4HQmCAXw4NaypgkkxIGK0jaZHm2j6/1izQIDAQAB\""; 72 } 73 { 74 name = "_dmarc"; 75 ttl = 10800; 76 type = "TXT"; 77 data = "\"v=DMARC1; p=none\""; 78 } 79 ]; 80 }; 81}