Files

8.8 KiB

Mail

Mail is part of the current tilde.club host, not a localhost-only experiment. The collected Postfix config accepts mail for tilde.club and several related domains, uses .mail/, and has no configured relayhost. Dovecot 2.4 serves Maildir mail from ~/.mail, authenticates through PAM, and exposes a Postfix authentication socket. The first-login wizard can create .forward.

OpenDKIM and Rspamd are connected through milters on localhost ports 8891 and 11332. A pyspf-milter service is also running; its presence alone does not show how it is connected. The guide does not reconstruct unpublished filter rules.

Decide what service you are offering

There are three useful starting points:

  • Local-only mail between shell accounts.
  • Internet mail with direct inbound and outbound delivery.
  • Inbound mail with outbound delivery through an authenticated relay.

The production reference matches the second configuration at the Postfix relayhost setting. Provider-side routing was not inspected. For a new direct mail host, verify that TCP 25 is permitted, the address has working reverse DNS, and the provider allows mail service. Do not discover a port-25 block after opening accounts.

Use a separate mail domain in examples if that is your intended policy. Here, mail addresses are member@tilde.example.net and the SMTP host is also tilde.example.net.

DNS before launch

Publish and verify:

  • A/AAAA records for the SMTP host; publish IPv6 only if SMTP and reverse DNS work there.
  • An MX for the mail domain pointing to that hostname, not to an IP literal.
  • A PTR for each sending address, matching the sending hostname with forward resolution.
  • SPF authorizing the actual sending service, including any outbound relay.
  • A DKIM public key for the signing selector you configure.
  • DMARC with a monitored report address and a policy you can operate. Start with observation and verify alignment before enforcing rejection.

Do not copy tilde.club's IP addresses, signing keys, DNS selectors, or domain aliases. Forwarded mail has additional SPF/DMARC consequences; test it against actual recipients rather than assuming .forward solves deliverability.

Install the base services

dnf install postfix dovecot dovecot-pigeonhole swaks

Back up existing configs first. The examples are for a new host. Merge main.cf.fragment into Postfix's config, replacing conflicting settings rather than appending duplicate guesses. Keep the distribution's default local-recipient checks, alias handling, and master services. Point root and postmaster aliases to a mailbox an operator reads, then run newaliases.

The example uses Dovecot LMTP for local mailbox delivery so the Sieve plugin can run. This is a deliberate new-host choice: the collected production config has an empty mailbox_transport and a local delivery transport. A configured Sieve plugin alone does not prove that every live delivery goes through it.

For a local-only host, keep Postfix listening on loopback, do not publish an MX or open SMTP externally, and explicitly reject nonlocal delivery with default_transport = error: external mail is not offered. Do not apply that setting to a host that promises Internet mail.

Dovecot 2.4

Use tilde.conf as a standalone starting config for system accounts with private primary groups. Replace the domain and TLS paths. Do not include another conflicting authentication config alongside it. Retain the distro's /etc/pam.d/dovecot authentication/account policy; it is a separate PAM service from SSH and should not inherit SSH-specific TOTP prompts.

This uses Dovecot 2.4 syntax. In particular, it uses mail_driver, mail_path, protocol/plugin blocks, and current TLS settings. Do not paste a Dovecot 2.3 mail_location tutorial into it.

The example enables IMAP and LMTP, requires TLS, uses a minimum of TLS 1.2, and places LMTP and authentication sockets inside Postfix's private spool. The current host also enables POP3 and ManageSieve; enable those on a new host only if they are part of the service you intend to support.

The recorded host has ssl_min_protocol = TLSv1. That is a live compatibility setting, not the minimum used by this example. Check client compatibility before changing a running system.

Ensure each mailbox and Sieve directory is owned by its member and is not readable by other members or the shared web group. Test SELinux access on a new enforcing host. Inspect doveadm user member for the actual resolved UID, group, home, and mail paths.

doveconf -n
postfix check
systemctl enable --now dovecot postfix

Check the journal and actual socket ownership. A parser check cannot prove that PAM login or delivery works. Do not add doveconf -P when sharing output: it reveals values that the default display hides.

Submission

Merge the named services from master.cf.fragment. Do not replace the rest of master.cf. The example offers authenticated STARTTLS on 587 and implicit TLS on 465, with authentication enabled on those services and TLS required before accepting credentials. Delivery on 25 remains available without mandatory TLS so remote mail servers can reach you.

Keep relay restrictions explicit. Test that an outside, unauthenticated client cannot relay to a third-party domain. Also test that an authenticated member can submit a message and that the expected envelope/header sender policy is enforced. If you want one-account/one-sender enforcement, maintain smtpd_sender_login_maps for the addresses and aliases you actually allow and then apply the matching sender restrictions to submission. Do not enable a sender-ownership rule against an empty map.

A shared host's localhost clients are not all trusted operators. Local shell users can invoke mail tools directly, so address-spoofing controls, outbound volume policy, abuse response, and logging need to cover local submission too. Use authenticated submission or an identity-aware local submission policy where account attribution is required.

Filtering and signing

The base examples establish mail transport, not a finished spam policy. Before opening Internet mail, configure maintained filtering and signing software. The production host's two milter endpoints are recorded above, but its private rules and signing material are not included here.

If using OpenDKIM, install the maintained package and generate a new key under /etc/opendkim/keys/tilde.example.net. Configure a signing table for your domain, a key table pointing to that key, and a localhost-only milter socket. Publish the generated public TXT record. Keep the private key restricted to the signing service. In Rspamd, configure the proxy/milter and controller according to its installed version, keep the controller private, and choose which service owns DKIM signing. Avoid accidentally signing twice with conflicting policies.

Add the tested milter endpoints to smtpd_milters and non_smtpd_milters only after verifying them. Choose and document what happens if filtering is down: accepting unfiltered mail and temporarily rejecting it are different policies. Add spam-folder handling only after confirming messages travel through the Sieve-enabled delivery path. Do not enable Sieve external-program extensions just because they appear in a production dump.

See OpenDKIM and Rspamd's MTA integration guide. Both need their own update, key rotation, and failure checks.

Verification

Use disposable mailboxes and clients you control:

  1. Deliver locally between two accounts and verify the mailbox path and ownership.
  2. Receive from an outside sender and send to an outside recipient.
  3. Verify the received SPF, DKIM, and DMARC results and inspect the queue/logs.
  4. Check IMAP login with a valid account, a wrong password, and an ineligible account.
  5. Check submission over TLS and reject an unauthenticated external relay attempt.
  6. Test aliases, .forward, invalid recipients, a full quota, Sieve, and service restart.
  7. Renew the certificate in a test run and confirm each mail service uses the new one.

For TLS inspection without exposing a password in command history:

openssl s_client -connect tilde.example.net:993 -servername tilde.example.net
openssl s_client -starttls smtp -connect tilde.example.net:587 -servername tilde.example.net
postqueue -p
journalctl -u postfix -u dovecot --since today

Do not submit a password until the client verifies the certificate and expected hostname. Do not paste authentication transcripts into public logs.

Back up mailbox data, Sieve files, aliases, transport/filter configs, and signing keys using the recovery plan. A key or MFA reset for SSH does not by itself revoke an existing webmail session, mail password, or application token.