This repository has no description
5.5 kB
200 lines
1{
2 self,
3 config,
4 lib,
5 pkgs,
6 ...
7}:
8let
9 relayHosts = map (host: host.nets.retiolum.ip6.addr) [
10 config.krebs.hosts.aergia
11 config.krebs.hosts.ignavia
12 config.krebs.hosts.coaxmetal
13 config.krebs.hosts.green
14 config.krebs.hosts.mors
15 ];
16
17 mynetworks = map (ip: "[${ip}]") relayHosts;
18in
19{
20 imports = [
21 self.inputs.nixos-mailserver.nixosModules.default
22 ];
23
24 mailserver = {
25 enable = true;
26 fqdn = "mail.lassul.us";
27 domains = [ "lassul.us" ];
28
29 loginAccounts = {
30 "lass@lassul.us" = {
31 hashedPasswordFile =
32 config.clan.core.vars.generators.mailserver-lass.files."lass-mail-password-hash".path;
33 aliases = [
34 "postmaster@lassul.us"
35 "root@lassul.us"
36 "abuse@lassul.us"
37 "hostmaster@lassul.us"
38 "webmaster@lassul.us"
39 "security@lassul.us"
40 "noc@lassul.us"
41 "mailer-daemon@lassul.us"
42 "nobody@lassul.us"
43 "lassulus@lassul.us"
44 ];
45 catchAll = [ "lassul.us" ];
46 };
47 "bot@lassul.us" = {
48 hashedPasswordFile =
49 config.clan.core.vars.generators.mailserver-bot.files."bot-mail-password-hash".path;
50 };
51 };
52
53 # TLS via existing ACME cert
54 x509.useACMEHost = "mail.lassul.us";
55
56 # DKIM — auto-managed by module
57 dkimSigning = true;
58 dkimSelector = "mail";
59
60 # ManageSieve: lets mail clients manage sieve rules dynamically (port 4190)
61 enableManageSieve = true;
62
63 # Full-text search for IMAP clients
64 fullTextSearch = {
65 enable = true;
66 memoryLimit = 500;
67 };
68
69 stateVersion = 3;
70 };
71
72 # Password generation for mail accounts
73 clan.core.vars.generators.mailserver-lass = {
74 files."lass-mail-password" = { };
75 files."lass-mail-password-hash" = { };
76 runtimeInputs = with pkgs; [
77 coreutils
78 mkpasswd
79 pwgen
80 ];
81 script = ''
82 pwgen -s 32 1 > "$out/lass-mail-password"
83 mkpasswd -sm bcrypt < "$out/lass-mail-password" > "$out/lass-mail-password-hash"
84 '';
85 };
86
87 clan.core.vars.generators.mailserver-bot = {
88 files."bot-mail-password" = { };
89 files."bot-mail-password-hash" = { };
90 runtimeInputs = with pkgs; [
91 coreutils
92 mkpasswd
93 pwgen
94 ];
95 script = ''
96 pwgen -s 32 1 > "$out/bot-mail-password"
97 mkpasswd -sm bcrypt < "$out/bot-mail-password" > "$out/bot-mail-password-hash"
98 '';
99 };
100
101 # Retiolum relay: allow krebs hosts to relay through postfix
102 services.postfix.settings.main.mynetworks = lib.mkForce (
103 [
104 "127.0.0.0/8"
105 "[::1]/128"
106 ]
107 ++ mynetworks
108 );
109
110 # ACME cert — reuse existing setup
111 security.acme.certs."mail.lassul.us" = {
112 group = "lasscert";
113 webroot = "/var/lib/acme/acme-challenge";
114 };
115 users.groups.lasscert.members = [
116 "dovecot2"
117 "postfix"
118 "nginx"
119 ];
120
121 # Firewall: SMTP(25), submission(587), submissions(465), IMAPS(993), ManageSieve(4190)
122 networking.firewall.allowedTCPPorts = [
123 25
124 587
125 465
126 993
127 4190
128 ];
129
130 # muchsync: lass user needs access to vmail for notmuch/muchsync
131 users.groups.virtualMail.members = [ "lass" ];
132 systemd.tmpfiles.rules = [
133 "L+ /home/lass/Maildir - - - - /var/vmail/lassul.us/lass/mail"
134 # dovecot pre-start sets /var/vmail to 02770 already; just fix subdirs
135 "z /var/vmail/lassul.us 2770 virtualMail virtualMail -"
136 "z /var/vmail/lassul.us/lass 2770 virtualMail virtualMail -"
137 "Z /var/vmail/lassul.us/lass/mail 2770 virtualMail virtualMail -"
138 ];
139
140 # Thunderbird autoconfig
141 services.nginx.virtualHosts."autoconfig.lassul.us" = {
142 forceSSL = true;
143 enableACME = true;
144 locations."= /mail/config-v1.1.xml".extraConfig = ''
145 default_type application/xml;
146 return 200 '<?xml version="1.0" encoding="UTF-8"?>
147 <clientConfig version="1.1">
148 <emailProvider id="lassul.us">
149 <domain>lassul.us</domain>
150 <displayName>lassul.us Mail</displayName>
151 <displayShortName>lassul.us</displayShortName>
152 <incomingServer type="imap">
153 <hostname>mail.lassul.us</hostname>
154 <port>993</port>
155 <socketType>SSL</socketType>
156 <authentication>password-cleartext</authentication>
157 <username>%EMAILADDRESS%</username>
158 </incomingServer>
159 <outgoingServer type="smtp">
160 <hostname>mail.lassul.us</hostname>
161 <port>465</port>
162 <socketType>SSL</socketType>
163 <authentication>password-cleartext</authentication>
164 <username>%EMAILADDRESS%</username>
165 </outgoingServer>
166 </emailProvider>
167 </clientConfig>';
168 '';
169 };
170
171 # Dovecot virtual mailbox: "Unread" shows all unseen messages across all folders
172 services.dovecot2.mailPlugins.globally.enable = [ "virtual" ];
173 services.dovecot2.extraConfig =
174 let
175 virtualDir = pkgs.linkFarm "dovecot-virtual" [
176 {
177 name = "Unread/dovecot-virtual";
178 path = pkgs.writeText "dovecot-virtual-unread" "*\n unseen\n";
179 }
180 ];
181 in
182 ''
183 namespace virtual {
184 prefix = virtual.
185 separator = .
186 location = virtual:${virtualDir}:INDEX=/var/vmail/virtual-indexes/%u
187 subscriptions = no
188 mailbox Unread {
189 auto = subscribe
190 }
191 }
192 '';
193
194 # notmuch + muchsync + msmtp for CLI mail access
195 environment.systemPackages = [
196 self.packages.${pkgs.system}.notmuch
197 pkgs.muchsync
198 pkgs.msmtp
199 ];
200}