Self-host your own digital island
1{ pkgs, config, lib, ... }:
2
3with lib;
4let
5 cfg = config.eilean;
6 domain = config.networking.domain;
7in {
8 options.eilean.mailserver = {
9 enable = mkEnableOption "mailserver";
10 systemAccountPasswordFile = mkOption {
11 type = types.nullOr types.str;
12 default = null;
13 };
14 };
15
16 config = mkIf cfg.mailserver.enable {
17 mailserver = {
18 enable = true;
19 fqdn = "mail.${domain}";
20 domains = [ "${domain}" ];
21
22 loginAccounts = {
23 "system@${domain}" = {
24 passwordFile = cfg.mailserver.systemAccountPasswordFile;
25 aliases = [
26 (mkIf cfg.gitea.enable "git@${domain}")
27 (mkIf cfg.mastodon.enable "mastodon@${domain}")
28 ];
29 };
30 };
31
32 # Use Let's Encrypt certificates. Note that this needs to set up a stripped
33 # down nginx and opens port 80.
34 certificateScheme = 3;
35
36 localDnsResolver = false;
37 };
38
39 services.nginx.enable = true;
40 services.nginx.virtualHosts."${config.mailserver.fqdn}".extraConfig = ''
41 return 301 $scheme://${domain}$request_uri;
42 '';
43
44 eilean.dns.enable = true;
45 eilean.services.dns.zones.${config.networking.domain}.records = [
46 {
47 name = "mail";
48 type = "A";
49 data = cfg.serverIpv4;
50 }
51 {
52 name = "mail";
53 type = "AAAA";
54 data = cfg.serverIpv6;
55 }
56 {
57 name = "@";
58 type = "MX";
59 data = "10 mail";
60 }
61 {
62 name = "@";
63 type = "TXT";
64 data = "\"v=spf1 a:mail.${config.networking.domain} -all\"";
65 }
66 {
67 name = "mail._domainkey";
68 ttl = 10800;
69 type = "TXT";
70 data = "\"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6YmYYvoFF7VqtGcozpVQa78aaGgZdvc5ZIHqzmkKdCBEyDF2FRbCEK4s2AlC8hhc8O4mSSe3S4AzEhlRgHXbU22GBaUZ3s2WHS8JJwZvWeTjsbXQwjN/U7xpkqXPHLH9IVfOJbHlp4HQmCAXw4NaypgkkxIGK0jaZHm2j6/1izQIDAQAB\"";
71 }
72 {
73 name = "_dmarc";
74 ttl = 10800;
75 type = "TXT";
76 data = "\"v=DMARC1; p=reject\"";
77 }
78 ];
79 };
80}