Maddy: Difference between revisions

imported>Onny
mNo edit summary
Dave (talk | contribs)
m Add alternate way of generating TLSA
 
(20 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[https://maddy.email Maddy] is a composable, modern mail server written in Go. It includes everything required to manage users, inboxes, send and receive mails while supporting all important secure protocols and standards.
[https://maddy.email Maddy] is a composable, modern mail server written in Go. It includes everything required to manage users, inboxes, send and receive mails while supporting all important secure protocols and standards.
{{Warning|Following example describes the usage of an experimental module which is still being reviewed as an [https://github.com/NixOS/nixpkgs/pull/153372 open PR] and might not be ready for production.}}


== Installation ==
== Installation ==
Line 52: Line 50:
   };
   };
   # Enable TLS listeners. Configuring this via the module is not yet
   # Enable TLS listeners. Configuring this via the module is not yet
   # implemented.
   # implemented, see https://github.com/NixOS/nixpkgs/pull/153372
   config = builtins.replaceStrings [
   config = builtins.replaceStrings [
     "imap tcp://0.0.0.0:143"
     "imap tcp://0.0.0.0:143"
Line 62: Line 60:
   # Reading secrets from a file. Do not use this example in production
   # Reading secrets from a file. Do not use this example in production
   # since it stores the keys world-readable in the Nix store.
   # since it stores the keys world-readable in the Nix store.
   secrets = "${pkgs.writeText "secrets" ''
   secrets = [ "${pkgs.writeText "secrets" ''
     GANDI_API_KEY=1234
     GANDI_API_KEY=1234
   ''}";
   ''}" ];
};
};


Line 72: Line 70:
</nowiki>}}
</nowiki>}}


Alternativley certificates can be manually loaded with setting <code>tls.loader = "file";</code> and manually specifiying key and certificates file paths using the <code>tls.certificates = [];</code> option. In this case, more ACME protocols and providers are available when using the native NixOS [[ACME]] module.
Alternativley certificates can be manually loaded with setting <code>tls.loader = "file";</code> and manually specifiying key and certificates file paths using the <code>tls.certificates = [];</code> option. In this case, more ACME protocols and providers are available when using the native NixOS [[ACME]] module or manual client tools like [[Certbot]].


=== DNS records ===
=== DNS records ===
Line 124: Line 122:
Replace the IP <code>1.2.3.4</code> with the IP of your mail server.
Replace the IP <code>1.2.3.4</code> with the IP of your mail server.


=== MTA-STS & DANE ===
=== MTA-STS ===


MTA-STS enforces secure TLS configuration for servers which support this standard. We already advertised this feature in the DNS records above, but we also have to serve a static configuration file using a web server. We use the web server [[Caddy]] to do this but of course you can [[Category:Web_Servers use others too]].
MTA-STS enforces secure TLS configuration for servers which support this standard. We already advertised this feature in the DNS records above, but we also have to serve a static configuration file using a web server. We use the web server [[Caddy]] to do this but of course you can other Web Servers too.


