Mischa323/dmarc-dashboard
GitHub: Mischa323/dmarc-dashboard
一个用于自动拉取和分析Microsoft 365 DMARC聚合报告的自托管仪表盘,帮助提升邮件安全性和合规性。
Stars: 0 | Forks: 0
# DMARC 仪表盘
一个自托管的仪表盘,通过 Microsoft Graph API 从 **Microsoft 365 邮箱** 读取 DMARC 聚合报告,并通过交互式图表将结果可视化。
## 功能
- 自动从 Office 365 邮箱读取 DMARC 报告邮件(`.xml`, `.xml.gz`, `.zip`)
- 解析 RFC 7489 聚合报告并将其存储在本地 SQLite 数据库中
- 交互式仪表盘 — 通过率/失败率、每日量趋势、失败原因分布、顶级 IP 和组织
- 多租户支持,支持每个租户独立的 Microsoft SSO 登录
- 后台调度器,支持全局和每个租户独立的获取间隔
- 手动“立即获取”按钮
- DMARC DNS 健康检查,包括 RFC 7489 §7.1 跨域 `rua` 授权
- 本地管理员账户的双因素认证
- 毛玻璃风格界面,支持自定义颜色主题
## 安装
选择适合你环境的方法:
| 方法 | 适用场景 |
|---|---|
| [Docker CLI](#-docker-cli) | Linux 服务器、NAS 设备、快速安装 |
| [Portainer](#-portainer) | 偏好 Web 界面的 Portainer 用户 |
| [Node.js](#-nodejs-without-docker) | 开发或无 Docker 的服务器 |
## environment variables file, so I should keep it as ".env" since it's a common term.
### 1. 下载 compose 文件
```
mkdir dmarc-dashboard && cd dmarc-dashboard
curl -O https://raw.githubusercontent.com/Mischa323/dmarc-dashboard/master/docker-compose.yml
```
### 2. (可选)创建 `.env` 文件以自定义端口
```
PORT=3443
```
跳过此步骤将使用默认端口 `3443`。
### 3. 启动
```
docker compose up -d
```
Docker 将从 GHCR 拉取预构建镜像 — 无需编译。
### 4. 打开设置向导
访问 `https://:3443`,按照 3 步向导创建管理员账户并连接你的第一个 Microsoft 365 租户。
### 更新
```
docker compose pull && docker compose up -d
```
### 启用自动更新 (Watchtower)
将以下服务添加到 `docker-compose.yml`,以便 Watchtower 在发布新镜像时自动拉取并重启容器:
```
watchtower:
image: containrrr/watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_LABEL_ENABLE: "true"
WATCHTOWER_CLEANUP: "true"
WATCHTOWER_POLL_INTERVAL: "86400" # seconds — 86400 = every 24 hours
command: --label-enable
```
`dmarc-dashboard` 服务已设置 `watchtower.enable=true` 标签,因此 Watchtower 将只管理此容器。
### 反向代理
在 `.env` 中设置 `HTTP_MODE=1` 以监听纯 HTTP(用于 nginx / Traefik 终止 TLS):
```
PORT=3000
HTTP_MODE=1
```
## - "a self-signed TLS certificate" – "self-signed" is a term, "TLS certificate" is technical, so I should translate "self-signed TLS certificate" but keep "TLS" in English? Based on examples, 'API Reference' -> 'API 参考', so acronyms like API are kept. Similarly, "TLS" might be kept as is.
### 1. 打开 Stacks
在 Portainer 中,进入 **Stacks → Add stack**。
### 2. 命名 stack
输入名称,例如 `dmarc-dashboard`。
### 3. 粘贴到 Web 编辑器
复制下方的整个代码块并粘贴到 **Web 编辑器**:
```
services:
dmarc-dashboard:
image: ghcr.io/mischa323/dmarc-dashboard:latest
restart: unless-stopped
ports:
- "3443:3443"
volumes:
- dmarc_data:/data
environment:
PORT: "3443"
DATABASE_URL: "/data/dmarc.db"
CERTS_DIR: "/data/certs"
# Uncomment the line below when running behind a reverse proxy (nginx/Traefik):
# HTTP_MODE: "1"
labels:
- "com.centurylinklabs.watchtower.enable=true"
volumes:
dmarc_data:
```
### 4. 部署 stack
点击 **Deploy the stack**。Portainer 将拉取镜像,创建 `dmarc_data` 卷,并启动容器。
### 5. 打开设置向导
访问 `https://:3443`,按照 3 步向导创建管理员账户并连接你的第一个 Microsoft 365 租户。
### 更新
进入 **Stacks → dmarc-dashboard**,点击 **Pull and redeploy**。`dmarc_data` 卷将被保留。
### 启用自动更新 (Watchtower)
在 Web 编辑器中将 Watchtower 服务添加到你的 stack,使其与 `dmarc-dashboard` 并列:
```
watchtower:
image: containrrr/watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_LABEL_ENABLE: "true"
WATCHTOWER_CLEANUP: "true"
WATCHTOWER_POLL_INTERVAL: "86400" # seconds — 86400 = every 24 hours
command: --label-enable
```
然后点击 **Update the stack**。Watchtower 将每 24 小时检查新镜像并自动重启容器。
**更改检查间隔:**
| 频率 | `WATCHTOWER_POLL_INTERVAL` |
|---|---|
| 每小时 | `3600` |
| 每 6 小时 | `21600` |
| 每 24 小时 | `86400` |
## 🟢 Node.js(无 Docker)
### 要求
- Node.js 20+
- 一个 Microsoft Entra (Azure AD) 应用注册
### 步骤
```
# - So, translation: "2. 启动 — .env 和自签名 TLS 证书自动生成"
git clone https://github.com/Mischa323/dmarc-dashboard.git
cd dmarc-dashboard
npm install
# - I need to ensure it flows naturally in Chinese.
node server.js
# 5. 3. Open https://localhost:3443 and follow the setup wizard
```
使用不同的端口:
```
PORT=8443 node server.js
```
或在首次运行生成的 `.env` 文件中添加 `PORT=8443`。
## Azure 应用注册
1. 进入 **Entra 管理中心 → 应用注册 → 新建注册**
2. 命名(例如 `DMARC Dashboard`),选择单租户,邮件获取无需重定向 URI
3. **API 权限 → 添加权限 → Microsoft Graph → 应用程序权限**
- `Mail.Read` — 用于读取报告邮件
- `User.Read.All` — SSO 用户查找所需(如果不使用 SSO 则为可选)
4. 授予管理员同意
5. **证书和机密 → 新建客户端机密** — 立即复制其值
6. 记下概述页面上的**租户 ID** 和**应用程序(客户端)ID**
7. 在仪表盘的租户配置界面输入这些值
应用使用 **客户端凭据流** — 邮件获取无需交互式用户登录。
## 配置
| 变量 | 描述 | 默认值 |
|---|---|---|
| `PORT` | 监听端口 | `3443` |
| `SECRET` | 会话密钥 | 自动生成,保存到 `/data/.secret` |
| `DATABASE_URL` | SQLite 数据库路径 | `dmarc.db` / `/data/dmarc.db` |
| `CERTS_DIR` | TLS 证书和密钥目录 | `./certs` / `/data/certs` |
| `HTTP_MODE` | 设置为 `1` 以使用纯 HTTP(反向代理模式) | — |
租户凭据(租户 ID、客户端 ID、客户端机密、邮箱)存储在数据库中,并通过管理界面管理 — 非环境变量。
## DMARC DNS 设置
将你的域名的 `rua` 标签指向已配置的邮箱:
```
_dmarc.yourdomain.com TXT "v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com"
```
如果报告邮箱与被监控域名**不同域**,需要添加授权记录 (RFC 7489 §7.1):
```
yourdomain.com._report._dmarc.mailboxdomain.com TXT "v=DMARC1;"
```
仪表盘的 DNS 健康检查可检测缺失的授权记录并显示需要添加的确切记录。
## 项目结构
```
dmarc-dashboard/
├── server.js Entry point — starts HTTPS/HTTP server
├── src/
│ ├── app.js Express app factory
│ ├── config.js Environment config, secret and .env generation
│ ├── db.js SQLite schema, migrations, helpers
│ ├── dmarcParser.js RFC 7489 XML parser
│ ├── fetcher.js Fetch and persist reports
│ ├── graphClient.js Microsoft Graph API client
│ ├── msalHelper.js MSAL token acquisition
│ ├── scheduler.js Background fetch scheduler
│ ├── tenantTest.js DNS and connectivity health checks
│ └── routes/
│ ├── admin.js Admin UI routes
│ ├── api.js JSON API for the dashboard
│ ├── auth.js Local login, SSO, 2FA
│ ├── main.js Dashboard and reports pages
│ └── setup.js First-run setup wizard
├── views/ EJS templates
├── Dockerfile
├── docker-compose.yml
└── .env.example
```
## 许可证
MIT
标签:DMARC, DNS健康检查, Docker, GNU通用公共许可证, Microsoft Graph API, MITM代理, Mutation, Node.js, Office 365, RFC 7489, SQLite, XML解析, 交互式图表, 仪表板, 双因素认证, 可视化, 合规工具, 域名认证, 安全防御评估, 报告分析, 聚合报告, 自托管, 请求拦截, 调度器, 邮件安全, 邮箱监控