about summary refs log tree commit diff
path: root/machines/misc/mailserver.nix
blob: a9548fcb7620f9e62b5c0e25f057205ec2d41e31 (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
{ config, pkgs, lib, ... }: let
  vhostMap = {
    smtpd_sender_login_maps = [
      "SELECT username AS allowedUser"
      "FROM mailbox"
      "WHERE username='%s' AND active = 1"
      "UNION SELECT goto FROM alias"
      "WHERE address='%s' AND active = 1"
    ];

    virtual_alias_maps = [
      "SELECT goto"
      "FROM alias"
      "WHERE address='%s' AND active = '1'"
    ];

    virtual_mailbox_domains = [
      "SELECT domain"
      "FROM domain"
      "WHERE domain='%s' AND active = '1'"
    ];

    virtual_mailbox_maps = [
      "SELECT maildir"
      "FROM mailbox"
      "WHERE username='%s' AND active = '1'"
    ];
  };

  mkDbMap = query: "proxy:pgsql:${pkgs.writeText "database.cf" ''
    hosts = localhost
    user = postfix
    dbname = postfix
    query = ${query}
  ''}";

in {
  services.spamassassin.enable = true;

  services.postfix.enable = true;
  services.postfix.hostname = "mailtest.lan";

  # TODO: This is a dummy, replace it once we know about the real root fs.
  fileSystems."/".label = "root";
  boot.loader.grub.device = "nodev";

  vuizvui.services.postfix.enable = true;
  vuizvui.services.postfix.restrictions = {
    sender = [
      "reject_authenticated_sender_login_mismatch"
      "reject_unknown_sender_domain"
    ];
    recipient = [
      "permit_sasl_authenticated"
      "permit_mynetworks"
      "reject_unauth_destination"
      "reject_invalid_hostname"
      "reject_non_fqdn_hostname"
      "reject_non_fqdn_sender"
      "reject_non_fqdn_recipient"
      "reject_unknown_reverse_client_hostname"
    ];
    helo = [
      "permit_sasl_authenticated"
      "permit_mynetworks"
      "reject_invalid_hostname"
      "reject_unauth_pipelining"
      "reject_non_fqdn_hostname"
    ];
  };

  services.postfix.extraConfig = ''
    ${lib.concatStrings (lib.mapAttrsToList (cfgvar: query: ''
      ${cfgvar} = ${mkDbMap (lib.concatStringsSep " " query)}
    '') vhostMap)}

    # a bit more spam protection
    disable_vrfy_command = yes

    smtpd_sasl_type=dovecot
    smtpd_sasl_path=private/auth_dovecot XXXXXXXXXXXXXXX
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_authenticated_header = yes
    broken_sasl_auth_clients = yes

    proxy_read_maps = ${lib.concatStringsSep " " (map (s: "\$${s}") [
      "local_recipient_maps" "mydestination" "virtual_alias_maps"
      "virtual_alias_domains" "virtual_mailbox_maps" "virtual_mailbox_domains"
      "relay_recipient_maps" "relay_domains" "canonical_maps"
      "sender_canonical_maps" "recipient_canonical_maps" "relocated_maps"
      "transport_maps" "mynetworks" "smtpd_sender_login_maps"
    ])}

    local_transport = virtual
    virtual_transport = dovecot

    virtual_uid_maps = static:5000 XXXXXXXXXXXX
    virtual_gid_maps = static:5000 XXXXXXXXXXXX

    smtpd_tls_cert_file=/etc/ssl/mail.crt XXXX: KEYS
    smtpd_tls_key_file=/etc/ssl/mail.key XXXX: KEYS
    smtpd_use_tls=yes
  '';

  services.postfix.extraMasterConf = ''
    mailman unix - n n - - pipe
      flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ''${nexthop} ''${user}
      # ^^^ FIXME: maybe not needed!

    dovecot unix - n n - - pipe
      flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ''${recipient}
      # ^^^ FIXME: maybe not needed!

    spamassassin unix - n n - - pipe
      user=${toString config.ids.uids.spamd} argv=${pkgs.spamassassin}/bin/spamc -f -e /var/setuid-wrappers/sendmail -oi -f ''${sender} ''${recipient}
      # ^^^ FIXME: maybe not needed!
  '';
}