aboutsummaryrefslogtreecommitdiff
path: root/flakes/private/milters/flake.nix
blob: c4de5b6c0a6b3186ad6b06b36f95827983c73f48 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
{
  inputs.secrets.url = "path:../../secrets";
  inputs.environment.url = "path:../environment";
  inputs.files-watcher.url = "path:../../files-watcher";
  inputs.opendmarc.url = "path:../../opendmarc";
  inputs.openarc.url = "path:../../openarc";
  outputs = { self, secrets, environment, opendmarc, openarc, files-watcher }: {
    nixosModule = self.nixosModules.milters;
    nixosModules.milters = { lib, pkgs, config, nodes, ... }:
      {
        imports = [
          secrets.nixosModule
          environment.nixosModule
          files-watcher.nixosModule
          opendmarc.nixosModule
          openarc.nixosModule
        ];
        options.myServices.mail.milters.enable = lib.mkEnableOption "enable Mail milters";
        options.myServices.mail.milters.sockets = lib.mkOption {
          type = lib.types.attrsOf lib.types.path;
          default = {
            opendkim = "/run/opendkim/opendkim.sock";
            opendmarc = config.services.opendmarc.socket;
            openarc = config.services.openarc.socket;
          };
          readOnly = true;
          description = ''
            milters sockets
            '';
        };
        config = lib.mkIf config.myServices.mail.milters.enable {
          secrets.keys = {
            "opendkim" = {
              isDir = true;
              user = config.services.opendkim.user;
              group = config.services.opendkim.group;
              permissions = "0550";
            };
            "opendkim/eldiron.private" = {
              user = config.services.opendkim.user;
              group = config.services.opendkim.group;
              permissions = "0400";
              text = config.myEnv.mail.dkim.eldiron.private;
            };
          };
          users.users."${config.services.opendkim.user}".extraGroups = [ "keys" ];
          services.opendkim = {
            enable = true;
            socket = "local:${config.myServices.mail.milters.sockets.opendkim}";
            domains =
              let
                getDomains = p: lib.mapAttrsToList (n: v: v.fqdn) p.emailPolicies;
                bydomain = builtins.mapAttrs (n: getDomains) nodes.eldiron.config.myServices.dns.zones;
                domains' = lib.flatten (builtins.attrValues bydomain);
              in
                builtins.concatStringsSep "," domains';
            keyPath = config.secrets.fullPaths."opendkim";
            selector = "eldiron";
            configFile = pkgs.writeText "opendkim.conf" ''
              SubDomains        yes
              UMask             002
              AlwaysAddARHeader yes
              '';
            group = config.services.postfix.group;
          };
          systemd.services.opendkim.serviceConfig.Slice = "mail.slice";
          systemd.services.opendkim.preStart = lib.mkBefore ''
            # Skip the prestart script as keys are handled in secrets
            exit 0
            '';
          services.filesWatcher.opendkim = {
            restart = true;
            paths = [
              config.secrets.fullPaths."opendkim/eldiron.private"
            ];
          };

          systemd.services.milter_verify_from = {
            description  = "Verify from milter";
            after = [ "network.target" ];
            wantedBy = [ "multi-user.target" ];

            serviceConfig = {
              Slice = "mail.slice";
              User = "postfix";
              Group = "postfix";
              ExecStart = let
                pymilter = with pkgs.python38Packages; buildPythonPackage rec {
                  pname = "pymilter";
                  version = "1.0.4";
                  src = fetchPypi {
                    inherit pname version;
                    sha256 = "1bpcvq7d72q0zi7c8h5knhasywwz9gxc23n9fxmw874n5k8hsn7k";
                  };
                  doCheck = false;
                  buildInputs = [ pkgs.libmilter ];
                };
                python = pkgs.python38.withPackages (p: [ pymilter ]);
              in "${python}/bin/python ${./verify_from.py} -s /run/milter_verify_from/verify_from.sock";
              RuntimeDirectory = "milter_verify_from";
            };
          };
        };
      };
  };
}