|
1 |
| -# This module provides the mailing list definitions for `@nixos.org`. |
| 1 | +# This module makes it easy to define mailing lists in `simple-nixos-mailserver` |
| 2 | +# with a couple of features: |
2 | 3 | #
|
3 |
| -# Simply change the `lists` attribute set below to create new mailing lists or |
4 |
| -# edit membership of existing lists. |
5 |
| -# |
6 |
| -# If you wish to hide your email address, you can encrypt it with SOPS. Just |
7 |
| -# run `nix run .#encrypt-email-address -- --help` and follow the instructions. |
| 4 | +# 1. We can (optionally) encrypt the forward addresses for increase privacy. |
| 5 | +# 2. We can set up a login account for mailing addresses to allow sending |
| 6 | +# email via `SMTP` from those addresses. |
8 | 7 |
|
9 | 8 | { config, lib, ... }:
|
10 | 9 |
|
11 | 10 | let
|
12 |
| - # Mailing lists go here. |
13 |
| - # TODO: replace with the real `nixos.org` mailing lists. |
14 |
| - listsWithSecretFiles = { |
15 |
| - |
16 |
| - |
17 |
| - ../../secrets/jfly-email.umbriel |
18 |
| - |
19 |
| - ]; |
20 |
| - }; |
| 11 | + inherit (lib) types; |
21 | 12 |
|
22 | 13 | fileToSecretId = file: builtins.baseNameOf file;
|
23 | 14 |
|
24 |
| - listsWithSecretPlaceholders = lib.mapAttrs' (name: members: { |
| 15 | + listsWithSecretPlaceholders = lib.mapAttrs' (name: mailingList: { |
25 | 16 | name = name;
|
26 | 17 | value = map (
|
27 | 18 | member:
|
28 | 19 | if builtins.isString member then member else config.sops.placeholder.${fileToSecretId member}
|
29 |
| - ) members; |
30 |
| - }) listsWithSecretFiles; |
| 20 | + ) mailingList.forwardTo; |
| 21 | + }) config.mailing-lists; |
31 | 22 |
|
32 |
| - secretFiles = lib.pipe listsWithSecretFiles [ |
33 |
| - (lib.mapAttrsToList (_name: members: members)) |
| 23 | + secretAddressFiles = lib.pipe config.mailing-lists [ |
| 24 | + (lib.mapAttrsToList (_name: mailingList: mailingList.forwardTo)) |
34 | 25 | lib.flatten
|
35 | 26 | (builtins.filter (member: !builtins.isString member))
|
36 | 27 | ];
|
| 28 | + |
| 29 | + secretPasswordFiles = lib.pipe config.mailing-lists [ |
| 30 | + (lib.filterAttrs (_name: mailingList: mailingList.loginAccount != null)) |
| 31 | + (lib.mapAttrsToList (_name: mailingList: mailingList.loginAccount.encryptedHashedPassword)) |
| 32 | + ]; |
37 | 33 | in
|
38 | 34 |
|
39 | 35 | {
|
40 |
| - # Declare secrets for every secret email in the lists above. |
41 |
| - sops.secrets = builtins.listToAttrs ( |
42 |
| - map (file: { |
43 |
| - name = fileToSecretId file; |
44 |
| - value = { |
45 |
| - format = "binary"; |
46 |
| - sopsFile = file; |
47 |
| - }; |
48 |
| - }) secretFiles |
49 |
| - ); |
| 36 | + options = { |
| 37 | + mailing-lists = lib.mkOption { |
| 38 | + type = types.attrsOf ( |
| 39 | + types.submodule { |
| 40 | + options = { |
| 41 | + forwardTo = lib.mkOption { |
| 42 | + type = types.listOf (types.either types.str types.path); |
| 43 | + description = '' |
| 44 | + Either a plaintext email address, or a path to an email address |
| 45 | + encrypted with `nix run .#encrypt-email address` |
| 46 | + ''; |
| 47 | + }; |
| 48 | + loginAccount = lib.mkOption { |
| 49 | + type = types.nullOr ( |
| 50 | + types.submodule { |
| 51 | + options = { |
| 52 | + encryptedHashedPassword = lib.mkOption { |
| 53 | + type = types.path; |
| 54 | + description = '' |
| 55 | + If specified, this enables sending emails from this address via SMTP. |
| 56 | + Must be a path to encrypted file generated with `nix run .#encrypt-email login` |
| 57 | + ''; |
| 58 | + }; |
| 59 | + }; |
| 60 | + } |
| 61 | + ); |
| 62 | + default = null; |
| 63 | + }; |
| 64 | + }; |
| 65 | + } |
| 66 | + ); |
| 67 | + description = '' |
| 68 | + Mailing lists. Supports both forward-only mailing lists, as well as mailing |
| 69 | + lists that allow sending via SMTP. |
| 70 | + ''; |
| 71 | + }; |
| 72 | + }; |
50 | 73 |
|
51 |
| - sops.templates."postfix-virtual-mailing-lists" = { |
52 |
| - content = lib.concatStringsSep "\n" ( |
53 |
| - lib.mapAttrsToList ( |
54 |
| - name: members: "${name} ${lib.concatStringsSep ", " members}" |
55 |
| - ) listsWithSecretPlaceholders |
| 74 | + config = { |
| 75 | + # Disable IMAP. We don't need it, as we don't store email on this server, we |
| 76 | + # only forward emails. |
| 77 | + mailserver.enableImap = false; |
| 78 | + mailserver.enableImapSsl = false; |
| 79 | + services.dovecot2.enableImap = false; |
| 80 | + |
| 81 | + mailserver.loginAccounts = lib.pipe config.mailing-lists [ |
| 82 | + (lib.filterAttrs (_name: mailingList: mailingList.loginAccount != null)) |
| 83 | + (lib.mapAttrs ( |
| 84 | + _name: mailingList: { |
| 85 | + hashedPasswordFile = |
| 86 | + config.sops.secrets.${fileToSecretId mailingList.loginAccount.encryptedHashedPassword}.path; |
| 87 | + } |
| 88 | + )) |
| 89 | + ]; |
| 90 | + |
| 91 | + # Declare secrets for every secret file. |
| 92 | + sops.secrets = builtins.listToAttrs ( |
| 93 | + (map (file: { |
| 94 | + name = fileToSecretId file; |
| 95 | + value = { |
| 96 | + format = "binary"; |
| 97 | + sopsFile = file; |
| 98 | + }; |
| 99 | + }) secretAddressFiles) |
| 100 | + ++ (map (file: { |
| 101 | + name = fileToSecretId file; |
| 102 | + value = { |
| 103 | + format = "binary"; |
| 104 | + sopsFile = file; |
| 105 | + # Need to restart `dovecot2.service` to trigger `genPasswdScript` in |
| 106 | + # `nixos-mailserver`: |
| 107 | + # https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/blob/af7d3bf5daeba3fc28089b015c0dd43f06b176f2/mail-server/dovecot.nix#L369 |
| 108 | + # This could go away if sops-nix gets support for "input addressed secret |
| 109 | + # paths": https://github.com/Mic92/sops-nix/issues/648 |
| 110 | + restartUnits = [ "dovecot2.service" ]; |
| 111 | + }; |
| 112 | + }) secretPasswordFiles) |
56 | 113 | );
|
57 | 114 |
|
58 |
| - # Need to restart postfix-setup to rerun `postmap` and generate updated `.db` |
59 |
| - # files whenever mailing list membership changes. |
60 |
| - # This could go away if sops-nix gets support for "input addressed secret |
61 |
| - # paths": https://github.com/Mic92/sops-nix/issues/648 |
62 |
| - restartUnits = [ "postfix-setup.service" ]; |
63 |
| - }; |
| 115 | + sops.templates."postfix-virtual-mailing-lists" = { |
| 116 | + content = lib.concatStringsSep "\n" ( |
| 117 | + lib.mapAttrsToList ( |
| 118 | + name: members: "${name} ${lib.concatStringsSep ", " members}" |
| 119 | + ) listsWithSecretPlaceholders |
| 120 | + ); |
| 121 | + |
| 122 | + # Need to restart postfix-setup to rerun `postmap` and generate updated `.db` |
| 123 | + # files whenever mailing list membership changes. |
| 124 | + # This could go away if sops-nix gets support for "input addressed secret |
| 125 | + # paths": https://github.com/Mic92/sops-nix/issues/648 |
| 126 | + restartUnits = [ "postfix-setup.service" ]; |
| 127 | + }; |
64 | 128 |
|
65 |
| - services.postfix.mapFiles.virtual-mailing-lists = |
66 |
| - config.sops.templates."postfix-virtual-mailing-lists".path; |
| 129 | + services.postfix.mapFiles.virtual-mailing-lists = |
| 130 | + config.sops.templates."postfix-virtual-mailing-lists".path; |
67 | 131 |
|
68 |
| - services.postfix.config.virtual_alias_maps = [ "hash:/etc/postfix/virtual-mailing-lists" ]; |
| 132 | + services.postfix.config.virtual_alias_maps = [ "hash:/etc/postfix/virtual-mailing-lists" ]; |
| 133 | + }; |
69 | 134 | }
|
0 commit comments