This is an old revision of the document!
Chatmail Relay: https://mail.haacknet.org
Official docs: https://chatmail.at/doc/relay/getting_started.html Ticket for Trixie: https://github.com/chatmail/relay/issues/476
Set up Debian 12 machine and a dedicated non-root user that will ssh into the root user and deploy the instance. Exchange keys etc., and make sure to use a ed25519 key. Once that's done, setup all DNS before starting and make sure all required packages are installed:
sudo apt install git rsync python3-venv python3-dev gcc libcrypt-dev
Then, as worker
ssh-keygen -t ed25519 -C "worker@$(hostname)" -f ~/.ssh/id_ed25519 chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 printf 'Host mail.haacknet.org\n HostName 127.0.0.1\n User root\n IdentityFile ~/.ssh/id_ed25519\n IdentitiesOnly yes\n' > ~/.ssh/config chmod 600 ~/.ssh/config git clone https://github.com/chatmail/chatmail.git cd ~/relay scripts/initenv.sh scripts/cmdeploy status mkdir -p ~/Repositories cd ~/Repositories git clone https://github.com/chatmail/relay cd relay scripts/initenv.sh scripts/cmdeploy init mail.haacknet.org
This creates chatmail.ini for you so that when you run cmdeploy it knows where to ssh and which instance to control, etc.
—
## 2. First deploy
``` cd ~/Repositories/relay scripts/cmdeploy run ```
This SSHes as root, installs the stack, writes Postfix/Dovecot/OpenDKIM/nginx, issues certs, starts services.
If it fails mid-way: fix the cause (SSH key, DNS A/AAAA already pointing at the box for HTTP-01, port 80 open), run `cmdeploy run` again. It is meant to be idempotent.
—
## 3. DNS at Hurricane Electric
TTL on HE for these was 14400 (4 hours). That is why Google `8.8.8.8` lagged. Authoritative check is `@ns1.he.net`, not `@8.8.8.8`.
Minimum records (names relative to zone `haacknet.org` or FQDN as you entered them):
| Name | Type | Value |
| — | — | — |
| `mail` | A | VPS IPv4 |
| `mail` | AAAA | VPS IPv6 |
| `mail` | MX | `10 mail.haacknet.org.` |
| `www.mail` | CNAME | `mail.haacknet.org.` |
| `mta-sts.mail` | CNAME | `mail.haacknet.org.` |
| `mail` | TXT | `v=spf1 a ~all` |
| `_dmarc.mail` | TXT | `v=DMARC1;p=reject;adkim=s;aspf=s` |
| `opendkim._domainkey.mail` | TXT | exact string from `cmdeploy dns` (DKIM `p=`) |
Plus whatever else `scripts/cmdeploy dns` prints (MTA-STS TXT `_mta-sts.mail`, maybe extra TLSA/HTTPS — use the command output as the checklist, not this table alone).
Print the checklist from the laptop:
``` cd ~/Repositories/relay scripts/cmdeploy dns ```
Verified live from the VPS after records existed:
``` dig @ns1.he.net TXT mail.haacknet.org # “v=spf1 a ~all”
dig @ns1.he.net TXT _dmarc.mail.haacknet.org # “v=DMARC1;p=reject;adkim=s;aspf=s”
dig @1.1.1.1 TXT mail.haacknet.org # same SPF ```
`cmdeploy dns` on the laptop still warned until the laptop resolver cache was cleared (reboot of netcmnd fixed it). Then:
``` Great! All your DNS entries are verified and correct. ```
Do not install Unbound on the VPS to “fix SPF”. Unbound is already there. Stale `8.8.8.8` is not the mail host.
—
## 4. Status and tests
``` scripts/cmdeploy status scripts/cmdeploy test ```
Status: all units listed above `active running`. Good.
Test result this session: 25 passed, 7 skipped, 2 failed.
Failures (not a broken relay):
1. `test_hide_senders_ip_address` — laptop could not `GET http://icanhazip.com:80` (`connection refused`). The test only uses that site to learn the client public IP so it can assert it is absent from mail headers. 2. `test_no_vrfy` — `TimeoutError` connecting to `mail.haacknet.org:25` from the laptop. Suite also skipped DKIM-from-outside tests with `port 25 not reachable for mail.haacknet.org`.
Skips for `CHATMAIL_DOMAIN2` are normal (no second relay configured).
Re-run one test:
``` scripts/cmdeploy test – -vv -k test_hide_senders_ip_address –tb=short ```
Skip the two environmental failures:
``` scripts/cmdeploy test – -vv –tb=short -k 'not test_hide_senders_ip_address and not test_no_vrfy' ```
`pytest -x` stops at first failure; that is why the first run looked “stalled.”
—
## 5. Day-to-day on any build machine
``` cd ~/Repositories/relay scripts/cmdeploy dns # zone check scripts/cmdeploy status # units scripts/cmdeploy run # apply git + chatmail.ini to the VPS scripts/cmdeploy test # online pytest ```
Upgrade relay software (not daily):
``` cd ~/Repositories/relay git pull origin main –rebase –autostash scripts/initenv.sh scripts/cmdeploy run ```
Or pin a tag: `git pull origin 1.10.0` (example; use a real tag from the repo).
You do not need to git pull just to run `dns` / `status`.
—
## 6. Several laptops + the VPS checkout
Rules that bit you in discussion:
- Copy one `chatmail.ini`. Do not `cmdeploy init` on machine #2. - Same git revision is nice-to-have; not required for `status`/`dns`. - Whoever runs `cmdeploy run` last overwrites the server to that tree + that ini. - `cmdeploy` always uses root SSH.
Copy ini + tree to another laptop:
``` scp ~/Repositories/relay/chatmail.ini other:/path/to/relay/chatmail.ini ```
SSH config on a remote laptop can stay `Host mail.haacknet.org` → public name. No need to force `HostName 127.0.0.1` unless you are on the VPS itself and hairpin to the public IP fails.
—
## 7. Management checkout on the VPS (`worker`)
You put the repo and the laptop’s `id_ed25519` on `/home/worker` instead of creating a `deploy` user.
Already done from netcmnd:
``` scp ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub root@mail.haacknet.org:/home/worker/.ssh/ scp -r ~/Repositories/relay root@mail.haacknet.org:/home/worker/ ```
On the VPS, as root:
``` apt install -y python3-venv python3-dev gcc libcrypt-dev rsync git ```
Then:
``` su - worker chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 cd ~/relay scripts/initenv.sh scripts/cmdeploy status ```
`authorized_keys` on root: already has this pubkey if that is how you SSH in from netcmnd. Do not append again unless `ssh root@mail.haacknet.org` from the `worker` account fails.
Do not add an SSH `HostName 127.0.0.1` stanza unless `cmdeploy` from `worker` cannot connect to `mail.haacknet.org` (hairpin). You explicitly rejected that complexity; hairpin first.
Do not run `cmdeploy init` on `worker`. The ini you copied is the one.
—
## 8. What not to do
- Dist-upgrade the mail VM to Trixie/Forky. - `apt install unbound` on the mail VM. - Hand-edit Dovecot/Postfix and expect it to survive the next `cmdeploy run`. - Second `cmdeploy init`. - Treat `8.8.8.8` as authority for your new TXT records (use `@ns1.he.net`). - Assume `cmdeploy test` from a LAN that blocks outbound 25 is a mail outage. - Put this relay on the same policy as your full Postfix+Dovecot mailbox servers (`jonathanhaack.com` etc.). Different job.
—
## 9. Clients
In Delta Chat / Arcane Chat, add account / use chatmail onboarding against `mail.haacknet.org`. Instant account create on first login is the point of doveauth.
Federation to other chatmail relays needs the full DNS set (`cmdeploy dns` green), not just A/AAAA.
—
## 10. Session outcome
- Relay installed and services up. - SPF + DMARC published at HE; Cloudflare already seeing SPF; laptop `cmdeploy dns` green after reboot. - Online tests: stack works; two failures are client-network (`icanhazip:80`, outbound `:25`). - Management copy: `worker@mail` + `~/relay` + `id_ed25519` + `initenv.sh` still to confirm with `cmdeploy status` from that user.
Check from `worker` when you next log in:
``` su - worker cd ~/relay scripts/cmdeploy dns scripts/cmdeploy status ```