|
|
1 maand geleden | |
|---|---|---|
| .github | 1 maand geleden | |
| docker | 1 maand geleden | |
| docs | 1 maand geleden | |
| public | 1 maand geleden | |
| scripts | 1 maand geleden | |
| src | 1 maand geleden | |
| test | 1 maand geleden | |
| .dockerignore | 1 maand geleden | |
| .env.example | 1 maand geleden | |
| .gitattributes | 1 maand geleden | |
| .gitignore | 1 maand geleden | |
| AGENTS.md | 1 maand geleden | |
| CHANGELOG.md | 1 maand geleden | |
| CODE_OF_CONDUCT.md | 1 maand geleden | |
| CONTRIBUTING.md | 1 maand geleden | |
| Dockerfile | 1 maand geleden | |
| LICENSE | 1 maand geleden | |
| README.md | 1 maand geleden | |
| SECURITY.md | 1 maand geleden | |
| SUPPORT.md | 1 maand geleden | |
| docker-compose.yml | 1 maand geleden | |
| index.html | 1 maand geleden | |
| landing.html | 1 maand geleden | |
| login.html | 1 maand geleden | |
| package-lock.json | 1 maand geleden | |
| package.json | 1 maand geleden | |
| tsconfig.json | 1 maand geleden | |
| vite.config.ts | 1 maand geleden | |
| vitest.config.ts | 1 maand geleden |
MailHub 是一个 Docker 化的多用户发信控制面板、SMTP Submission 服务和发送 API。它面向需要自托管出站邮件能力的团队,提供域名验证、DKIM 签名、DNS 配置提示、SMTP 凭据和 API Token 管理。
>=24.0.0node:testcp .env.example .env
npm install
npm test
npm run build
docker compose up -d --build
docker compose logs -f app postfix
默认管理面板通过 APP_PORT 暴露到宿主机 127.0.0.1:3025。生产环境建议使用 Nginx、Caddy 或其他反向代理提供 HTTPS。
首次启动前务必修改 .env 中的默认管理员密码、SESSION_SECRET、SMTP 凭据和域名/IP 配置。
以 .env.example 为模板创建 .env。常用配置包括:
APP_BASE_URL:管理面板和发送 API 的公网访问地址。MAIL_HOSTNAME:出站邮件 HELO、Postfix myhostname 和 DNS 指南中的发信主机名。SENDING_IP:发信服务器公网 IP。SESSION_SECRET:会话和服务端加密使用的随机密钥,生产环境必须使用强随机值。SUBMISSION_HOST、SUBMISSION_PORTS:SMTP Submission 对外连接信息。SUBMISSION_TLS_CERT、SUBMISSION_TLS_KEY:TLS 证书路径。证书文件应放在本地 certs/,不要提交到 Git。DEFAULT_SPF_MECHANISMS:需要保留的第三方 SPF include,例如事务邮件服务商。SEND_REQUIRES_VERIFIED:是否要求域名 DNS 验证通过后才能发信。LIST_UNSUBSCRIBE_MAILTO、LIST_UNSUBSCRIBE_URL:可选退订头配置,支持 {eventId}、{recipient}、{sender}、{domain}、{userId} 占位符。LIST_UNSUBSCRIBE_POST_ENABLED:是否添加 one-click 退订头;仅在退订 URL 真正支持合规 POST 时开启。FEEDBACK_ID_ENABLED:是否为 API 发信添加不含明文邮箱的 Feedback-Id。REPORT_ABUSE_TO、CSA_COMPLAINTS_TO:可选投诉处理邮箱头。BOUNCE_ADDRESS、BOUNCE_ENVELOPE_ENABLED:可选退信 envelope sender;确认 bounce 邮箱/域名可收信和处理前不要开启。MailHub 提供公网 SMTP Submission。所有发信端口都需要 SMTP AUTH,未认证请求不会转发邮件,避免开放中继。
Host: 由 SUBMISSION_HOST 配置,例如 smtp.mailhub.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 密码会同时保存哈希和服务端加密密文:哈希用于认证,加密密文用于用户本人在网页复制。旧数据如果只有哈希,无法反解,需要用户重新设置一次密码后才能复制。
每个用户可以在面板生成自己的 API Token。新 Token 会以哈希用于认证,并以服务端加密密文供所属账号在面板完整查看和复制;升级前创建、仅保存哈希的历史 Token 无法反解,可在面板确认后重新生成。
Token 支持以下权限:
send:发送邮件。mailboxes:read:查询可访问邮箱的元数据。mailboxes:write:创建长期或临时邮箱。messages:read:查询收到的邮件列表、文件夹和邮件正文。收信读取还受 Token 邮箱范围约束:默认仅 Token 所有者名下邮箱,也可限定到指定邮箱;管理员可显式授予全系统邮箱读取权限。该范围同样约束带 mailboxes:read 权限的邮箱元数据列表。
curl -X POST https://mailhub.example.com/api/send \
-H "Authorization: Bearer <USER_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@example.com",
"to": "user@example.net",
"subject": "Hello from MailHub",
"text": "Signed with DKIM and queued by MailHub."
}'
发送时会校验 From 所属域名必须归当前 Token 所属用户所有。.env 中的 API_TOKEN 仅作为旧版 admin 兼容发送 token,新用户应使用网页生成的用户级 Token。
查询收信列表和邮件详情:
curl -H "Authorization: Bearer <INBOUND_API_TOKEN>" \
"https://mailhub.example.com/api/inbound-messages?page=1&pageSize=20&folder=INBOX&read=false"
curl -H "Authorization: Bearer <INBOUND_API_TOKEN>" \
"https://mailhub.example.com/api/inbound-messages/123"
curl -H "Authorization: Bearer <INBOUND_API_TOKEN>" \
"https://mailhub.example.com/api/inbound-mailboxes/42/folders"
列表接口支持 page、pageSize、mailboxId、folder、read 和 q;详情接口返回 rawMessage、textBody 与 htmlBody;文件夹接口返回标准用途、邮件数和未读数。未授权邮箱不会出现在列表中,直接读取详情或文件夹时返回 404。
用户可在网页“DNS API”中保存以下服务商凭据:
域名绑定 DNS 凭据后,点击“一键配置 DNS”会写入或更新验证 TXT、DKIM TXT、SPF TXT、DMARC TXT 和发信主机 A 记录。PTR 反向解析只检测和提示,通常必须在云服务器或 IP 服务商控制台配置。
生产环境建议:
/opt/mailhub。.env.example 创建 .env,填写真实域名、IP、证书路径和强随机密钥。certs/ 目录,确保私钥不会进入 Git。如证书由宝塔等主机端工具续期,可在 .env 中设置 MAILHUB_CERT_SOURCE_DIR,该目录需包含 fullchain.pem 和 privkey.pem。docker compose up -d --build。127.0.0.1:${APP_PORT}。可选的远程部署脚本需要显式提供目标服务器和目录:
MAILHUB_DEPLOY_REMOTE=deploy@example.com \
MAILHUB_DEPLOY_DIR=/opt/mailhub \
MAILHUB_DEPLOY_BRANCH=main \
npm run deploy:remote
脚本会要求本地 HEAD 已推送到对应远端分支,然后在目标目录执行 git pull --ff-only 和 docker compose up -d --build,并等待 app、postfix 都进入健康状态。如果目标工作区存在未提交变更,脚本会停止;确认可暂存远端工作区时,可显式设置 MAILHUB_DEPLOY_STASH_REMOTE=1。
配置 MAILHUB_CERT_SOURCE_DIR 后,发布脚本会先把主机证书复制为受控快照,再校验有效期、主机名和公私钥匹配。同步过程带并发锁和失败回滚,目标证书固定为 0644,私钥固定为 0640 并授权给实际运行中的 app 容器组。证书变化后会重启 app,并通过容器端口 465、993 的 SNI、证书链、主机名和 SHA-256 指纹确认服务已加载新证书。
同一脚本可由宝塔计划任务定期执行;宝塔仍负责申请和续期证书,MailHub 只读取续期结果:
cd "/opt/mailhub" && MAILHUB_CERT_RESTART=1 ./scripts/sync-tls-certificate.sh
默认验证容器端口 465 993。若部署明确关闭了其中一个 TLS 服务,可通过 MAILHUB_CERT_VERIFY_ENDPOINTS 调整;离线同步且无法检测 app 容器组时,必须显式设置 MAILHUB_CERT_READER_GID。
npm test
npm run build
测试覆盖数据库迁移、多用户隔离、SMTP 凭据、API Token、DNS 服务商逻辑、DKIM、投递日志解析和前端纯逻辑模型。
.env、SQLite 数据库、API Token、SMTP 密码、DNS API 密钥、证书私钥或真实生产证书。SESSION_SECRET。25/465/587/2525 已在云防火墙和系统防火墙放行。欢迎提交 issue 和 pull request。开始前请阅读 CONTRIBUTING.md、CODE_OF_CONDUCT.md 和 SECURITY.md。
MailHub 使用 MIT License。详见 LICENSE。