ctucx.git: nixfiles

ctucx' nixfiles

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 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
{ inputs, pkgs, config, ... }:

let
  mailAutoConfig = ''
    <?xml version="1.0" encoding="UTF-8"?>
    <clientConfig version="1.1">
     <emailProvider id="ctu.cx">
       <domain>ctu.cx</domain>
       <displayName>${config.networking.fqdn}</displayName>
       <displayShortName>${config.networking.domain}</displayShortName>
       <incomingServer type="imap">
         <hostname>${config.networking.fqdn}</hostname>
         <port>993</port>
         <socketType>SSL</socketType>
         <authentication>password-cleartext</authentication>
         <username>%EMAILADDRESS%</username>
       </incomingServer>
       <outgoingServer type="smtp">
         <hostname>${config.networking.fqdn}</hostname>
         <port>465</port>
         <socketType>SSL</socketType>
         <authentication>password-cleartext</authentication>
         <username>%EMAILADDRESS%</username>
       </outgoingServer>
     </emailProvider>
    </clientConfig>
  '';

in {

  imports = [
    inputs.simple-nixos-mailserver.nixosModule
  ];

  age.secrets.restic-mail.file               = ./. + "/../../../secrets/${config.networking.hostName}/restic/mail.age";
  age.secrets.mail-password-katja.file       = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-katja-ctu.cx.age";
  age.secrets.mail-password-gts.file         = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-gts-ctu.cx.age";
  age.secrets.mail-password-gts-zug.file     = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-gts-zuggeschmack.de.age";
  age.secrets.mail-password-info-zug.file    = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-info-zuggeschmack.de.age";
  age.secrets.mail-password-vaultwarden.file = ./. + "/../../../secrets/${config.networking.hostName}/mail/password-vaultwarden-ctu.cx.age";

  dns.zones = with pkgs.dns.lib.combinators; let
    TXT   = [ "v=spf1 a mx ip4:${config.networking.primaryIP4} +ip6:${config.networking.primaryIP} ~all" ];
    DMARC = "v=DMARC1; p=none";
    MX    = with mx; [ (mx 10 "${config.networking.fqdn}.") ];
  in {
    "ctu.cx" = {
      inherit MX TXT;

      SRV = [
        { proto = "tcp"; service = "imaps"; priority = 0; weight = 1; port = 993; target = "${config.networking.fqdn}."; }
        { proto = "tcp"; service = "imap"; priority = 0; weight = 1; port = 143; target = "${config.networking.fqdn}."; }
        { proto = "tcp"; service = "submission"; priority = 0; weight = 1; port = 587; target = "${config.networking.fqdn}."; }
      ];

      subdomains = {
        autoconfig.CNAME         = [ config.networking.hostName ];
        _dmarc.TXT               = [ DMARC ];
        "mail._domainkey".TXT    = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKryfX99NkcU5Xe4AmG+kO/sfuYSXk5RqJhzxS4uMqERE8UszgEGdteXcD8pqON2MfDmA3G6cA+Oa+N4tIWdIYNwTISVXXMGdHvjFIsVUEW0turM104tXESELaPRntkCvDBk/yOgsBDRZQHSx5MdGwpzeRC8TLdCbalh3W0jp5PQIDAQAB" ];
      };
    };

    "ctucx.de" = {
      inherit MX TXT;

      subdomains = {
        _dmarc.TXT               = [ DMARC ];
        "mail._domainkey".TXT    = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5fu690bKYCZLPAFfQQK+nl+aAmtetaWBKCWzGj6pt7HjpFjystgtgnQ6+DZLFXWUp8GRfMEycySB5kQULtYtSMUmx0gQBnTTLsRj+e55/CYUllLV6YXb5uca7LuVhlWPpH3sCr6TvC2VFWe4t0UC3uIXhYPrCm6p8OE7g+TdHHwIDAQAB" ];
      };
    };

    "zuggeschmack.de" = {
      inherit MX TXT;

      subdomains = {
        _dmarc.TXT               = [ DMARC ];
        "mail._domainkey".TXT    = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDf0PX32wWq068cThCnAaX1RJMBiMo6pGfT/VOp9/IzXWmNO2aSyWEFp5lVwYFJnlGX1Sg1uvThICVDiscOqG5jBUAc0gl3SPEBFJ0cqLl7CYhD3Nkvgc8+7zn4huKvFGYXRSDqQm+AL4SSEjZ8hF+N9bGxt0bYu2WlGwZX8mTptwIDAQAB" ];
      };
    };

    "thein.ovh" = {
      inherit MX TXT;

      subdomains = {
        _dmarc.TXT               = [ DMARC ];
        "mail._domainkey".TXT    = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8oumqNkHboF/S4dnKue+hEC3V226ToMmL/fmXqbAhsW88m+jUuLgZE8Nl7kc/lzD9yY7JmCXcWFzoLJWE8xusfmT1yMOW9sQmee7g0tHsm1fVqFMUetmC4+QuqAdvjIGU5QndjdWHP/gssIoLPT7lCNUL4/lkaPmFiiDyvaMpkQIDAQAB" ];
      };
    };

    "flauschehorn.sexy" = {
      inherit MX TXT;

      subdomains = {
        _dmarc.TXT               = [ DMARC ];
        "mail._domainkey".TXT    = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvEPR8068KtlsiWiexSPWqagKmd07ggGvDcYICzOvhxVB0MDrn+/VYIXEbVX0Y9z60oT1ynjkhFjDWEofk11EoXwrg7xjkqZuszDrhdYqUnoLrzlugmnK4jXO3cAD0qeblX0rDmu30cmPP1Aj21tLTU6loYpORY+y4VaVfwtHswwIDAQAB" ];
      };
    };
  };

  security.acme.certs."${config.networking.fqdn}".reloadServices = [
    "postfix.service"
    "dovecot2.service"
  ];

  services.nginx = {
    enable = true;
    virtualHosts = {
      "${config.networking.fqdn}" = {
        enableACME = true;
        forceSSL   = true;
      };

      "autoconfig.ctu.cx" = {
        enableACME = true;
        forceSSL = true;
        locations."= /mail/config-v1.1.xml".return = "200 '${mailAutoConfig}'";
      };
    };
  };

  services.redis.servers.rspamd.bind = "::1";

  services.dovecot2.sieve.extensions = [
    "editheader"
  ];

  mailserver = {
    enable  = true;
    fqdn    = config.networking.fqdn;

    openFirewall        = true;
    localDnsResolver    = false;
    virusScanning       = false;

    redis.address       = "[::1]";

    certificateScheme   = "manual";
    certificateFile     = "${config.security.acme.certs.${config.networking.fqdn}.directory}/fullchain.pem";
    keyFile             = "${config.security.acme.certs.${config.networking.fqdn}.directory}/key.pem";

    enableManageSieve   = true;
    enableSubmission    = true;
    enableSubmissionSsl = true;
    enableImap          = true;
    enableImapSsl       = true;
    enablePop3          = false;
    enablePop3Ssl       = false;

    mailDirectory       = "/var/lib/mailboxes";
    sieveDirectory      = "/var/lib/sieve";
    dkimKeyDirectory    = "/var/lib/dkimKeys";

    domains = [
      "ctu.cx"
      "ctucx.de"
      "thein.ovh"
      "flauschehorn.sexy"
      "zuggeschmack.de"
    ];

    loginAccounts = {
      "katja@ctu.cx" = {
        hashedPasswordFile = config.age.secrets.mail-password-katja.path;
        sieveScript = builtins.readFile ./rules-katja.sieve;
        aliases = [
          "@ctu.cx"
          "@ctucx.de"
          "@thein.ovh"
        ];
      };

      "vaultwarden@ctu.cx" = {
        hashedPasswordFile = config.age.secrets.mail-password-vaultwarden.path;      	
      };

      "gts@ctu.cx" = {
        hashedPasswordFile = config.age.secrets.mail-password-gts.path;
      };

      "gts@zuggeschmack.de" = {
        hashedPasswordFile = config.age.secrets.mail-password-gts-zug.path;
      };

      "info@zuggeschmack.de" = {
        hashedPasswordFile = config.age.secrets.mail-password-info-zug.path;
        aliases = [
          "@zuggeschmack.de"
        ];
      };
    };
  };

  restic-backups.mail = {
    passwordFile = config.age.secrets.restic-mail.path;
    paths        = [
      "/var/lib/mailboxes"
      "/var/lib/dkimKeys"
      "/var/lib/sieve"
    ];
  };

}