Records the host's service inventory, setup runbook, mail account list, sync plan, package diff vs. clean install, and hardening TODOs, including today's SSH hardening (key-only, no root login) and the fail2ban sshd findtime fix for a low-and-slow brute-force evasion pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RdTyvEJkfNLDVAWt8WQ6X9
5.5 KiB
alpha.jayfield.org — Adding Email Accounts (How-To)
Accounts, aliases, and domains for the mail stack (Postfix + Dovecot) all
live in one place: the vmail MySQL database on this host. There's no
admin UI — everything below is a mysql insert plus one hash-generation
command. See SETUP.md §3 for how this schema was built in the first
place; this doc is just the day-to-day "add a mailbox" recipe.
No service restart is ever needed for account changes. Postfix and
Dovecot query MySQL live on every delivery/login (auth_cache_size is
unset/disabled on this host — verified in /etc/dovecot/conf.d/10-auth.conf)
so a new row is usable immediately.
1. Prerequisite: the domain must already exist
sudo mysql vmail -e "SELECT * FROM domains;"
Currently just jayfield.org. If you ever need a second domain, insert it
here first (INSERT INTO vmail.domains (domain) VALUES ('newdomain.tld');)
— but note that's the easy part; a real second domain also needs its own
DNS zone/MX/SPF/DMARC records and DKIM selector (see SETUP.md §2/§3), a
TLS cert covering it, and its own mynetworks/inet_interfaces
consideration. Out of scope for just adding a mailbox — this doc assumes
jayfield.org.
2. Generate the password hash
Never put a plaintext password in the accounts table — hash it first:
sudo doveadm pw -s SHA512-CRYPT
(You'll be prompted twice, interactively — don't pass the password as a
CLI argument, it'd land in shell history.) Copy the full
{SHA512-CRYPT}$6$... output; that's the exact string that goes in the
password column.
You may see Error: net_connect_unix(/run/dovecot/stats-writer) failed: Permission denied printed before the hash — that's doveadm trying to
report stats, unrelated to the hash it prints right after; harmless, not a
sign the hash is wrong.
3. Insert the account
sudo mysql vmail -e "INSERT INTO accounts (username, domain, password, quota, enabled, sendonly) VALUES ('newuser', 'jayfield.org', '{SHA512-CRYPT}\$6\$...', 2048, 1, 0);"
quotais in MB (existing accounts use2048= 2GB — match that unless there's a reason not to).enabled = 1— required for the account to authenticate or receive mail at all. Setting it to0disables the account without deleting it (see §6).sendonly = 0— normal mailbox: can send and receive. Set to1only for a send-only address that should never accept incoming mail (see §5).
That's it — no mailbox directory to create by hand. Dovecot auto-creates
/var/vmail/mailboxes/jayfield.org/<user>/mail/ (owned vmail:vmail,
700) the first time the account logs in or receives mail.
4. Client configuration (no webmail — this stack is IMAP/SMTP only)
| Setting | Value |
|---|---|
| IMAP (recommended) | mail.jayfield.org : 993, implicit TLS |
| IMAP (STARTTLS) | mail.jayfield.org : 143 |
| SMTP submission | mail.jayfield.org : 587, STARTTLS + SASL (PLAIN) auth required |
| Username | <user>@jayfield.org (full address, not just the local part) |
| Password | the plaintext password you hashed in §2 |
| Port 25 | not for clients — server-to-server only, no SASL, no relay (reject_unauth_destination) |
disable_plaintext_auth = yes is set — clients must actually negotiate TLS
first; a client configured for plaintext IMAP/SMTP on the wrong port will
just fail to auth, not silently send credentials in the clear.
5. Send-only accounts (sendonly = 1)
Postfix's recipient-access.cf query rejects any inbound mail to a
sendonly=1 address at RCPT TO time (450/550 before it's even
accepted), while the account can still authenticate via SASL on 587 and
send outbound. Use this for something like a monitoring/alerting sender
address that should never actually receive replies.
6. Aliases (forward one address to another mailbox)
Aliases don't need their own mailbox or password — they're a pure
redirect, resolved at RCPT TO time via aliases.cf:
sudo mysql vmail -e "INSERT INTO aliases (source_username, source_domain, destination_username, destination_domain, enabled) VALUES ('sales', 'jayfield.org', 'jens', 'jayfield.org', 1);"
This host already has postmaster/hostmaster/webmaster/wlan →
jens as standing aliases (RFC-required roles + a house one) — check
SELECT * FROM aliases; before adding a new one to avoid duplicates.
7. Disabling / removing an account
Prefer disabling over deleting — it's reversible and doesn't touch the Maildir:
sudo mysql vmail -e "UPDATE accounts SET enabled = 0 WHERE username = 'olduser' AND domain = 'jayfield.org';"
This blocks both authentication and inbound delivery immediately (both
accounts.cf and recipient-access.cf filter on enabled = true). The
actual mail data stays on disk at
/var/vmail/mailboxes/jayfield.org/olduser/ until you decide to remove it
by hand — nothing auto-deletes it.
8. Verify a new account end-to-end
Don't trust the INSERT alone — confirm both directions actually work,
same discipline as SETUP.md §7:
# IMAP auth works
doveadm auth test newuser@jayfield.org
# Watch a real inbound + outbound test the same way §7 of SETUP.md describes:
# send TO newuser@jayfield.org from an external provider, confirm in
# /var/log/mail.log:
# dovecot: lmtp(newuser@jayfield.org)<...>: sieve: msgid=<...>: stored mail into mailbox 'INBOX'
# then send FROM the new account via a real mail client on 587, confirm:
# postfix/submission/smtpd[...]: sasl_method=PLAIN, sasl_username=newuser@jayfield.org