RE:NODE

App hosting11 min read

Stalwart mail server setup: domains, accounts and DKIM

Setting up Stalwart from first sign-in: the host name, domains, accounts and aliases, DKIM keys, the DNS records to publish, ports, spam filtering and testing.

0 readers

Stalwart is a complete mail server in one program: SMTP for sending and receiving, IMAP and JMAP for reading, a spam filter, DKIM signing and a web admin to drive all of it. Setting it up comes down to five decisions made in order - the server's host name, the domains it serves, the accounts that live on them, the DKIM keys that sign their mail, and the DNS records that tell the world about all of the above. Do them in that order and the first test message arrives with three passes in its headers. Do them out of order, especially publishing DNS before the host name is settled, and you spend an evening chasing mismatches.

This guide follows that order. It stays close to concepts rather than exact menu paths, because Stalwart's web admin has been reorganised more than once between releases. Where a screen name matters, it says which version it applies to.

What Stalwart is and how it is put together#

Stalwart is written in Rust and ships as a single binary. Where a classic setup combines Postfix, Dovecot, Rspamd and OpenDKIM, Stalwart does all of it in one process with one configuration store. The pieces you will meet:

  • The MTA - the SMTP side. It accepts inbound mail on port 25, takes submissions from your users on 587 and 465, queues outbound mail and delivers it, either directly to recipients' MX hosts or through a relay.
  • The mail store - mailboxes, folders, messages and their search index. Stalwart can keep data in an embedded database (RocksDB is the usual default) or in an external one such as PostgreSQL, with large message bodies optionally in object storage. For a single server the embedded store is the right choice.
  • Access protocols - IMAP (both IMAP4rev1 and IMAP4rev2), JMAP over HTTPS, and POP3. Sieve filtering with ManageSieve for clients that edit rules.
  • The directory - where accounts and passwords live. The internal directory is the default; LDAP, SQL and OpenID Connect are options for organisations that already have a user store.
  • The spam and phishing filter - built in, rule and score based, with statistical classification and DNS blocklist checks.
  • Authentication for mail - DKIM signing on the way out; SPF, DKIM, DMARC and ARC verification on the way in; DMARC and TLS reports in both directions.
  • The web admin - a browser interface for all of the above, plus the queue, logs and reports.

The upshot is that almost everything in this guide happens in the web admin. You rarely touch a configuration file.

First sign-in to the web admin#

A fresh Stalwart install starts in what the project calls bootstrap mode: no mail services run, the server listens only on HTTP port 8080, and it prints a temporary administrator password to its console exactly once. The setup wizard at http://<host>:8080/admin asks for the server host name, the default domain, where to store data and which directory to authenticate against. When it finishes, it writes its configuration, creates the permanent administrator and restarts, after which the web admin moves to HTTPS on the configured host name.

On a hosted server the install has already been done for you, so your first step is simply to sign in. Find the administrator credentials the server was created with - look at the panel's Startup tab and at the console output from the first start, and if they are in neither place, ask support rather than resetting anything - and open the web admin on the address and port the panel shows for your server.

Once you are in, do two things before anything else:

  1. Change the administrator password to one stored in a password manager, and turn on two-factor authentication for the admin account if your version offers it.
  2. Read the logs view once. It is where you will look first whenever a message goes missing, and knowing what normal looks like makes the abnormal obvious.

The host name and certificates#

The server's host name is the name it announces in every SMTP conversation (the EHLO greeting), the name in your MX records, and the name on the TLS certificate clients see. Pick it once and keep it: mail.example.com is conventional and works.

That one name has to line up in four places:

