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}