summaryrefslogtreecommitdiff
path: root/os/kay/modules/mail.nix
blob: ee91f783b812a024c9a20fe0003f8c6201c434df (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
{ config, ... }: let
  ipv6 = "2001:470:ee65::1337";
  domain = config.global.userdata.domain;

  username = config.global.userdata.name;
  secret = "$argon2i$v=19$m=4096,t=3,p=1$SWV5aWU3YWUgZWFTNm9oc28gTGFvdDdlRG8ga2FTaWVjaDYgYWV0aDFHb28$O/sDv7oy9wUxFjvKoxB5o8ZnPvjYJo9DjX0C/AZQFF0";
  email = [
    "${username}@${domain}"
    "official@${domain}"

    "postmaster@${domain}"
    "hostmaster@${domain}"
  ];

  credentials_directory = "/run/credentials/stalwart-mail.service";
in {
  networking.firewall.allowedTCPPorts = [
    25    # smto
    465   # submission
    587   # submissions
    993   # imap ssl
    4190  # managesieve
  ];

  security.acme.certs.${domain}.postRun = "systemctl restart stalwart-mail.service";
  sops.secrets = {
    "mail.${domain}/dkim_rsa" = {};
    "mail.${domain}/dkim_ed25519" = {};
  };

  services.stalwart-mail = {
    enable = true;
    loadCredential = [
      "dkim_rsa:${config.sops.secrets."mail.${domain}/dkim_rsa".path}"
      "dkim_ed25519:${config.sops.secrets."mail.${domain}/dkim_ed25519".path}"

      "cert:${config.security.acme.certs.${domain}.directory}/fullchain.pem"
      "key:${config.security.acme.certs.${domain}.directory}/key.pem"
    ];

    settings = {
      macros = {
        host = "mail.${domain}";
        default_domain = domain;
        default_directory = "in-memory";
        default_store = "sqlite";
      };

      queue.outbound = {
        ip-strategy = "ipv6_then_ipv4";
        source-ip.v6 = "['${ipv6}']";
        tls.starttls = "optional";
      };
      server.listener = {
        smtp.bind = [ "[${ipv6}]:25" "0.0.0.0:25" ];
        jmap.bind = [ "[::]:8034" ];
      };

      signature = {
        rsa = {
          private-key = "file://${credentials_directory}/dkim_rsa";
          selector = "rsa";
          set-body-length = true;
        };
        ed25519 = {
          public-key = "EHk924AruF9Y0Xaf009rpRl+yGusjmjT1Zeho67BnDU=";
          private-key = "file://${credentials_directory}/dkim_ed25519";
          domain = "%{DEFAULT_DOMAIN}%";
          selector = "ed25519";
          headers = [ "From" "To" "Date" "Subject" "Message-ID" ];
          algorithm = "ed25519-sha256";
          canonicalization = "relaxed/relaxed";
          set-body-length = true;
          report = true;
        };
      };

      certificate."default" = {
        cert = "file://${credentials_directory}/cert";
        private-key = "file://${credentials_directory}/key";
      };

      storage.blob = "fs";
      store = {
        fs.disable = false;
        sqlite.disable = false;
      };

      directory."in-memory" = {
        type = "memory";
        options.subaddressing = true;

        principals = [
          {
            inherit email;
            inherit secret;
            name = username;
            type = "admin";
          }
          { # for mta-sts & dmarc reports
            email = "reports${domain}";
            inherit secret;
            name = "reports";
            type = "individual";
          }
        ];
      };
    };
  };
}