summaryrefslogtreecommitdiff
path: root/modules/postsrsd.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/postsrsd.nix')
-rw-r--r--modules/postsrsd.nix163
1 files changed, 163 insertions, 0 deletions
diff --git a/modules/postsrsd.nix b/modules/postsrsd.nix
new file mode 100644
index 00000000..bc941e3e
--- /dev/null
+++ b/modules/postsrsd.nix
@@ -0,0 +1,163 @@
1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8
9 cfg = config.services.postsrsd;
10 runtimeDirectoryName = "postsrsd";
11 runtimeDirectory = "/run/${runtimeDirectoryName}";
12 # TODO: follow RFC 42, but we need a libconfuse format first:
13 # https://github.com/NixOS/nixpkgs/issues/401565
14 # Arrays in `libconfuse` look like this: {"Life", "Universe", "Everything"}
15 # See https://www.nongnu.org/confuse/tutorial-html/ar01s03.html.
16 #
17 # Note: We're using `builtins.toJSON` to escape strings, but JSON strings
18 # don't have exactly the same semantics as libconfuse strings. For example,
19 # "${F}" gets treated as an env var reference, see above issue for details.
20 libconfuseDomains = "{ " + lib.concatMapStringsSep ", " builtins.toJSON cfg.domains + " }";
21 configFile = pkgs.writeText "postsrsd.conf" ''
22 secrets-file = "''${CREDENTIALS_DIRECTORY}/secrets-file"
23 domains = ${libconfuseDomains}
24 separator = "${cfg.separator}"
25
26 # Disable postsrsd's jailing in favor of confinement with systemd.
27 unprivileged-user = ""
28 chroot-dir = ""
29
30 ${cfg.extraConfig}
31 '';
32
33in
34{
35 imports =
36 map
37 (
38 name:
39 lib.mkRemovedOptionModule [ "services" "postsrsd" name ] ''
40 `postsrsd` was upgraded to `>= 2.0.0`, with some different behaviors and configuration settings:
41 - NixOS Release Notes: https://nixos.org/manual/nixos/unstable/release-notes#sec-nixpkgs-release-25.05-incompatibilities
42 - NixOS Options Reference: https://nixos.org/manual/nixos/unstable/options#opt-services.postsrsd.enable
43 - Migration instructions: https://github.com/roehling/postsrsd/blob/2.0.10/README.rst#migrating-from-version-1x
44 - Postfix Setup: https://github.com/roehling/postsrsd/blob/2.0.10/README.rst#postfix-setup
45 ''
46 )
47 [
48 "domain"
49 "forwardPort"
50 "reversePort"
51 "timeout"
52 "excludeDomains"
53 ];
54
55 disabledModules = [ "services/mail/postsrsd.nix" ];
56
57 options = {
58 services.postsrsd = {
59 enable = lib.mkOption {
60 type = lib.types.bool;
61 default = false;
62 description = "Whether to enable the postsrsd SRS server for Postfix.";
63 };
64
65 secretsFile = lib.mkOption {
66 type = lib.types.path;
67 default = "/var/lib/postsrsd/postsrsd.secret";
68 description = "Secret keys used for signing and verification";
69 };
70
71 domains = lib.mkOption {
72 type = lib.types.listOf lib.types.str;
73 description = "Domain names for rewrite";
74 default = [ config.networking.hostName ];
75 defaultText = lib.literalExpression "[ config.networking.hostName ]";
76 };
77
78 separator = lib.mkOption {
79 type = lib.types.enum [
80 "-"
81 "="
82 "+"
83 ];
84 default = "=";
85 description = "First separator character in generated addresses";
86 };
87
88 user = lib.mkOption {
89 type = lib.types.str;
90 default = "postsrsd";
91 description = "User for the daemon";
92 };
93
94 group = lib.mkOption {
95 type = lib.types.str;
96 default = "postsrsd";
97 description = "Group for the daemon";
98 };
99
100 extraConfig = lib.mkOption {
101 type = lib.types.lines;
102 default = "";
103 };
104
105 configurePostfix = lib.mkOption {
106 type = lib.types.bool;
107 default = false;
108 description = "noop";
109 };
110 };
111 };
112
113 config = lib.mkIf cfg.enable {
114 users.users = lib.optionalAttrs (cfg.user == "postsrsd") {
115 postsrsd = {
116 group = cfg.group;
117 uid = config.ids.uids.postsrsd;
118 };
119 };
120
121 users.groups = lib.optionalAttrs (cfg.group == "postsrsd") {
122 postsrsd.gid = config.ids.gids.postsrsd;
123 };
124
125 systemd.services.postsrsd-generate-secrets = {
126 path = [ pkgs.coreutils ];
127 script = ''
128 if [ -e "${cfg.secretsFile}" ]; then
129 echo "Secrets file exists. Nothing to do!"
130 else
131 echo "WARNING: secrets file not found, autogenerating!"
132 DIR="$(dirname "${cfg.secretsFile}")"
133 install -m 750 -o ${cfg.user} -g ${cfg.group} -d "$DIR"
134 install -m 600 -o ${cfg.user} -g ${cfg.group} <(dd if=/dev/random bs=18 count=1 | base64) "${cfg.secretsFile}"
135 fi
136 '';
137 serviceConfig = {
138 Type = "oneshot";
139 };
140 };
141
142 systemd.services.postsrsd = {
143 description = "PostSRSd SRS rewriting server";
144 after = [
145 "network.target"
146 "postsrsd-generate-secrets.service"
147 ];
148 before = [ "postfix.service" ];
149 wantedBy = [ "multi-user.target" ];
150 requires = [ "postsrsd-generate-secrets.service" ];
151 confinement.enable = true;
152
153 serviceConfig = {
154 ExecStart = "${lib.getExe pkgs.postsrsd} -C ${configFile}";
155 User = cfg.user;
156 Group = cfg.group;
157 PermissionsStartOnly = true;
158 RuntimeDirectory = runtimeDirectoryName;
159 LoadCredential = "secrets-file:${cfg.secretsFile}";
160 };
161 };
162 };
163}