2 inputs.secrets.url = "path:../../secrets";
3 inputs.environment.url = "path:../environment";
4 inputs.files-watcher.url = "path:../../files-watcher";
5 inputs.opendmarc.url = "path:../../opendmarc";
6 inputs.openarc.url = "path:../../openarc";
7 outputs = { self, secrets, environment, opendmarc, openarc, files-watcher }: {
8 nixosModule = self.nixosModules.milters;
9 nixosModules.milters = { lib, pkgs, config, nodes, ... }:
13 environment.nixosModule
14 files-watcher.nixosModule
18 options.myServices.mail.milters.enable = lib.mkEnableOption "enable Mail milters";
19 options.myServices.mail.milters.sockets = lib.mkOption {
20 type = lib.types.attrsOf lib.types.path;
22 opendkim = "/run/opendkim/opendkim.sock";
23 opendmarc = config.services.opendmarc.socket;
24 openarc = config.services.openarc.socket;
31 config = lib.mkIf config.myServices.mail.milters.enable {
35 user = config.services.opendkim.user;
36 group = config.services.opendkim.group;
39 "opendkim/eldiron.private" = {
40 user = config.services.opendkim.user;
41 group = config.services.opendkim.group;
43 text = config.myEnv.mail.dkim.eldiron.private;
46 users.users."${config.services.opendkim.user}".extraGroups = [ "keys" ];
49 socket = "local:${config.myServices.mail.milters.sockets.opendkim}";
52 getDomains = p: lib.mapAttrsToList (n: v: v.fqdn) p.emailPolicies;
53 bydomain = builtins.mapAttrs (n: getDomains) nodes.eldiron.config.myServices.dns.zones;
54 domains' = lib.flatten (builtins.attrValues bydomain);
56 builtins.concatStringsSep "," domains';
57 keyPath = config.secrets.fullPaths."opendkim";
59 configFile = pkgs.writeText "opendkim.conf" ''
64 group = config.services.postfix.group;
66 systemd.services.opendkim.serviceConfig.Slice = "mail.slice";
67 systemd.services.opendkim.preStart = lib.mkBefore ''
68 # Skip the prestart script as keys are handled in secrets
71 services.filesWatcher.opendkim = {
74 config.secrets.fullPaths."opendkim/eldiron.private"
78 systemd.services.milter_verify_from = {
79 description = "Verify from milter";
80 after = [ "network.target" ];
81 wantedBy = [ "multi-user.target" ];
88 pymilter = with pkgs.python38Packages; buildPythonPackage rec {
92 inherit pname version;
93 sha256 = "1bpcvq7d72q0zi7c8h5knhasywwz9gxc23n9fxmw874n5k8hsn7k";
96 buildInputs = [ pkgs.libmilter ];
98 python = pkgs.python38.withPackages (p: [ pymilter ]);
99 in "${python}/bin/python ${./verify_from.py} -s /run/milter_verify_from/verify_from.sock";
100 RuntimeDirectory = "milter_verify_from";