{ config, lib, pkgs, ... }: let inherit (lib.modules) mkIf mkForce; inherit (lib.trivial) flip; inherit (lib.strings) optionalString escapeShellArgs; inherit (builtins) toFile concatStringsSep; mailConfig = config.services.mailserver; opendkimConfig = config.services.opendkim; opendkimArgs = ["-f" "-l" "-x" opendkimConfig.configFile]; dkimUser = opendkimConfig.user; dkimGroup = opendkimConfig.group; keyDir = mailConfig.dkim.directory; selector = "mail"; inherit (mailConfig) domains; createDomainDkimCert = dom: let dkimKey = "${keyDir}/${dom}.${selector}.key"; dkimDNSFile = "${keyDir}/${dom}.${selector}.txt"; in '' if [ ! -f "${dkimKey}" ] then ${pkgs.opendkim}/bin/opendkim-genkey -s "${selector}" \ -d "${dom}" \ --bits="1024" \ --directory="${keyDir}" mv "${keyDir}/${selector}.private" "${dkimKey}" mv "${keyDir}/${selector}.txt" "${dkimDNSFile}" echo "Generated key for domain ${dom} selector ${selector}" fi ''; createAllCerts = concatStringsSep "\n" (map createDomainDkimCert mailConfig.domains); keyTable = toFile "opendkim-KeyTable" (concatStringsSep "\n" (flip map domains (dom: "${dom} ${dom}:${selector}:${keyDir}/${dom}.${selector}.key"))); signingTable = toFile "opendkim-SigningTable" (concatStringsSep "\n" (flip map domains (dom: "${dom} ${dom}"))); in { config = mkIf (mailConfig.enable && mailConfig.dkim.enable) { services.opendkim = { enable = true; inherit selector; keyPath = keyDir; domains = "csl:${concatStringsSep "," domains}"; configFile = toFile "opendkim.conf" ('' Canonicalization relaxed/relaxed UMask 0002 Socket ${opendkimConfig.socket} KeyTable file:${keyTable} SigningTable file:${signingTable} '' + (optionalString mailConfig.debugMode '' Syslog yes SyslogSuccess yes LogWhy yes '')); }; systemd.tmpfiles.rules = ["d '${keyDir}' - ${dkimUser} ${dkimGroup} - -"]; users.users.postfix.extraGroups = ["${dkimGroup}"]; systemd.services.opendkim = { preStart = mkForce createAllCerts; serviceConfig = { ExecStart = mkForce "${pkgs.opendkim}/bin/opendkim ${escapeShellArgs opendkimArgs}"; PermissionsStartOnly = mkForce false; }; }; }; }