9 cfg = config.services.opendkim;
11 defaultSock = "local:/run/opendkim/opendkim.sock";
22 "${cfg.keyPath}/${cfg.selector}.private"
26 ++ lib.optionals (cfg.configFile != null) [
31 configFile = pkgs.writeText "opendkim.conf" (
32 lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name} ${value}") cfg.settings)
37 (lib.mkRenamedOptionModule [ "services" "opendkim" "keyFile" ] [ "services" "opendkim" "keyPath" ])
42 enable = lib.mkEnableOption "OpenDKIM sender authentication system";
44 socket = lib.mkOption {
46 default = defaultSock;
47 description = "Socket which is used for communication with OpenDKIM.";
53 description = "User for the daemon.";
56 group = lib.mkOption {
59 description = "Group for the daemon.";
62 domains = lib.mkOption {
64 default = "csl:${config.networking.hostName}";
65 defaultText = lib.literalExpression ''"csl:''${config.networking.hostName}"'';
66 example = "csl:example.com,mydomain.net";
68 Local domains set (see `opendkim(8)` for more information on datasets).
69 Messages from them are signed, not verified.
73 keyPath = lib.mkOption {
74 type = lib.types.path;
76 The path that opendkim should put its generated private keys into.
77 The DNS settings will be found in this directory with the name selector.txt.
79 default = "/var/lib/opendkim/keys";
82 selector = lib.mkOption {
84 description = "Selector to use when signing.";
87 # TODO: deprecate this?
88 configFile = lib.mkOption {
89 type = lib.types.nullOr lib.types.path;
91 description = "Additional opendkim configuration as a file.";
94 settings = lib.mkOption {
98 freeformType = attrsOf str;
101 description = "Additional opendkim configuration";
106 config = lib.mkIf cfg.enable {
107 users.users = lib.optionalAttrs (cfg.user == "opendkim") {
110 uid = config.ids.uids.opendkim;
114 users.groups = lib.optionalAttrs (cfg.group == "opendkim") {
115 opendkim.gid = config.ids.gids.opendkim;
119 etc = lib.mkIf (cfg.settings != { }) {
120 "opendkim/opendkim.conf".source = configFile;
122 systemPackages = [ pkgs.opendkim ];
125 services.opendkim.configFile = lib.mkIf (cfg.settings != { }) configFile;
127 systemd.tmpfiles.rules = [
128 "d '${cfg.keyPath}' - ${cfg.user} ${cfg.group} - -"
131 systemd.services.opendkim = {
132 description = "OpenDKIM signing and verification daemon";
133 after = [ "network.target" ];
134 wantedBy = [ "multi-user.target" ];
138 if ! test -f ${cfg.selector}.private; then
139 ${pkgs.opendkim}/bin/opendkim-genkey -s ${cfg.selector} -d all-domains-generic-key
140 echo "Generated OpenDKIM key! Please update your DNS settings:\n"
141 echo "-------------------------------------------------------------"
142 cat ${cfg.selector}.txt
143 echo "-------------------------------------------------------------"
148 ExecStart = "${pkgs.opendkim}/bin/opendkim ${lib.escapeShellArgs args}";
151 RuntimeDirectory = lib.optional (cfg.socket == defaultSock) "opendkim";
152 StateDirectory = "opendkim";
153 StateDirectoryMode = "0700";
154 ReadWritePaths = [ cfg.keyPath ];
156 AmbientCapabilities = [ ];
157 CapabilityBoundingSet = "";
158 DevicePolicy = "closed";
159 LockPersonality = true;
160 MemoryDenyWriteExecute = true;
161 NoNewPrivileges = true;
162 PrivateDevices = true;
163 PrivateMounts = true;
167 ProtectControlGroups = true;
169 ProtectHostname = true;
170 ProtectKernelLogs = true;
171 ProtectKernelModules = true;
172 ProtectKernelTunables = true;
173 ProtectSystem = "strict";
175 RestrictAddressFamilies = [
179 RestrictNamespaces = true;
180 RestrictRealtime = true;
181 RestrictSUIDSGID = true;
182 SystemCallArchitectures = "native";
185 "~@privileged @resources"