Commit 8bbe609c authored by Vitaly Lipatov's avatar Vitaly Lipatov

mail skill: document Let's Encrypt cert renewal and deploy-hook

Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
parent 0997f97a
...@@ -21,6 +21,23 @@ Execute mail management task: $ARGUMENTS ...@@ -21,6 +21,23 @@ Execute mail management task: $ARGUMENTS
- Autoconfig XML: `/var/www/autoconfig/` on mail.etersoft.ru - Autoconfig XML: `/var/www/autoconfig/` on mail.etersoft.ru
- Roundcube: `/etc/roundcube/config.inc.php` on 10.20.30.66 - Roundcube: `/etc/roundcube/config.inc.php` on 10.20.30.66
## TLS certificate (Let's Encrypt)
Cert: `mail.etersoft.ru` + 15 SAN (autoconfig/autodiscover/imap.*/smtp.* over etersoft.ru/com/net/org + mail.eterhost.ru, smtp.eterhost.ru). 90-day, renews weekly.
- Live: `/etc/letsencrypt/live/mail.etersoft.ru/{fullchain,privkey}.pem`
- Renewal: `/etc/cron.weekly/letsencrypt``certbot renew`, **webroot** at `/var/spool/nginx/tmp/client` (conf: `/etc/letsencrypt/renewal/mail.etersoft.ru.conf`). **nginx MUST be up** for webroot — do NOT stop it around renew (leftover `serv nginx stop` from old standalone auth silently broke renewals: "All renewals failed").
- Deploy hook: `/etc/letsencrypt/renewal-hooks/deploy/update_pem.sh` (symlink → `/etc/postfix/tls/update_pem.sh`). Runs after EVERY successful renewal and pushes the live cert into the mail daemons:
- Postfix — ONE combined cert+key file `/etc/postfix/tls/mail.etersoft.ru_full.pem` (`smtpd_tls_cert_file = smtpd_tls_key_file` = same path in `main.cf`)
- Cyrus — cert `/var/lib/imap/ssl/mail.etersoft.ru.crt`, key `/var/lib/imap/ssl/etersoft.pem` (`tls_server_cert`/`tls_server_key` in `/etc/imapd.conf`)
- reloads postfix, cyrus-imapd, nginx.
- nginx reads live `fullchain.pem` directly (`/etc/nginx/sites-enabled.d/mail.etersoft.ru.conf`).
### Check / diagnose
- Served vs live: `openssl s_client -connect mail.etersoft.ru:993 -servername mail.etersoft.ru </dev/null | openssl x509 -noout -dates` vs `certbot certificates`. Divergent dates = daemon copies stale (deploy hook didn't run).
- Check ALL ports: 993 (IMAPS), 465 (SMTPS), 25/587 (STARTTLS), 443 (HTTPS).
- Hook must live in `/etc/letsencrypt/renewal-hooks/deploy/` (fires on any renewal incl. manual) — NOT only as deprecated `--renew-hook` on the cron line (manual `certbot --expand` would skip it → mail stuck on expired cert).
- Force fresh deploy: `certbot renew` (nginx up) — hook fires and redeploys.
- Renewal log: `/var/log/letsencrypt/letsencrypt.log` (`Running deploy-hook command:` confirms hook fired).
## CRITICAL: defaultdomain Hoffice.etersoft.ru ## CRITICAL: defaultdomain Hoffice.etersoft.ru
**NEVER change this!** The `H` prefix is intentional. When defaultdomain matches login domain, Cyrus strips domain from userid → SASL gets username without @domain → auth breaks. `Hoffice` doesn't match any real domain → full userid preserved. **NEVER change this!** The `H` prefix is intentional. When defaultdomain matches login domain, Cyrus strips domain from userid → SASL gets username without @domain → auth breaks. `Hoffice` doesn't match any real domain → full userid preserved.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment