aboutsummaryrefslogtreecommitdiff
path: root/modules/private/mail/milters.nix
blob: 5de03cf12dcb04152579f01ffa5e7a4c7823fbe5 (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
{ lib, pkgs, config, ... }:
{
  options.myServices.mail.milters.sockets = lib.mkOption {
    type = lib.types.attrsOf lib.types.path;
    default = {
      opendkim = "/run/opendkim/opendkim.sock";
      opendmarc = "/run/opendmarc/opendmarc.sock";
      openarc = "/run/openarc/openarc.sock";
    };
    readOnly = true;
    description = ''
      milters sockets
      '';
  };
  config = lib.mkIf (config.myServices.mail.enable || config.myServices.mailBackup.enable) {
    secrets.keys = [
      {
        dest = "opendkim/eldiron.private";
        user = config.services.opendkim.user;
        group = config.services.opendkim.group;
        permissions = "0400";
        text = config.myEnv.mail.dkim.eldiron.private;
      }
      {
        dest = "opendkim/eldiron.txt";
        user = config.services.opendkim.user;
        group = config.services.opendkim.group;
        permissions = "0444";
        text = ''
          eldiron._domainkey	IN	TXT	${config.myEnv.mail.dkim.eldiron.public}'';
      }
      {
        dest = "opendmarc/ignore.hosts";
        user = config.services.opendmarc.user;
        group = config.services.opendmarc.group;
        permissions = "0400";
        text = let
          mxes = lib.attrsets.filterAttrs
            (n: v: v.mx.enable)
            config.myEnv.servers;
          in
            builtins.concatStringsSep "\n" ([
              config.myEnv.mail.dmarc.ignore_hosts
            ] ++ lib.mapAttrsToList (n: v: v.fqdn) mxes);
      }
    ];
    users.users."${config.services.opendkim.user}".extraGroups = [ "keys" ];
    services.opendkim = {
      enable = true;
      socket = "local:${config.myServices.mail.milters.sockets.opendkim}";
      domains = builtins.concatStringsSep "," (lib.flatten (map
        (zone: map
          (e: "${e.domain}${lib.optionalString (e.domain != "") "."}${zone.name}")
          (zone.withEmail or [])
        )
        config.myEnv.dns.masterZones
      ));
      keyPath = "${config.secrets.location}/opendkim";
      selector = "eldiron";
      configFile = pkgs.writeText "opendkim.conf" ''
        SubDomains        yes
        UMask             002
        AlwaysAddARHeader yes
        '';
      group = config.services.postfix.group;
    };
    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"
      ];
    };

    users.users."${config.services.opendmarc.user}".extraGroups = [ "keys" ];
    services.opendmarc = {
      enable = true;
      socket = "local:${config.myServices.mail.milters.sockets.opendmarc}";
      configFile = pkgs.writeText "opendmarc.conf" ''
        AuthservID                  HOSTNAME
        FailureReports              false
        FailureReportsBcc           postmaster@immae.eu
        FailureReportsOnNone        true
        FailureReportsSentBy        postmaster@immae.eu
        IgnoreAuthenticatedClients  true
        IgnoreHosts                 ${config.secrets.fullPaths."opendmarc/ignore.hosts"}
        SoftwareHeader              true
        SPFIgnoreResults            true
        SPFSelfValidate             true
        UMask                       002
        '';
      group = config.services.postfix.group;
    };
    services.filesWatcher.opendmarc = {
      restart = true;
      paths = [
        config.secrets.fullPaths."opendmarc/ignore.hosts"
      ];
    };

    services.openarc = {
      enable = true;
      user = "opendkim";
      socket = "local:${config.myServices.mail.milters.sockets.openarc}";
      group = config.services.postfix.group;
      configFile = pkgs.writeText "openarc.conf" ''
        AuthservID              mail.immae.eu
        Domain                  mail.immae.eu
        KeyFile                 ${config.secrets.fullPaths."opendkim/eldiron.private"}
        Mode                    sv
        Selector                eldiron
        SoftwareHeader          yes
        Syslog                  Yes
        '';
    };
    systemd.services.openarc.postStart = lib.optionalString
          (lib.strings.hasPrefix "local:" config.services.openarc.socket) ''
      while [ ! -S ${lib.strings.removePrefix "local:" config.services.openarc.socket} ]; do
        sleep 0.5
      done
      chmod g+w ${lib.strings.removePrefix "local:" config.services.openarc.socket}
      '';
    services.filesWatcher.openarc = {
      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 = {
        User = "postfix";
        Group = "postfix";
        ExecStart = let python = pkgs.python3.withPackages (p: [ p.pymilter ]);
          in "${python}/bin/python ${./verify_from.py} -s /run/milter_verify_from/verify_from.sock";
        RuntimeDirectory = "milter_verify_from";
      };
    };
  };
}