{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
Line 151: Line 149:
Replace the domain <code>mta-sts.example.org</code> and  the domain <code>mx1.example.org</code> with the ones you're using.
Replace the domain <code>mta-sts.example.org</code> and  the domain <code>mx1.example.org</code> with the ones you're using.


Using a TLSA (DANE) record is recommended to bind TLS-certificates to a server. You can generate the key using following command
=== TLSA (DANE) ===
 
Using a TLSA (DANE) record is recommended to bind TLS-certificates to a server. Your nameserver needs DNSSEC support for it. You can generate the key using following command


<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
Line 157: Line 157:
</syntaxhighlight>
</syntaxhighlight>


Your nameserver needs DNSSEC support for it. Add the key to a new TLSA record in your nameserver
Or you can generate it directly from the TLS-certificate that you are using with maddy:<syntaxhighlight lang="console">
# openssl x509 -in cert.pem -pubkey -noout | openssl ec -pubin -outform der | sha256sum
</syntaxhighlight>Add the key to a new TLSA record in your nameserver


{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
Line 173: Line 175:
</syntaxhighlight>
</syntaxhighlight>


=== Managing users and inboxes ===
Check if DNSSEC is working correctly for your new TLSA record
 
<syntaxhighlight lang="console">
# nix shell nixpkgs#dnsutils --command delv _25._tcp.mx1.example.org TLSA @1.1.1.1
; fully validated
_25._tcp.mx1.example.org. 10800 IN TLSA 3 1 1 7f59d873a70e224b184c95a4eb54caa9621e47d48b4a25d312d83d96 e3498238
_25._tcp.mx1.example.org. 10800 IN RRSIG TLSA 13 5 10800 20230601000000 20230511000000 39688 example.org. He9VYZ35xTC3fNo8GJa6swPrZodSnjjIWPG6Th2YbsOEKTV1E8eGtJ2A +eyBd9jgG+B3cA/jw8EJHmpvy/buCw==
</syntaxhighlight>
 
To verify that the TLSA record matches the TLS certificate of the mail server, issue following openssl command
 
<syntaxhighlight lang="console">
# openssl s_client -connect mx1.example.org:25 -starttls smtp -dane_tlsa_domain mx1.example.org -dane_tlsa_rrdata "3 1 1 7f59d873a70e224b184c95a4eb54caa9621e47d48b4a25d312d83d96"
[...]
Verify return code: 0 (ok)
[...]
</syntaxhighlight>
 
Replace the hostnames and the TLSA hash according to your configuration.
 
=== Users and inboxes ===


Creating credentials and inboxes for a specific account. The first command creates the user <code>postmaster@example.org</code> and will prompt for a password.
Creating credentials and inboxes for a specific account. The first command creates the user <code>postmaster@example.org</code> and will prompt for a password.
Line 194: Line 216:
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ options, lib, ... }: {
{ options, lib, ... }: {
services.rspamd.enable = true;


services.maddy.config = builtins.replaceStrings ["msgpipeline local_routing {"] [''msgpipeline local_routing {
services.maddy.config = builtins.replaceStrings ["msgpipeline local_routing {"] [''msgpipeline local_routing {
Line 203: Line 223:
     }
     }
   }''] options.services.maddy.config.default;
   }''] options.services.maddy.config.default;
services.rspamd = {
  enable = true;
  locals."dkim_signing.conf".text = ''
    selector = "default";
    domain = "project-insanity.org";
    path = "/var/lib/maddy/dkim_keys/$domain_$selector.key";
  '';
};
systemd.services.rspamd.serviceConfig.SupplementaryGroups = [ "maddy" ];


[...]
[...]
Line 209: Line 240:
The second part in this example replaces a part in the default config of the Maddy module and inserts the rspamd check to the message pipeline as described in the [https://maddy.email/reference/checks/rspamd upstream documentation].
The second part in this example replaces a part in the default config of the Maddy module and inserts the rspamd check to the message pipeline as described in the [https://maddy.email/reference/checks/rspamd upstream documentation].


== Tipps & tricks ==
The [[rspamd]] article also has some notes on how to achieve training for spam/ham mails using an additional helper script.
 
=== Mail attachement size ===
 
The default max mail attachement size is set to 32MB, for a higher value (in this case 64MB) change the default configuration via this workaround
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ options, lib, ... }: {
 
services.maddy.config = builtins.replaceStrings [
  "dmarc yes"
] [
  ''dmarc yes
  max_message_size 64M''] options.services.maddy.config.default;
 
[...]
</nowiki>}}
 
=== Alias addresses ===
 
The following example will add an alias <code>mailA@example.org</code> for the local mail address <code>mailB@example.org</code> meaning that every mail send to <code>mailA</code> will get delivered to <code>mailB</code>.
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ options, lib, ... }: {
 
services.maddy.config = builtins.replaceStrings [
  "optional_step file /etc/maddy/aliases"
] [
  "optional_step static {
    entry mailA@example.org mailB@example.org
  }"] options.services.maddy.config.default;
 
[...]
</nowiki>}}
 
== Tips & tricks ==


=== Test mail server ===
=== Test mail server ===
Line 264: Line 330:


Of course autoconfig.example.org domain should point to your server running the SSL enabled web service.
Of course autoconfig.example.org domain should point to your server running the SSL enabled web service.
== Troubleshooting ==
=== TLS it not available or unauthenticated but required ===
This error occurs if the receiving mail server has a invalid or none TLS configuration. The default configuration of Maddy enforces a valid TLS connection to the remote server for delivery. If you want to disable this default policy, apply following configuration hack
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ options, lib, ... }: {
services.maddy.config = builtins.replaceStrings [
  "min_tls_level encrypted"
] [
  "min_tls_level none"] options.services.maddy.config.default;
[...]
</nowiki>}}


== See also ==
== See also ==
* [https://maddy.email Maddy homepage and documentation]
* [https://maddy.email Maddy homepage and documentation]
* [[Stalwart]], an open-source, all-in-one mail server solution that supports JMAP, IMAP4, and SMTP protocols
* [https://nixos-mailserver.readthedocs.io/en/latest Simple NixOS Mailserver]
* [[Imapsync]], useful tool to migrate mailboxes to a new server


[[Category:Mail Server]]
[[Category:Mail Server]]
[[Category:Server]]