User guide

Self-hosted mail without the pain. Get DNS right first, then missus does the rest — first domain, DKIM, TLS, mailboxes, DMARC reports — in one short sitting.

1. DNS prerequisites

Mail is the hardest sysadmin task because so much of "does it work?" lives in DNS. Get this right before installing missus and the rest is straightforward.

  • A hostname for the mail server, e.g. mail.example.com, with an A (and AAAA, if IPv6) record pointing at the box.
  • Reverse DNS (PTR) on the public IP pointing back at mail.example.com. Set this at the hosting provider — most receiving MTAs (Gmail, Outlook) reject mail from senders without correct rDNS, and there's nothing missus can do about that.
  • For each mail domain you'll host: an MX record example.com → mail.example.com (priority 10 is the default). missus shows you the exact records on the /dns-advice page once you've added the domain.
  • Outbound port 25 open. Many providers (DigitalOcean, OVH consumer plans, residential ISPs) block this by default — check before committing to a host.
  • A local DNS resolver on the box (nameserver 127.0.0.1): nomina in recursor mode, or apt install unbound. Spamhaus refuses queries that come through public resolvers (8.8.8.8, 1.1.1.1, your provider's): mail still arrives, but the blocklists stop no spammer. missus check tells you which case you're in. A local resolver that forwards to public ones is just as blind: with nomina, leave the forwarders empty.
If outbound 25 is blocked, missus can't deliver outbound mail: it has no relay (smarthost) setting yet. Pick a host that opens 25, or ask the provider to.
Clean boxes only. missus takes over the whole mail stack: at the first missus apply Postfix's main.cf/master.cf, Dovecot's config and three Rspamd files become symlinks to files under /srv/missus (each original is saved as <file>.dpkg-bak). Mailboxes, domains and settings already on the box are not imported, and removing missus does not restore the backups.

2. Install missus

curl -fsSL https://apt.netforge.it/netforge.asc \
    | sudo gpg --dearmor -o /usr/share/keyrings/netforge.gpg
echo "deb [signed-by=/usr/share/keyrings/netforge.gpg] https://apt.netforge.it/free $(. /etc/os-release; echo $VERSION_CODENAME) main" \
    | sudo tee /etc/apt/sources.list.d/netforge.list
sudo apt update
sudo apt install missus

sudo missus admin create yourname
sudo systemctl start missus

The install pulls in Postfix, Dovecot (with sieve, IMAP, POP, LMTP), Rspamd and certbot. The postinst lays out /srv/missus/ (Maildirs, DKIM keys, state.db, backups), generates a 256-bit session secret and wires Postfix, Dovecot and Rspamd to missus's configs. Until a Let's Encrypt certificate exists, TLS uses Debian's self-signed one: mail clients connect, with a warning.

3. First login

missus binds to 127.0.0.1:8443 by default — reachable via an SSH tunnel or behind a reverse proxy. The deployment recipe is "missus on a backend host or a private network, panel reachable from your laptop". From your laptop:

ssh -L 8443:127.0.0.1:8443 root@your-mail-server
# then open http://127.0.0.1:8443/ in your browser

Log in, enrol 2FA at /account. Then go to /system/server and set:

  • Hostname — exactly what your A/AAAA records point at (e.g. mail.example.com). missus rejects bare names like localhost; an FQDN is required because certbot, DKIM record naming, and SPF mechanism resolution all depend on it.
  • Public IPv4, Public IPv6 (if you have one).
  • Default DMARC policy: start at quarantine for new domains, escalate to reject once you're confident SPF + DKIM are aligned (see DMARC section below).

Saving applies it to Postfix, Dovecot and Rspamd at once — every save in the panel does. /system/apply re-does it all, e.g. after editing files by hand.

4. First mail domain

Go to /domains, click + New domain, enter example.com, set a default mailbox quota (e.g. 1024 MB) and outbound rate limit (e.g. 200/h is sane for personal use; bump to 1000+ for a small team).

On save, missus generates a 2048-bit DKIM keypair under /srv/missus/dkim/example.com.missus.private with selector missus. The public key is what you'll publish to DNS in the next step.

Then go to /dns-advice.

5. Publish the DNS records

/dns-advice shows the exact records you need to publish for each domain you've added. There are six per domain:

TypeNameWhat it does
A / AAAAmail.example.comServer hostname → IP (you set this before install)
MXexample.comWhere mail for this domain lands
TXT (SPF)example.comAuthorizes the server's IPs to send for the domain
TXT (DKIM)missus._domainkey.example.comPublic key receivers use to verify outbound signatures
TXT (DMARC)_dmarc.example.comWhat receivers should do when SPF and DKIM both fail

Paste them at your registrar — or, if you also run nomina, add them as zone records there. Then click Verify on /dns-advice; missus dials the public DNS and reports each row green / yellow / red. Wait until they're all green before issuing TLS or sending real mail.

SRV records are optional but really nice — a Thunderbird or Apple Mail user types jane@example.com + password and the client finds the IMAP and SMTP hosts automatically.

6. TLS for SMTP/IMAP

Go to /system/certificates, request a Let's Encrypt cert for mail.example.com. missus uses certbot --standalone, which needs port 80 free for a few seconds.

arx on the same box? nginx holds port 80, so let arx get the certificate: create the site mail.example.com in arx and turn on HTTPS. arx issues and renews it; missus finds it in arx's certificate store and uses it — at once with Use it now on /system/certificates, otherwise within a day (missus-cert-sync.timer, which also picks up every renewal).

On success, missus drops the cert at /etc/letsencrypt/live/mail.example.com/, points Postfix's smtpd_tls_cert_file + Dovecot's ssl_cert at it, and reloads both daemons. Debian's certbot.timer renews it; missus's deploy hook reloads Postfix and Dovecot after each renewal.

7. Mailboxes & aliases

Mailboxes are virtual — they don't map to Unix users. Authentication happens against state.db (Argon2id hashes) via Dovecot. The on-disk Maildir lives at /srv/missus/mail/<domain>/<local>/ owned by the system vmail user.

# From the panel: /mailboxes → + New mailbox
#   address: jane@example.com
#   password: (strong password)
#
# From the CLI:
sudo missus mailbox add jane@example.com

Aliases redirect mail without a Maildir. Use them for role addresses, departmental fan-outs, and catch-alls:

# Single redirect
info@example.com  → jane@example.com

# Fan-out (one source, many targets)
sales@example.com  → jane@example.com, mark@example.com

# Catch-all (anything @example.com that isn't a defined mailbox)
@example.com  → jane@example.com

Edit at /aliases, or:

sudo missus alias add info@example.com jane@example.com
sudo missus alias add @example.com jane@example.com

Users change their own password on an optional page (/me): address, current password, new password twice. It's off by default and listens only on loopback:

sudo missus me enable     # page on 127.0.0.1:8444
sudo missus me status

Publish it with an arx reverse proxy site, e.g. mail.example.com → http://127.0.0.1:8444, with a Let's Encrypt certificate. The page runs as the user missus-me and can't read /srv/missus; a backend on a Unix socket checks the current password, allows 5 attempts per address and 20 per IP every 15 minutes, writes the new hash and closes the open IMAP/POP3 sessions. Tell your users to enter the new password in their mail apps right away: most apps (K-9 included) never ask, they just keep retrying the old one.

8. DMARC aggregate reports

DMARC report ingest is one of the things you'd otherwise pay $20–200/month for as a SaaS. missus does it inline with the rest of the panel.

On /dmarc/<domain>/enable, missus does three things in one step:

  1. Creates a mailbox dmarc@<domain> with a generated password (shown once, then never again — save it).
  2. Updates the DMARC TXT record advice to include rua=mailto:dmarc@<domain>. Re-publish the record from /dns-advice.
  3. Enables a daily systemd timer (missus-dmarc-poll.timer) that walks the dmarc@ Maildir, ingests attached XML / ZIP / GZ reports, and stores aggregate stats in state.db.

Within 24 h Gmail, Microsoft, Yahoo and dozens of other receivers start mailing reports. The /dmarc/<domain> dashboard shows: total messages observed, alignment percentage, top sources, top failing IPs.

Manual import for a one-off report or to backfill: missus dmarc import path/to/report.xml.gz.

9. Queue & live monitoring

The /queue page reads postqueue -p and lays it out as a sortable table. For each message you can hold, release, requeue, or delete. Filtering by sender or recipient is one click.

The /system/live dashboard auto-refreshes every few seconds and shows: postfix queue depth (active / deferred / hold), dovecot active sessions, Rspamd action breakdown over the last 5 minutes, recent log lines. Useful when you're chasing "did this message land?" in real time.

The Blocklists card on the same page answers the other question: is this server listed? Every hour (missus-rbl.timer) the public IPv4/IPv6 set in /system/server are checked on Spamhaus ZEN, SpamCop and PSBL; Check now runs it at once, and so does the CLI:

sudo missus rbl check     # exit 1 = listed, 2 = blind
sudo missus telegram test

Every change (listed, delisted, the check going blind) is sent to Telegram: create a bot with @BotFather, then put its token and your chat id (ask @userinfobot) under /system/server → Telegram alerts. The token is never shown again once saved.

10. Backups & migration

Everything missus owns lives under /srv/missus/ — Maildirs, state.db, DKIM private keys, certbot live tree. Backup is plain rsync.

sudo rsync -aHAX --delete /srv/missus/ backup-host:/srv/missus-snapshot/

# new box, after `apt install missus`
sudo rsync -aHAX backup-host:/srv/missus-snapshot/ /srv/missus/
sudo missus rehydrate

missus rehydrate re-emits the per-mailbox sieve scripts and the postfix/dovecot/rspamd configs from /srv/missus/ on the new host, then reloads each daemon.

For granular restore (a single mailbox, a whole domain) the /backup page bundles tarballs you can pick apart at restore time.

11. Troubleshooting

First stop:

sudo missus check

Walks filesystem, daemons, listening ports (25/465/587/993/995), postfix wiring (virtual_mailbox_domains, virtual_alias_maps), and reports each step ✓ / ! / ✗.

Blocklist check "blind"? The resolver on 127.0.0.1 doesn't get answers from Spamhaus:

dig @127.0.0.1 2.0.0.127.zen.spamhaus.org +short
# 127.0.0.2 127.0.0.4 127.0.0.10  → fine
# 127.255.255.254                  → it goes through a public resolver
#   (nomina: empty the forwarders), then flush the old answer:
sudo rndc flush
sudo missus apply          # Rspamd switches to 127.0.0.1 too
sudo missus rbl check

Daemon logs:

sudo journalctl -u postfix -n 100 --no-pager
sudo journalctl -u dovecot -n 100 --no-pager
sudo journalctl -u rspamd -n 100 --no-pager
sudo journalctl -u missus -n 100 --no-pager

For mail-flow debugging, follow /var/log/mail.log while you send a test message. The Postfix queue ID lets you grep the entire path through smtpd, cleanup, qmgr, smtp.

If you ever need to nuke missus and rebuild: apt purge missus intentionally does not delete /srv/missus/. Maildirs and DKIM keys are user data — even cascade purges from unrelated package removals leave your data alone. To actually wipe, remove the directories by hand — sudo rm -rf /srv/missus /etc/missus — that's an explicit, deliberate action you have to take.