Initial docs: alpha.jayfield.org server documentation
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
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
# 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
|
||||
|
||||
```bash
|
||||
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:
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
sudo mysql vmail -e "INSERT INTO accounts (username, domain, password, quota, enabled, sendonly) VALUES ('newuser', 'jayfield.org', '{SHA512-CRYPT}\$6\$...', 2048, 1, 0);"
|
||||
```
|
||||
- `quota` is in **MB** (existing accounts use `2048` = 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 to `0` disables the account without deleting it (see
|
||||
§6).
|
||||
- `sendonly = 0` — normal mailbox: can send *and* receive. Set to `1` only
|
||||
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`:
|
||||
```bash
|
||||
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:
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user