Stalwart Mail Server Installation
Stalwart is a modern, all-in-one mail server written in Rust that supports JMAP, IMAP4, and SMTP with a built-in web admin interface and automatic spam filtering. This guide covers deploying Stalwart on Linux, configuring JMAP/IMAP/SMTP, setting up DKIM signing, and using the web admin panel.
Prerequisites
- Ubuntu 20.04+/Debian 11+ or CentOS 8+/Rocky Linux 8+
- Minimum 1 GB RAM (2 GB recommended)
- A domain name with DNS control
- Ports 25, 80, 443, 587, 465, 993, 8080 accessible
- Root or sudo access
- No other mail server running
Installing Stalwart
# Create a dedicated user and directories
useradd -r -s /sbin/nologin stalwart-mail
mkdir -p /opt/stalwart-mail/{data,logs,config}
chown -R stalwart-mail:stalwart-mail /opt/stalwart-mail
# Download and install via the official install script
curl -fsSL https://get.stalw.art/install.sh | \
sudo bash -s -- --path /opt/stalwart-mail
Alternatively, download the binary manually:
# Get the latest release
VERSION=$(curl -s https://api.github.com/repos/stalwartlabs/mail-server/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4)
# Download for Linux x86_64
wget "https://github.com/stalwartlabs/mail-server/releases/download/${VERSION}/stalwart-mail-x86_64-unknown-linux-gnu.tar.gz"
tar xzf stalwart-mail-*.tar.gz -C /usr/local/bin/
chmod +x /usr/local/bin/stalwart-mail
# Install with wizard
stalwart-mail --install
Initial Setup Wizard
Run the interactive setup wizard:
sudo stalwart-mail --config /opt/stalwart-mail/config/config.toml --init
The wizard prompts for:
- Base directory:
/opt/stalwart-mail - Domain:
yourdomain.com - Hostname:
mail.yourdomain.com - Admin password: Choose a strong password
- TLS: Choose Let's Encrypt automatic or provide existing certs
Start as a systemd service:
# The installer creates the service, or create it manually
sudo tee /etc/systemd/system/stalwart-mail.service << 'EOF'
[Unit]
Description=Stalwart Mail Server
After=network.target
[Service]
Type=simple
User=stalwart-mail
ExecStart=/usr/local/bin/stalwart-mail --config /opt/stalwart-mail/config/config.toml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now stalwart-mail
sudo systemctl status stalwart-mail
DNS Configuration
Required DNS records:
# A record
mail.yourdomain.com. IN A YOUR_SERVER_IP
# MX record
yourdomain.com. IN MX 10 mail.yourdomain.com.
# SPF
yourdomain.com. IN TXT "v=spf1 mx -all"
# DKIM (get value from admin panel after setup)
mail._domainkey.yourdomain.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjAN..."
# DMARC
_dmarc.yourdomain.com. IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]"
# JMAP SRV record (for auto-discovery)
_jmap._tcp.yourdomain.com. IN SRV 0 1 443 mail.yourdomain.com.
Set reverse DNS at your VPS provider to mail.yourdomain.com.
SMTP and DKIM Configuration
Stalwart's configuration is in TOML format. Key SMTP settings:
# /opt/stalwart-mail/config/config.toml
[server.listener."smtp"]
bind = ["0.0.0.0:25"]
protocol = "smtp"
tls.implicit = false
[server.listener."submission"]
bind = ["0.0.0.0:587"]
protocol = "smtp"
tls.implicit = false
[server.listener."submissions"]
bind = ["0.0.0.0:465"]
protocol = "smtp"
tls.implicit = true
[session.rcpt]
relay = [{ if = "authenticated-as", ne = "", then = true }, { else = false }]
[session.ehlo]
reject-non-fqdn = true
Generate and configure DKIM keys:
# Generate DKIM key via admin panel, or manually
openssl genrsa -out /opt/stalwart-mail/config/dkim-private.pem 2048
openssl rsa -in /opt/stalwart-mail/config/dkim-private.pem \
-pubout -out /opt/stalwart-mail/config/dkim-public.pem
# Extract public key for DNS
openssl rsa -in /opt/stalwart-mail/config/dkim-private.pem -pubout \
| grep -v "PUBLIC KEY" | tr -d '\n'
Add to config:
[signature."mail.yourdomain.com"]
private-key = "/opt/stalwart-mail/config/dkim-private.pem"
domain = "yourdomain.com"
selector = "mail"
headers = ["From", "To", "Date", "Subject", "Message-ID"]
algorithm = "rsa-sha256"
canonicalization = "relaxed/relaxed"
JMAP and IMAP Configuration
JMAP (JSON Meta Application Protocol) is Stalwart's modern email API:
[server.listener."jmap"]
bind = ["0.0.0.0:443"]
protocol = "http"
tls.implicit = true
[jmap.session.timeout]
authenticated = "30m"
anonymous = "1m"
# JMAP push notifications
[jmap.push]
max-total = 100
throttle = "1s"
IMAP configuration for legacy clients:
[server.listener."imap"]
bind = ["0.0.0.0:143"]
protocol = "imap"
tls.implicit = false
[server.listener."imaps"]
bind = ["0.0.0.0:993"]
protocol = "imap"
tls.implicit = true
[imap.auth]
max-failures = 3
allow-plain-text = false
Spam Filtering
Stalwart includes built-in spam filtering using Rspamd or its own Sieve-based filters:
[spam-filter]
enable = true
# Set the spam threshold
threshold.discard = 15
threshold.reject = 12
threshold.spam = 5
# Bayes learning
[spam-filter.bayes]
enable = true
min-learns = 200
# DNSBL checks
[spam-filter.dnsbl]
enable = true
Train the Bayes filter:
# Mark messages as spam (via admin panel or IMAP commands)
# Or feed a corpus of known spam:
stalwart-mail spam-learn --ham /path/to/ham/
stalwart-mail spam-learn --spam /path/to/spam/
Web Admin Interface
Access the admin panel at https://mail.yourdomain.com:8080/admin or https://mail.yourdomain.com/admin depending on your setup.
Default credentials:
- Username:
admin - Password: Set during the wizard (or check the install output)
From the admin panel you can:
- Add/manage domains and accounts
- View DKIM keys and DNS status
- Monitor the mail queue
- Configure spam filter settings
- Run diagnostics
Manage accounts via CLI:
# Create an account
stalwart-mail manage account create \
--name alice \
--email [email protected] \
--password StrongPassword123
# List accounts
stalwart-mail manage account list
# Add an alias
stalwart-mail manage alias create [email protected] [email protected]
Migrating from Legacy Servers
Migrate from Postfix/Dovecot or other servers:
# Export mail from existing Dovecot server (on old server)
# Using imapsync
apt install -y imapsync
imapsync \
--host1 old-mail.yourdomain.com \
--user1 [email protected] \
--password1 OldPassword \
--host2 mail.yourdomain.com \
--user2 [email protected] \
--password2 NewPassword \
--ssl1 --ssl2
# Import from Maildir format directly
stalwart-mail import maildir \
--path /var/mail/alice/Maildir \
--account [email protected]
Troubleshooting
SMTP connection refused on port 25:
# Check if the port is listening
ss -tlnp | grep ':25'
# Many VPS providers block port 25 by default
# Check provider firewall and request unblocking if needed
TLS certificate issues:
# Check certificate status
journalctl -u stalwart-mail | grep -i cert
# Verify domain A record resolves correctly (required for Let's Encrypt)
dig mail.yourdomain.com
# Force certificate renewal via admin panel or:
stalwart-mail --acme-renew
Messages rejected with "relay access denied":
Ensure SMTP authentication is configured for submission (port 587/465). Check that clients authenticate before sending.
JMAP clients not connecting:
# Verify JMAP endpoint is accessible
curl -v https://mail.yourdomain.com/.well-known/jmap
# Check logs
journalctl -u stalwart-mail -f | grep jmap
Conclusion
Stalwart delivers a modern, high-performance mail server that supports both classic IMAP/SMTP clients and the new JMAP protocol, all in a single Rust binary with low resource overhead. Its built-in spam filtering, web admin interface, and automated TLS make it a compelling option for teams migrating away from complex Postfix/Dovecot stacks. Configure DKIM, SPF, and DMARC immediately after setup to ensure good email deliverability.


