My Nix Configuration
at main 5.7 kB view raw
1{ 2 config, 3 lib, 4 self, 5 ... 6}: 7let 8 d = self.lib.data.mail; 9 cfg = config.services.stalwart-mail; 10 sec = config.age.secrets; 11 credsDir = "/run/credentials/stalwart-mail.service"; 12 certDir = config.security.acme.certs."pyroxdev-mail".directory; 13 isAuthenticated = d: { 14 "if" = "!is_empty(authenticated_as)"; 15 "then" = d; 16 }; 17 otherwise = d: { 18 "else" = d; 19 }; 20 ifThen = f: d: { 21 "if" = f; 22 "then" = d; 23 }; 24 smSecret = { 25 owner = "stalwart-mail"; 26 group = "stalwart-mail"; 27 }; 28in 29{ 30 services.stalwart-mail = { 31 credentials = { 32 cert = "${certDir}/cert.pem"; 33 key = "${certDir}/key.pem"; 34 }; 35 enable = true; 36 dataDir = "/var/lib/stalwart"; 37 settings = { 38 tracer.stdout.level = "info"; 39 authentication.fallback-admin = { 40 user = "fallback"; 41 secret = "%{file:${sec.stalwart-fallback-admin-pw.path}}%"; 42 }; 43 config = { 44 local-keys = [ 45 "asn.*" 46 "auth.*" 47 "authentication.*" 48 "auto-ban.*" 49 "calendar.*" 50 "certificate.*" 51 "changes.*" 52 "cluster.*" 53 "config.*" 54 "contacts.*" 55 "directory.*" 56 "http.*" 57 "imap.*" 58 "jmap.*" 59 "queue.*" 60 "report.*" 61 "resolver.*" 62 "server.*" 63 "session.*" 64 "signature.*" 65 "storage.*" 66 "store.*" 67 "tracer.*" 68 "webadmin.*" 69 "form.*" 70 "email.*" 71 "spam-filter.*" 72 ]; 73 }; 74 certificate = { 75 default = { 76 default = true; 77 cert = "%{file:${credsDir}/cert}%"; 78 private-key = "%{file:${credsDir}/key}%"; 79 subjects = [ 80 "dav.pyrox.dev" 81 "mail.pyrox.dev" 82 "mta-sts.pyrox.dev" 83 "autoconfig.pyrox.dev" 84 "autodiscover.pyrox.dev" 85 ]; 86 }; 87 }; 88 server = import ./server.nix { inherit d; }; 89 # Use NixOS-generated certs now, since stalwart can't do it on its own 90 # (DeSec API Errors abound) 91 # acme = import ./acme.nix { inherit cfg sec; }; 92 # HTTP Configuration 93 # https://stalw.art/docs/http/overview 94 http = { 95 url = "'https://${d.extUrl}'"; 96 hsts = true; 97 rate-limit = { 98 account = "10000/1m"; 99 }; 100 }; 101 # Disable HTTP Forms submission 102 # https://stalw.art/docs/http/form-submission 103 form.enable = false; 104 # DKIM Signatures 105 signature = import ./signature.nix { inherit sec; }; 106 # Storage Settings 107 # https://stalw.art/docs/storage/overview 108 store = { 109 data = { 110 type = "rocksdb"; 111 path = "${cfg.dataDir}/db"; 112 purge.frequency = "0 3 *"; 113 }; 114 blob = { 115 type = "fs"; 116 path = "${cfg.dataDir}/blobs"; 117 depth = 2; 118 compression = "lz4"; 119 purge.frequency = "0 4 *"; 120 }; 121 db.path = "${cfg.dataDir}/db2"; 122 }; 123 storage = { 124 data = "data"; 125 blob = "blob"; 126 fts = "data"; 127 lookup = "data"; 128 directory = "default"; 129 }; 130 directory = { 131 default = { 132 type = "internal"; 133 store = "data"; 134 }; 135 }; 136 # ASN/GeoIP Lookups 137 # https://stalw.art/docs/server/asn 138 asn = { 139 type = "dns"; 140 separator = "|"; 141 zone.ipv4 = "origin.asn.cymru.com"; 142 zone.ipv6 = "origin6.asn.cymru.com"; 143 index.asn = 0; 144 index.asn-name = 1; 145 index.country = 2; 146 }; 147 auto-ban = import ./auto-ban.nix; 148 # JMAP Settings 149 # https://stalw.art/docs/email/jmap 150 jmap = { 151 mailbox.max-depth = 10; 152 mailbox.max-name-length = 255; 153 # 50 MB 154 email.max-attachment-size = 50 * 1000 * 1000; 155 # 75 MB 156 email.max-size = 75 * 1000 * 1000; 157 email.parse.max-items = 10; 158 }; 159 imap = import ./imap.nix; 160 # Maintainance 161 # https://stalw.art/docs/email/maintenance 162 email.auto-expunge = "180d"; 163 changes.max-history = 10000; 164 session = import ./session.nix { inherit isAuthenticated otherwise ifThen; }; 165 queue = import ./queue.nix { inherit d ifThen otherwise; }; 166 # DNS Settings 167 # https://stalw.art/docs/mta/outbound/dns 168 resolver = { 169 custom = [ 170 "tls://dns11.quad9.net" 171 "tcp://1.1.1.1" 172 ]; 173 concurrency = 2; 174 preserve-intermediates = true; 175 timeout = "5s"; 176 attempts = 3; 177 edns = true; 178 }; 179 report = import ./report.nix { inherit d; }; 180 calendar = import ./calendar.nix; 181 # Authentication 182 auth = import ./auth.nix { inherit ifThen otherwise; }; 183 # Contacts 184 # https://stalw.art/docs/collaboration/contact 185 contacts = { 186 # 512 KiB 187 max-size = 524288; 188 default.href-name = "default"; 189 default.display-name = "Contacts"; 190 }; 191 # Spam Filtering 192 # https://stalw.art/docs/spamfilter/overview 193 spam-filter = { 194 card-is-ham = true; 195 }; 196 }; 197 }; 198 systemd.services.stalwart-mail.serviceConfig = { 199 Restart = lib.mkForce "always"; 200 RestartSec = lib.mkForce 1; 201 }; 202 age.secrets = { 203 stalwart-secret-rsa = smSecret // { 204 file = ../../secrets/stalwart-secret-rsa.age; 205 }; 206 stalwart-secret-ed25519 = smSecret // { 207 file = ../../secrets/stalwart-secret-ed25519.age; 208 }; 209 stalwart-desec-token = smSecret // { 210 file = ../../secrets/stalwart-desec-token.age; 211 }; 212 stalwart-fallback-admin-pw = smSecret // { 213 file = ../../secrets/stalwart-fallback-admin-pw.age; 214 }; 215 }; 216}