Няма описание

Codex a3074bf002 fix: improve dns apply status and toast feedback преди 1 месец
certs bc997b5cda chore: initialize git baseline преди 1 месец
docker bc997b5cda chore: initialize git baseline преди 1 месец
public a3074bf002 fix: improve dns apply status and toast feedback преди 1 месец
src a3074bf002 fix: improve dns apply status and toast feedback преди 1 месец
test a3074bf002 fix: improve dns apply status and toast feedback преди 1 месец
.dockerignore bc997b5cda chore: initialize git baseline преди 1 месец
.env.example 23f51d7396 docs: update multi-user deployment guide преди 1 месец
.gitignore bc997b5cda chore: initialize git baseline преди 1 месец
Dockerfile bc997b5cda chore: initialize git baseline преди 1 месец
README.md 23f51d7396 docs: update multi-user deployment guide преди 1 месец
docker-compose.yml bc997b5cda chore: initialize git baseline преди 1 месец
package.json 05f5b67606 test: add auth smtp dns coverage преди 1 месец

README.md

MailHub

MailHub 是一个 Docker 化的多用户发信域名管理面板、SMTP Submission 服务和发送 API。它负责:

  • 开放注册用户账号,并隔离每个用户的域名、SMTP 凭据、DNS API 凭据和发送记录。
  • 为每个发信域名生成验证 TXT、DKIM key、SPF、DMARC、发信主机 A 记录建议。
  • 支持 Cloudflare、阿里云 DNS、腾讯云 DNSPod API,一键写入基础发信 DNS。
  • 读取公网 DNS,检查 SPF、DKIM、DMARC、PTR、发信主机 A 记录状态。
  • 通过内部 Postfix 出站队列发送邮件,并按发件域名加 DKIM 签名。

运行

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 可反代到公网域名。

账号和权限

  • 首次启动会根据 .env 中的 ADMIN_USERADMIN_EMAILADMIN_PASSWORD 创建或修复一个 admin 用户。
  • 普通用户可在 /register 开放注册。
  • 用户只能看到自己的域名、SMTP 凭据、DNS 凭据、API Token 和发送记录。
  • admin 用户可在网页里修改系统业务设置、查看用户列表、禁用或启用用户。

SMTP 发信

MailHub 提供公网 SMTP Submission。所有发信端口都需要 SMTP AUTH,未认证不会转发邮件,避免开放中继。

连接信息:

Host: 由 SUBMISSION_HOST 配置,例如 in.example.com
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 凭据”中配置,可复制

SMTP 密码会同时保存哈希和服务端加密密文:哈希用于认证,加密密文用于用户本人在网页复制。旧数据如果只有哈希,无法反解,需要用户重新设置一次密码后才能复制。

.env 中的 SUBMISSION_USERNAMESUBMISSION_PASSWORD 只用于首次给 admin 初始化 SMTP 凭据。初始化后以每个用户在面板保存的 SMTP 凭据为准,修改后无需重启。

DNS API 一键配置

用户可在网页“DNS API”中保存以下服务商凭据:

  • Cloudflare:API Token,建议只授予目标 Zone 的 DNS Edit 权限;可选 Zone ID。
  • 阿里云 DNS:AccessKeyId 和 AccessKeySecret。
  • 腾讯云 DNSPod:SecretId 和 SecretKey。

域名绑定 DNS 凭据后,点击“一键配置 DNS”会写入或更新:

  • _mailhub.<domain> TXT 验证记录。
  • <selector>._domainkey.<domain> DKIM TXT。
  • 根域 SPF TXT,并合并为一条 v=spf1
  • _dmarc.<domain> DMARC TXT。
  • 发信主机 A 记录。

PTR 反向解析只检测和提示,通常必须在云服务器或 IP 服务商控制台配置。

网页化系统设置

admin 可在面板中修改以下业务设置:

  • APP_BASE_URL
  • MAIL_HOSTNAME
  • SENDING_IP
  • DEFAULT_SPF_MECHANISMS
  • DMARC_POLICY
  • DMARC_RUA
  • SEND_REQUIRES_VERIFIED

基础设施设置仍通过 .env 配置并需要重启,例如监听端口、数据目录、SMTP 中继、TLS 证书路径和 SESSION_SECRET

发送 API

每个用户在面板生成自己的发送 API Token。Token 只在创建时完整显示并自动复制,之后列表只显示前缀。

curl -X POST http://mail-send.example.com/api/send \
  -H "Authorization: Bearer <USER_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "noreply@example.com",
    "to": "user@example.com",
    "subject": "Hello from MailHub",
    "text": "Signed with DKIM and queued by MailHub."
  }'

发送时会校验 From 所属域名必须归当前 Token 所属用户所有。.env 中的 API_TOKEN 仅作为旧版 admin 兼容发送 token,新用户应使用网页生成的用户级 Token。

测试

npm test

测试覆盖:

  • 旧 SQLite 数据迁移到 admin 用户。
  • 多用户域名、发送记录、SMTP 凭据、API Token 隔离。
  • SMTP 密码可复制明文与哈希认证。
  • Cloudflare、阿里云 DNS、腾讯云 DNSPod 的 mocked API 写入流程。

生产检查

  • 修改默认 admin 密码并设置足够长的 SESSION_SECRET
  • 不要提交 .env、SQLite 数据库、证书私钥或 DNS/API 密钥。
  • 服务器出站 25 端口没有被云厂商拦截。
  • 服务器入站 25/465/587/2525 已在云防火墙和系统防火墙放行。
  • SPF、DKIM、DMARC 均通过。
  • 发信 IP 的 PTR 指向 MAIL_HOSTNAME
  • MAIL_HOSTNAME 的 A 记录指回发信 IP。
  • 新 IP 先小流量预热,避免突然大批量发送。