WhereMust be
Stalwart's server host namemail.example.com
A recordmail.example.com points at the server's IP
MX recordthe domain's MX target is mail.example.com
PTR record for the IPresolves to mail.example.com (set by the IP's owner)

The last one is not in your zone - reverse DNS belongs to whoever owns the address. Reverse DNS and PTR for mail servers explains why it matters and what to do when you cannot set it.

The certificate covers the host name your users' clients connect to for IMAP and submission. Stalwart has a built-in ACME client and can obtain and renew certificates itself, using the TLS-ALPN, HTTP or DNS challenge. Which challenge can work depends on which ports reach the server, so on a hosted plan with a fixed set of ports, ask support how certificates are best handled for your server rather than guessing. An expired or mismatched certificate on the mail host is the classic "every phone in the office complains on Monday" incident.

Domains, accounts and aliases#

A domain in Stalwart is a name the server accepts mail for. Add your domain first; accounts cannot exist without one.

Then create accounts. Each account has a login name, a password, one or more email addresses, and optionally a quota. Some conventions that save trouble later:

  • Login name and address are separate. An account named anna can hold anna@example.com, a.smith@example.com and anna@example.org as addresses. Users log in with whatever you set as the login; tell them which.
  • Set a quota on every account. A mailbox with no quota is a disk that fills on a schedule you do not control. 2-5 GB is a sensible starting point for office mail.
  • Use aliases for roles, not accounts. info@, sales@ and billing@ are better as extra addresses on the people who handle them, or as a group, than as accounts with their own passwords somebody has to remember.
  • Groups and mailing lists deliver one address to several accounts. Use a group when a team shares an address and needs shared access, a list when it is pure distribution.
  • A catch-all - accepting every address at the domain - sounds convenient and collects a great deal of spam. Avoid it unless you have a specific reason.
  • The postmaster address. RFC 5321 requires that postmaster@ exists for every domain you receive mail for. Point it at a real person.

For each user's devices, prefer application passwords where your version supports them, so a lost phone means revoking one password rather than resetting the user's main one. The client side is in email client setup for IMAP and SMTP.

DKIM keys and the DNS records to publish#

When you add a domain, Stalwart generates DKIM keys for it. Recent versions generate two by default, one Ed25519 and one RSA, and sign outgoing mail with both. That is deliberate: Ed25519 signatures are small and modern, but not every receiver verifies them yet, so the RSA signature is the one most receivers actually check. Publish both. Each has its own selector, and in recent releases the default selector pattern looks like v1-ed25519-20260101 - whatever your server generated, copy it exactly.

Stalwart also computes the full set of records it expects for each domain and shows them in the web admin as a zone you can copy. Use that as your source of truth rather than typing records from a blog post, because the DKIM keys are unique to your server. For example.com on mail.example.com at 203.0.113.25, the shape is:

records for example.com, simplified
mail                         IN A     203.0.113.25@                            IN MX    10 mail.example.com.@                            IN TXT   "v=spf1 mx -all"v1-rsa-20261008._domainkey   IN TXT   "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."v1-ed25519-20261008._domainkey IN TXT "v=DKIM1; k=ed25519; p=11qYAYKx..."_dmarc                       IN TXT   "v=DMARC1; p=none; rua=mailto:postmaster@example.com"

The list Stalwart shows will also contain records you can add later: MTA-STS and TLS-RPT for enforcing TLS on inbound mail, SRV records for client discovery, and CNAME records for autoconfig and autodiscover. Start with the five above; add the rest once mail flows.

Points that catch people:

  • The DKIM record name is relative. In most DNS editors you type v1-rsa-20261008._domainkey in the name field, not the full name with your domain appended. Typing the full name produces ...example.com.example.com.
  • Long RSA keys are split into strings. A 2048-bit key exceeds 255 characters, so it has to be stored as several quoted strings. Most editors do this for you; if verification fails, check this first.
  • SPF with `mx` authorises your MX hosts. If you send through a relay, add the relay's include: and keep one record.
  • Start DMARC at `p=none`. DMARC reports and policy rollout explains when to tighten it.

Key rotation, including how Stalwart can automate it when it has API access to your DNS provider, is in DKIM keys and rotation.

Ports and which services to expose#

Stalwart can listen on all of the standard mail ports. On your own machine you would open the ones you use; on a hosted plan with a fixed number of ports, you choose.

PortServiceWho connectsNeeded?
25SMTPOther mail servers delivering to youYes, to receive anything
587Submission, STARTTLSYour users' mail clientsOne of 587 or 465
465Submission, implicit TLSYour users' mail clientsOne of 587 or 465
993IMAP over TLSMail clients reading mailYes, for most clients
443HTTPS: JMAP, web adminJMAP clients, the adminFor JMAP and admin
143 / 995 / 110Plain IMAP, POP3Legacy clientsRarely
4190ManageSieveClients that edit filter rulesOptional

Never expose plain IMAP on 143 or POP3 on 110 without STARTTLS enforced; passwords would cross the network readable. On a RE:NODE Mail Server plan there are five ports to share out, which is enough for one submission port, IMAPS, HTTPS and a couple more - and port 25 itself is forwarded by support on request, because a container cannot open it on the public address by itself. Use the port numbers the panel shows for your server in your clients; if one of them is not the standard number, the client simply needs to be told.

Spam filtering and outbound delivery#

Stalwart's spam filter scores each inbound message with tags - authentication results, blocklist hits, header oddities, content features, the statistical classifier's verdict - and adds up their scores. The default spam threshold is 5.0. By default nothing is rejected on score alone; spam is marked and filed. Every message gets two headers you should learn to read:

code
X-Spam-Status: No, score=-1.20X-Spam-Result: DKIM_ALLOW (-0.20), DMARC_POLICY_ALLOW (-0.50), SPF_ALLOW (-0.20), ...

X-Spam-Result lists every rule that fired and its contribution, which turns "why did this land in Junk" from a mystery into a lookup. Thresholds and scores are adjustable in the web admin's spam filter settings; mail server spam filtering covers tuning, training and false positives.

For outbound mail there are two strategies. Direct delivery looks up each recipient's MX and connects to its port 25. Relay hands everything to one smarthost, which delivers on your behalf. In recent Stalwart versions a relay is a route of the Relay type in the outbound settings, with the relay's address, port, whether TLS is implicit (port 465) or negotiated (587 with STARTTLS), and the username and secret to authenticate with; the outbound strategy then sends remote mail through that route. Stalwart still signs with your DKIM keys before handing mail over, so your signature arrives intact. SMTP relay for outgoing mail covers choosing a relay and the SPF change it needs.

Testing and troubleshooting#

Test from the outside, in this order.

bash
# DNS: every record you published$ dig +short MX example.com$ dig +short TXT example.com$ dig +short TXT _dmarc.example.com$ dig +short TXT v1-rsa-20261008._domainkey.example.com# Inbound SMTP reachable, with a banner and STARTTLS offered$ openssl s_client -starttls smtp -connect mail.example.com:25 -crlf -quiet# Submission with authentication, using swaks$ swaks --to you@gmail.com --from anna@example.com \    --server mail.example.com:587 --tls --auth-user anna

Then send a real message from a client to a Gmail or Outlook address you control and read the Authentication-Results header: spf=pass, dkim=pass and dmarc=pass with header.from=example.com is the finished state. Reply to it to test inbound.

The failures people actually hit:

  • Nothing arrives from outside. Port 25 is not reaching the server. Check the MX target resolves to the right address, then test the port from a machine outside your network. On a hosted plan, confirm that port 25 forwarding has been set up.
  • Sending works to yourself but not to Gmail. Outbound 25 is blocked, so mail sits in the queue. Look at the queue in the web admin; if attempts time out, configure a relay.
  • `dkim=fail` or `dkim=neutral`. The published record does not match the key, usually a truncated or wrongly split value, or the selector name is wrong.
  • Clients warn about the certificate. The name they connect to is not on the certificate, or it has expired.
  • Login fails from clients but works in the web admin. The client is using the full address when the login name is different, or the wrong security setting for the port (STARTTLS on 465, or implicit TLS on 587).

FAQ#

Does Stalwart need a separate database server?

No. The embedded store is the default and is the right choice for a single server. External databases and object storage exist for clustered deployments with several nodes.

Can one Stalwart server host several domains?

Yes. Add each domain, give each its own DKIM keys and DNS records, and create accounts with addresses on any of them. One account can even hold addresses on several domains.

Why does Stalwart sign with two DKIM keys?

One Ed25519 key and one RSA key. Ed25519 is the modern algorithm, but verifier support is still uneven, so the RSA signature is what most receivers check. A message with one passing signature passes DKIM.

Do I need POP3?

Almost certainly not. IMAP keeps mail on the server and in sync across devices; POP3 downloads and usually deletes. Leave it off unless a specific legacy device needs it.

What should I back up?

The whole data store, which holds mailboxes, accounts, DKIM keys and settings together. On RE:NODE the backup slots are stored off the machine they protect and can be downloaded, so keep one recent download somewhere of your own as well. Restore it once onto a scratch server to prove the backup works.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000