1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.opendkim;
8
9 defaultSock = "local:/run/opendkim/opendkim.sock";
10
11 keyFile = "${cfg.keyPath}/${cfg.selector}.private";
12
13 args = [ "-f" "-l"
14 "-p" cfg.socket
15 "-d" cfg.domains
16 "-k" keyFile
17 "-s" cfg.selector
18 ] ++ optionals (cfg.configFile != null) [ "-x" cfg.configFile ];
19
20in {
21
22 ###### interface
23
24 options = {
25
26 services.opendkim = {
27
28 enable = mkOption {
29 type = types.bool;
30 default = false;
31 description = "Whether to enable the OpenDKIM sender authentication system.";
32 };
33
34 socket = mkOption {
35 type = types.str;
36 default = defaultSock;
37 description = "Socket which is used for communication with OpenDKIM.";
38 };
39
40 user = mkOption {
41 type = types.str;
42 default = "opendkim";
43 description = "User for the daemon.";
44 };
45
46 group = mkOption {
47 type = types.str;
48 default = "opendkim";
49 description = "Group for the daemon.";
50 };
51
52 domains = mkOption {
53 type = types.str;
54 default = "csl:${config.networking.hostName}";
55 example = "csl:example.com,mydomain.net";
56 description = ''
57 Local domains set (see <literal>opendkim(8)</literal> for more information on datasets).
58 Messages from them are signed, not verified.
59 '';
60 };
61
62 keyPath = mkOption {
63 type = types.path;
64 description = ''
65 The path that opendkim should put its generated private keys into.
66 The DNS settings will be found in this directory with the name selector.txt.
67 '';
68 default = "/var/lib/opendkim/keys";
69 };
70
71 selector = mkOption {
72 type = types.str;
73 description = "Selector to use when signing.";
74 };
75
76 configFile = mkOption {
77 type = types.nullOr types.path;
78 default = null;
79 description = "Additional opendkim configuration.";
80 };
81
82 };
83
84 };
85
86
87 ###### implementation
88
89 config = mkIf cfg.enable {
90
91 users.users = optionalAttrs (cfg.user == "opendkim") (singleton
92 { name = "opendkim";
93 group = cfg.group;
94 uid = config.ids.uids.opendkim;
95 });
96
97 users.groups = optionalAttrs (cfg.group == "opendkim") (singleton
98 { name = "opendkim";
99 gid = config.ids.gids.opendkim;
100 });
101
102 environment.systemPackages = [ pkgs.opendkim ];
103
104 systemd.services.opendkim = {
105 description = "OpenDKIM signing and verification daemon";
106 after = [ "network.target" ];
107 wantedBy = [ "multi-user.target" ];
108
109 preStart = ''
110 mkdir -p "${cfg.keyPath}"
111 cd "${cfg.keyPath}"
112 if ! test -f ${cfg.selector}.private; then
113 ${pkgs.opendkim}/bin/opendkim-genkey -s ${cfg.selector} -d all-domains-generic-key
114 echo "Generated OpenDKIM key! Please update your DNS settings:\n"
115 echo "-------------------------------------------------------------"
116 cat ${cfg.selector}.txt
117 echo "-------------------------------------------------------------"
118 fi
119 chown ${cfg.user}:${cfg.group} ${cfg.selector}.private
120 '';
121
122 serviceConfig = {
123 ExecStart = "${pkgs.opendkim}/bin/opendkim ${escapeShellArgs args}";
124 User = cfg.user;
125 Group = cfg.group;
126 RuntimeDirectory = optional (cfg.socket == defaultSock) "opendkim";
127 PermissionsStartOnly = true;
128 };
129 };
130
131 };
132}