# MailHub MailHub 是一个 Docker 化的发信域名管理面板和发送 API。它负责: - 添加发信域名并生成验证 TXT。 - 为每个域名生成 DKIM key 和 DNS 记录。 - 读取当前公网 DNS,合并已有 SPF 和第三方发信 include。 - 给出 SPF、DKIM、DMARC、PTR、发信主机 A 记录的状态和建议。 - 通过内部 Postfix 出站队列发送邮件,API 会先给邮件加 DKIM 签名。 ## 运行 ```bash cd /www/wwwroot/mail.ss5.xyz docker compose up -d --build docker compose ps docker compose logs -f app postfix ``` 管理面板默认监听宿主机 `127.0.0.1:3025`,nginx 已反代到 `mail-send.ss5.xyz`。 面板使用 HTML 登录页和 Cookie 会话。登录账号和 API Token 在 `.env`: - `ADMIN_USER` - `ADMIN_PASSWORD` - `API_TOKEN` - `SESSION_SECRET` 可选;不设置时会从管理密码和 API Token 派生。 ## SMTP 公网发信 MailHub 现在提供公网 SMTP Submission。所有发信端口都需要 SMTP AUTH,未认证不会转发邮件,避免开放中继。 连接信息: ```txt Host: in.ss5.xyz Port 25: SMTP + STARTTLS + AUTH Port 587: SMTP Submission + STARTTLS + AUTH Port 465: SMTPS implicit TLS + AUTH Port 2525: SMTP + STARTTLS + AUTH Username: 在面板左侧“SMTP 凭据”中配置 Password: 在面板左侧“SMTP 凭据”中配置,保存后不会回显 ``` 默认 `SUBMISSION_ALLOW_INSECURE_AUTH=false`,也就是 `25/587/2525` 必须先 STARTTLS 才允许 AUTH;`465` 连接建立时就是 TLS。 `.env` 中的 `SUBMISSION_USERNAME` 和 `SUBMISSION_PASSWORD` 只用于首次初始化数据库。初始化后以面板保存的 SMTP 凭据为准,修改后无需重启。 当前 TLS 证书位于: ```txt certs/mail-send.ss5.xyz.crt certs/mail-send.ss5.xyz.key ``` 这是一张自签名证书,只用于先把协议跑通。正式公网使用建议替换为包含 `in.ss5.xyz` 的可信证书,然后重启: ```bash docker compose up -d app ``` ## 当前默认配置 ```env MAIL_HOSTNAME=in.ss5.xyz SENDING_IP=8.231.54.11 DEFAULT_SPF_MECHANISMS=include:spf.mailjet.com SMTP_HOST=postfix SMTP_PORT=25 ``` 如果实际出站 IP 不是 `8.231.54.11`,需要同步修改 `.env` 和面板里对应域名的“发信 IP”。 ## DNS 重点 SPF 只能保留一条 `v=spf1` TXT。不要为了 Mailjet、飞书、本机发信分别添加多条 SPF;要合并为一条。 ## in.ss5.xyz 测试记录 请为 `in.ss5.xyz` 添加或确认以下记录: ```txt in.ss5.xyz. A 8.231.54.11 ``` ```txt _mailhub.in.ss5.xyz. TXT mailhub-verification=9e45358e44624ce991c655e9c19b847f8c98 ``` ```txt mh202607._domainkey.in.ss5.xyz. TXT v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuaQrn0IrsNDVsbn160yOR7DMBaOkXegtlhUCvHYdKCy5Aa/rUcGvUI3gbLoo6m9QEiLs3EAJo29Y9RBbv3lQn/PvAKtfrTuT6Zo1BfcIhe9wJvipgAkH+hFmB4aNZ7MMTKE7vOztOHJooyyiJSHhgBqCVSG4fP7hr+vz5X8kAPXfasQnChHAmA1zM/m41/7qyo78C4pbqBiMAkkGV0zwNhaR1Fy1hdKx4IGpmrMrm5/sye4MK8dMD3jXooJ1Efv+Sh0HjpvKrN8zcxqvNDPusmIgZBxCN49m4R0dYsldK/v/KOeQJVfd+B6U0/2O8p2JHpd5Y1eaJjbREvFsKI30aQIDAQAB ``` ```txt in.ss5.xyz. TXT v=spf1 ip4:8.231.54.11 a:in.ss5.xyz include:spf.mailjet.com ~all ``` ```txt _dmarc.in.ss5.xyz. TXT v=DMARC1; p=none; rua=mailto:dmarc@in.ss5.xyz; adkim=s; aspf=s; pct=100 ``` 还需要在 IP 服务商控制台设置反向解析: ```txt 8.231.54.11 PTR in.ss5.xyz ``` 当前检测到 `8.231.54.11` 的 PTR 仍是 `11.54.231.8.bc.googleusercontent.com`。 当前 `ss5.xyz` 已检测到两条 SPF,建议合并为: ```txt v=spf1 include:spf.mailjet.com include:_netblocks.m.feishu.cn include:spf.ss5.xyz.com include:spf.97admin.com ip4:8.231.54.11 a:ali.ss5.xyz -all ``` 当前测试发信主机使用 `in.ss5.xyz`,它应当解析到 `8.231.54.11`。二者需要保持对齐: - 如果由当前 Docker 服务器发信,把 `in.ss5.xyz` A 记录和 IP 的 PTR 都指向 `8.231.54.11`。 - 如果实际由 `39.108.92.239` 发信,把 `.env` 和域名设置里的 `SENDING_IP` 改为 `39.108.92.239`。 PTR 反向解析需要在云厂商或 IP 服务商控制台设置,普通域名 DNS 控制台不能设置。 ## 发送 API ```bash curl -X POST http://mail-send.ss5.xyz/api/send \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "from": "noreply@ss5.xyz", "to": "user@example.com", "subject": "Hello from MailHub", "text": "Signed with DKIM and queued by Postfix." }' ``` SMTP 发信时,`Host` 使用 `in.ss5.xyz`。任意已添加并完成 DNS 配置的发信域名,都可以使用该域名下任意邮箱地址作为 `From`,例如 `notice@example.com`、`billing@example.com`、`noreply@example.com`。本服务会按 `From` 所属域名查找 DKIM 私钥并签名。 生产发信前确认: - 服务器出站 25 端口没有被云厂商拦截。 - 服务器入站 `25/465/587/2525` 已在云防火墙和系统防火墙放行。 - SPF、DKIM、DMARC 均通过。 - 发信 IP 的 PTR 指向 `MAIL_HOSTNAME`。 - `MAIL_HOSTNAME` 的 A 记录指回发信 IP。 - 新 IP 先小流量预热,避免突然大批量发送。