Maddy: Difference between revisions

imported>Onny
Add note on how to change Maddy passwords
Onny (talk | contribs)
No edit summary
 
(38 intermediate revisions by 5 users not shown)
Line 3: Line 3:
== Installation ==
== Installation ==


{{Warning|Following example describes the usage of an experimental module which is still being reviewed as an open PR and might not be ready for production.}}
The following example enables the Maddy mail server on localhost, listening on mail delivery SMTP/Submission ports (<code>25,  587</code>) and IMAP port (<code>143</code>) for mail clients to connect to. Mailboxes for the accounts <code>postmaster@example.org</code> and <code>user1@example.org</code> get created if they don't exist yet.


The following example enables the Maddy mail server listening on mail delivery SMTP/Submission ports (<code>25,  587</code>) and IMAP/IMAPS ports (<code>143/993</code>) for mail clients to connect to. The server is configured to send and receive mails for the primary domain <code>example.org</code>.
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
services.maddy = {
  enable = true;
  primaryDomain = "localhost";
  ensureAccounts = [
    "user1@example.org"
    "postmaster@example.org"
  ];
  ensureCredentials = {
    # Do not use this in production. This will make passwords world-readable
    # in the Nix store
    "user1@example.org".passwordFile = "${pkgs.writeText "postmaster" "test"}";
    "postmaster@example.org".passwordFile = "${pkgs.writeText "postmaster" "test"}";
  };
};
</nowiki>}}
 
This local test setup doesn't provide secure TLS connections and should be used only for testing purpose.
 
== Configuration ==
 
=== TLS ===
 
The following example changes the hostname for the mail server to the public domain <code>example.org</code>. TLS certificates are obtained using using the ACME dns-01 challenge. This requires API access to your domain provider. See [https://maddy.email/reference/tls-acme/ upstream documentation] for a list on supported providers and how to configure them.
 
Further the TLS connection is enabled on IMAP port <code>993</code> and Submission port <code>465</code>.


{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
Line 13: Line 38:
   primaryDomain = "example.org";
   primaryDomain = "example.org";
   tls = {
   tls = {
     certPath = /var/lib/acme/example.org/example.org.crt;
     loader = "acme";
     keyPath = /var/lib/acme/example.org/example.org.key;
     extraConfig = ''
  };
      email put-your-email-here@example.org
  imap = {
      agreed # indicate your agreement with Let's Encrypt ToS
    port = 143;
      host ${config.services.maddy.primaryDomain}
    tlsEnable = true;
      challenge dns-01
     tlsPort = 993;
      dns gandi {
        api_token "{env:GANDI_API_KEY}"
      }
     '';
   };
   };
  # Enable TLS listeners. Configuring this via the module is not yet
  # implemented, see https://github.com/NixOS/nixpkgs/pull/153372
  config = builtins.replaceStrings [
    "imap tcp://0.0.0.0:143"
    "submission tcp://0.0.0.0:587"
  ] [
    "imap tls://0.0.0.0:993 tcp://0.0.0.0:143"
    "submission tls://0.0.0.0:465 tcp://0.0.0.0:587"
  ] options.services.maddy.config.default;
  # Reading secrets from a file. Do not use this example in production
  # since it stores the keys world-readable in the Nix store.
  secrets = [ "${pkgs.writeText "secrets" ''
    GANDI_API_KEY=1234
  ''}" ];
};
};
</nowiki>}}
TLS certificates can be obtained by using services like [[certbot]] or the [[acme]] service. Please reference their documentation on how to configure them to acquire the certificates.
In case of using the ''acme'' service, grant the ''maddy''  service read permissions for the certificates by adding it to the corresponding group
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
systemd.services.maddy.serviceConfig.SupplementaryGroups =
  [ config.security.acme.certs."example.org".group ];
</nowiki>}}


For other clients such as ''certbot'', add it to the <code>acme</code> group
# Opening ports for additional TLS listeners. This is not yet
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
# implemented in the module.
systemd.services.maddy.serviceConfig.SupplementaryGroups = [ "acme" ];
networking.firewall.allowedTCPPorts = [ 993 465 ];
</nowiki>}}
</nowiki>}}


== Configuration ==
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 89: 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 116: 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">
# nix shell nixpkgs#hash-slinger --command tlsa --create example.org
# nix shell nixpkgs#hash-slinger --command tlsa --port=25 --protocol=tcp mx1.example.org
</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 130: Line 168:
</nowiki>}}
</nowiki>}}


=== Managing users and inboxes ===
To verify if the record is set correctly
 
<syntaxhighlight lang="console">
# nix shell nixpkgs#dnsutils --command dig _25._tcp.mx1.example.org TLSA +short
3 1 1 7f59d873a70e224b184c95a4eb54caa9621e47d48b4a25d312d83d96 e3498238
</syntaxhighlight>
 
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 151: 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 160: 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 166: 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 172: Line 281:
You can use several online tools to test your mail server configuration:
You can use several online tools to test your mail server configuration:


* [https://ssl-tools.net/mailservers ssl-tools.net/mailservers]: Test your mail server configuration for validity and security.
* [https://en.internet.nl/test-mail en.internet.nl/test-mail]: Test your mail server configuration for validity and security.
* [https://www.mail-tester.com mail-tester.com]: Send a mail to this service and get a rating about the "spaminess" of your mail server.
* [https://www.mail-tester.com mail-tester.com]: Send a mail to this service and get a rating about the "spaminess" of your mail server.
* Send a mail to the echo server <code>echo@univie.ac.at</code>. You should receive a response containing your message in several seconds.
* Send a mail to the echo server <code>echo@univie.ac.at</code>. You should receive a response containing your message in several seconds.
Line 221: 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]]