aboutsummaryrefslogtreecommitdiff
path: root/modules/private/mail/sympa.nix
blob: ed7e5989d2ba6142012fa7a386f2857863e5dda7 (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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
{ lib, pkgs, config, ... }:
let
  domain = "lists.immae.eu";
  sympaConfig = config.myEnv.mail.sympa;
in
{
  config = lib.mkIf config.myServices.mail.enable {
    services.duplyBackup.profiles.sympa = {
      rootDir = "/var/lib/sympa";
    };
    services.websites.env.tools.vhostConfs.mail = {
      extraConfig = lib.mkAfter [
        ''
          Alias /static-sympa/ /var/lib/sympa/static_content/
          <Directory /var/lib/sympa/static_content/>
            Require all granted
            AllowOverride none
          </Directory>
          <Location /sympa>
            SetHandler "proxy:unix:/run/sympa/wwsympa.socket|fcgi://"
            Require all granted
          </Location>
          ''
      ];
    };

    secrets.keys = [
      {
        dest = "sympa/db_password";
        permissions = "0400";
        group = "sympa";
        user = "sympa";
        text = sympaConfig.postgresql.password;
      }
    ]
    ++ lib.mapAttrsToList (n: v: {
      dest = "sympa/data_sources/${n}.incl"; permissions = "0400"; group = "sympa"; user = "sympa"; text = v;
    }) sympaConfig.data_sources
    ++ lib.mapAttrsToList (n: v: {
      dest = "sympa/scenari/${n}"; permissions = "0400"; group = "sympa"; user = "sympa"; text = v;
    }) sympaConfig.scenari;
    users.users.sympa.extraGroups = [ "keys" ];
    systemd.services.sympa.serviceConfig.SupplementaryGroups = [ "keys" ];
    systemd.services.sympa-archive.serviceConfig.SupplementaryGroups = [ "keys" ];
    systemd.services.sympa-bounce.serviceConfig.SupplementaryGroups = [ "keys" ];
    systemd.services.sympa-bulk.serviceConfig.SupplementaryGroups = [ "keys" ];
    systemd.services.sympa-task.serviceConfig.SupplementaryGroups = [ "keys" ];

    # https://github.com/NixOS/nixpkgs/pull/84202
    systemd.services.sympa.serviceConfig.ProtectKernelModules = lib.mkForce false;
    systemd.services.sympa-archive.serviceConfig.ProtectKernelModules = lib.mkForce false;
    systemd.services.sympa-bounce.serviceConfig.ProtectKernelModules = lib.mkForce false;
    systemd.services.sympa-bulk.serviceConfig.ProtectKernelModules = lib.mkForce false;
    systemd.services.sympa-task.serviceConfig.ProtectKernelModules = lib.mkForce false;
    systemd.services.sympa.serviceConfig.ProtectKernelTunables = lib.mkForce false;
    systemd.services.sympa-archive.serviceConfig.ProtectKernelTunables = lib.mkForce false;
    systemd.services.sympa-bounce.serviceConfig.ProtectKernelTunables = lib.mkForce false;
    systemd.services.sympa-bulk.serviceConfig.ProtectKernelTunables = lib.mkForce false;
    systemd.services.sympa-task.serviceConfig.ProtectKernelTunables = lib.mkForce false;

    systemd.services.wwsympa = {
      wantedBy = [ "multi-user.target" ];
      after = [ "sympa.service" ];
      serviceConfig = {
        Type = "forking";
        PIDFile = "/run/sympa/wwsympa.pid";
        Restart = "always";
        ExecStart = ''${pkgs.spawn_fcgi}/bin/spawn-fcgi \
          -u sympa \
          -g sympa \
          -U wwwrun \
          -M 0600 \
          -F 2 \
          -P /run/sympa/wwsympa.pid \
          -s /run/sympa/wwsympa.socket \
          -- ${pkgs.sympa}/bin/wwsympa.fcgi
        '';
        StateDirectory = "sympa";
        ProtectHome = true;
        ProtectSystem = "full";
        ProtectControlGroups = true;
      };
    };

    services.postfix = {
      mapFiles = {
        sympa_virtual = pkgs.writeText "virtual.sympa" ''
          sympa-request@${domain} postmaster@immae.eu
          sympa-owner@${domain}   postmaster@immae.eu
        '';
        sympa_transport = pkgs.writeText "transport.sympa" ''
          ${domain}                        error:User unknown in recipient table
          sympa@${domain}                  sympa:sympa@${domain}
          listmaster@${domain}             sympa:listmaster@${domain}
          bounce@${domain}                 sympabounce:sympa@${domain}
          abuse-feedback-report@${domain}  sympabounce:sympa@${domain}
        '';
      };
      config = {
        transport_maps = lib.mkAfter [
          "hash:/etc/postfix/sympa_transport"
          "hash:/var/lib/sympa/sympa_transport"
        ];
        virtual_alias_maps = lib.mkAfter [
          "hash:/etc/postfix/sympa_virtual"
        ];
        virtual_mailbox_maps = lib.mkAfter [
          "hash:/etc/postfix/sympa_transport"
          "hash:/var/lib/sympa/sympa_transport"
          "hash:/etc/postfix/sympa_virtual"
        ];
      };
      masterConfig = {
        sympa = {
          type = "unix";
          privileged = true;
          chroot = false;
          command = "pipe";
          args = [
            "flags=hqRu"
            "user=sympa"
            "argv=${pkgs.sympa}/bin/queue"
            "\${nexthop}"
          ];
        };
        sympabounce = {
          type = "unix";
          privileged = true;
          chroot = false;
          command = "pipe";
          args = [
            "flags=hqRu"
            "user=sympa"
            "argv=${pkgs.sympa}/bin/bouncequeue"
            "\${nexthop}"
          ];
        };
      };
    };
    services.sympa = {
      enable = true;
      listMasters = sympaConfig.listmasters;
      mainDomain = domain;
      domains = {
        "${domain}" = {
          webHost = "mail.immae.eu";
          webLocation = "/sympa";
        };
      };

      database = {
        type = "PostgreSQL";
        user = sympaConfig.postgresql.user;
        host = sympaConfig.postgresql.socket;
        name = sympaConfig.postgresql.database;
        passwordFile = config.secrets.fullPaths."sympa/db_password";
        createLocally = false;
      };
      settings = {
        sendmail = "/run/wrappers/bin/sendmail";
        log_smtp = "on";
        sendmail_aliases = "/var/lib/sympa/sympa_transport";
        aliases_program = "${pkgs.postfix}/bin/postmap";
      };
      settingsFile = {
        "virtual.sympa".enable = false;
        "transport.sympa".enable = false;
      } // lib.mapAttrs' (n: v: lib.nameValuePair
        "etc/${domain}/data_sources/${n}.incl"
        { source = config.secrets.fullPaths."sympa/data_sources/${n}.incl"; }) sympaConfig.data_sources
        // lib.mapAttrs' (n: v: lib.nameValuePair
        "etc/${domain}/scenari/${n}"
        { source = config.secrets.fullPaths."sympa/scenari/${n}"; }) sympaConfig.scenari;
      web = {
        server = "none";
      };

      mta = {
        type = "none";
      };
    };
  };
}