Stalwart is an open source mail and collaboration server written in Rust. A single binary provides SMTP, IMAP, POP3, JMAP, ManageSieve, built-in spam filtering, DKIM signing and a web administration interface, with no separate Postfix, Dovecot or Rspamd to maintain. In this tutorial you will install Stalwart on Ubuntu 24.04 with the official installer, secure the admin interface, obtain a TLS certificate, publish the DNS records for your domain, and test sending and receiving mail.
Prerequisites
To follow this tutorial, you will need:
- A server running Ubuntu 24.04 LTS, for example a CubePath VPS, with at least 1 GB of RAM (2 GB recommended) and no other mail server installed.
- A non-root user with
sudoprivileges. - A domain name, referred to as
your_domain, and access to its DNS zone. The mail host will bemail.your_domain. - A static public IPv4 address, referred to as
your_server_ip, with reverse DNS (PTR) set tomail.your_domain. Set it from your provider's panel or ask support to do it. - Inbound and outbound TCP port 25 allowed by your provider.
Check that nothing is using the mail ports yet:
sudo ss -tlpn | grep -E ':(25|443|465|587|993|8080)\s'
The command should print nothing.
Step 1 - Creating the A record
Stalwart requests its certificate from Let's Encrypt, which needs mail.your_domain to resolve to your server. Create this record in your DNS provider now so it propagates while you install:
| Type | Name | Value |
|---|---|---|
| A | mail | your_server_ip |
Verify it:
dig +short A mail.your_domain
your_server_ip
You will add the MX, SPF, DKIM and DMARC records in Step 5, using the values Stalwart generates.
Step 2 - Installing Stalwart
Stalwart's supported installation method on Linux is its install script, which downloads the release binary, creates a stalwart system user, writes a default configuration and registers a systemd service. Download the script and read it before running it:
curl --proto '=https' --tlsv1.2 -sSf https://get.stalw.art/install.sh -o stalwart-install.sh
less stalwart-install.sh
Run it:
sudo sh stalwart-install.sh
By default everything is installed under /opt/stalwart, with the configuration file in /opt/stalwart/etc/config.toml and data in /opt/stalwart/data. At the end, the script prints the administrator credentials:
Installation complete! Continue the setup at http://your_server_ip:8080/login
Your administrator account is 'admin' with password 'Xk3...'.
Copy the password now; it is not shown again.
Check that the service is running:
sudo systemctl status stalwart
● stalwart.service - Stalwart Server
Loaded: loaded (/etc/systemd/system/stalwart.service; enabled; preset: enabled)
Active: active (running) since ...
NoteReleases before 0.11 named the binary and the service
stalwart-mailand installed to/opt/stalwart-mail. Ifsystemctl status stalwartreports that the unit is not found, usestalwart-mailin the commands below.
Confirm the listeners are open:
sudo ss -tlpn | grep stalwart
You should see Stalwart listening on ports 25, 465, 587, 143, 993, 443 and 8080, among others.
Step 3 - Configuring the firewall and reaching the admin interface
Allow SSH and the ports clients and other mail servers need. Port 80 is used by the Let's Encrypt HTTP challenge in some setups and is harmless to open:
sudo ufw allow OpenSSH
sudo ufw allow 25,80,443,465,587,993/tcp
sudo ufw enable
Port 8080 serves the admin interface over plain HTTP, so do not open it to the internet. Instead, reach it through an SSH tunnel from your own computer:
ssh -L 8080:127.0.0.1:8080 your_user@your_server_ip
With the tunnel open, browse to http://localhost:8080/login and sign in as admin with the password from Step 2. Once HTTPS is working in Step 4, the admin interface is also available at https://mail.your_domain/login.
The first thing to do is change the admin password from the account menu in the web interface.
Step 4 - Setting the hostname and getting a TLS certificate
In the web interface, open Settings and go to the server section:
- Under Network, set the server Hostname to
mail.your_domainand save. Stalwart uses this name in the SMTP greeting, which must match your PTR record. - Under TLS > ACME Providers, create a provider using the Let's Encrypt production directory, add
mail.your_domainto its domains, enter a contact email address, and save.
Apply the changes with Reload configuration, or restart the service:
sudo systemctl restart stalwart
Within a minute or two, Stalwart obtains the certificate through the TLS-ALPN challenge on port 443. Check that the server now presents it:
openssl s_client -connect mail.your_domain:993 -servername mail.your_domain </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject
issuer=C = US, O = Let's Encrypt, CN = R11
subject=CN = mail.your_domain
If you still see a self-signed certificate, look for ACME errors in the log files under /opt/stalwart/logs.
Step 5 - Adding your domain and publishing DNS records
In the web interface, go to Management > Directory > Domains and create your_domain. Stalwart generates DKIM keys for the domain automatically. Open the domain's DNS records view: it lists every record the domain needs, including MX, SPF, the DKIM public keys, DMARC, and autoconfig and SRV entries for clients.
Publish at least these records in your DNS provider, copying the exact values from Stalwart:
| Type | Name | Value |
|---|---|---|
| MX | @ | mail.your_domain (priority 10) |
| TXT | @ | v=spf1 mx -all |
| TXT | DKIM selector shown by Stalwart, for example 202609r._domainkey | v=DKIM1; k=rsa; h=sha256; p=... |
| TXT | _dmarc | v=DMARC1; p=quarantine; rua=mailto:postmaster@your_domain |
Stalwart typically publishes both an RSA and an Ed25519 DKIM key; add both. The SRV and autoconfig records are optional but let clients such as Thunderbird configure themselves.
Verify the records:
dig +short MX your_domain
dig +short TXT your_domain
dig +short TXT _dmarc.your_domain
Step 6 - Creating a mail account
Go to Management > Directory > Accounts and create an account:
- Name (login):
alice - Email:
alice@your_domain - Password: a strong password
Save it. Mail clients connect with these settings:
| Protocol | Server | Port | Security |
|---|---|---|---|
| IMAP | mail.your_domain | 993 | SSL/TLS |
| SMTP submission | mail.your_domain | 465 | SSL/TLS |
| SMTP submission | mail.your_domain | 587 | STARTTLS |
| JMAP | https://mail.your_domain | 443 | HTTPS |
Step 7 - Testing SMTP, IMAP and JMAP
Install swaks, a command-line SMTP test tool, and send an authenticated message to an external address you control:
sudo apt install -y swaks
swaks --to your_external_address --from alice@your_domain \
--server mail.your_domain --port 587 --tls \
--auth-user alice --auth-password 'alice_password'
The transcript should show with a 250 response for the message, followed by 221 when the connection closes. Check the received message's headers for spf=pass, dkim=pass and dmarc=pass, then reply to it to test inbound delivery.
Check that JMAP discovery works. The session endpoint returns a JSON document describing the account and its capabilities:
curl -s -u 'alice:alice_password' https://mail.your_domain/.well-known/jmap | head -c 300
{"capabilities":{"urn:ietf:params:jmap:core":{...
Finally, configure the account in a mail client with the IMAP settings from Step 6 and confirm the reply arrived.
Step 8 - Reviewing spam filtering
Stalwart's spam filter is enabled by default and combines DNS blocklists, reputation, header and content rules, and a Bayesian classifier. Its settings live under Settings > Spam filter in the web interface, where you can adjust the score thresholds for marking messages as spam or rejecting them. Messages marked as spam are delivered to the user's Junk folder, and users train the Bayes classifier by moving messages into or out of Junk in their mail client.
Keep an eye on the first days of traffic in the logs under /opt/stalwart/logs or the Logs view of the web interface before tightening thresholds.
Updating Stalwart
Download the new release binary from the Stalwart GitHub releases page, or rerun the install script as described in the official upgrade notes for your version, then restart the service:
sudo systemctl restart stalwart
Read the release notes before updating. Some releases change configuration keys or the storage format and include a migration step.
Troubleshooting
Other servers cannot deliver mail to you: from a machine outside your network, run nc -vz mail.your_domain 25. A timeout means port 25 is blocked by a firewall or by your provider.
Clients get a certificate warning: the ACME order has not completed. Confirm mail.your_domain resolves to this server and that port 443 is open, then check the logs in /opt/stalwart/logs for ACME errors.
Sending fails with relay not allowed: the client is not authenticating. Use port 465 or 587 with authentication enabled; port 25 only accepts mail for your own domains.
Outgoing mail lands in spam: verify the PTR record with dig +short -x your_server_ip, and confirm the hostname in Settings is mail.your_domain and the DKIM records match the ones Stalwart shows.
Conclusion
You now have a Stalwart mail server on Ubuntu 24.04 with a Let's Encrypt certificate, SPF, DKIM and DMARC, and a working account reachable over IMAP, SMTP and JMAP. As next steps, configure a backup of /opt/stalwart/data, migrate existing mailboxes from your old server with imapsync, and explore the calendar and contacts support in recent Stalwart releases.
