commit 2999e562c732fd129c6489033e6408e2dc2ae668 Author: shenjianZ Date: Mon Jul 28 12:18:54 2025 +0800 mailu branch failed diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b90dbbc --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/backend/node_modules +/frontend/node_modules +/backend/package-lock.json +/frontend/package-lock.json \ No newline at end of file diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..8453a91 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,7 @@ +1.在终端执行命令时使用适合Windows 的命令 + +2.始终使用中文回答 + +3.对于项目代码的中打印语句代码(println语句、console语句等等)和注释需要保留,不要随意改动他们 + +4.对于前端的npm等命令你输出到屏幕即可(给出命令即可),我会在其他终端自己执行 \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1599250 --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +# Email Unlimit Project (临时邮件项目) + +## 最终架构 (单一 Docker Compose + 宿主机 Nginx) + +本项目采用生产环境推荐的架构:所有服务(包括您的应用和完整的 Mailu 邮件套件)都由一个 `docker-compose.full.yml` 文件统一管理,而入口的反向代理则由 **宿主机上的 Nginx** 负责。 + +- **宿主机 Nginx:** 作为项目的唯一公共入口 (`main.shenjianl.cn`)。它负责: + 1. 处理所有外部流量和 SSL 加密(推荐)。 + 2. 将对域名根路径 (`/`) 的访问反向代理到 **前端 Docker 容器** (`localhost:5181`)。 + 3. 将对 `/api` 路径的访问反向代理到 **后端 Docker 容器** (`localhost:5182`)。 + 4. 将对 `/mailu` 路径的访问反向代理到 **Mailu Admin UI** (`localhost:80`)。 + +- **Docker 容器 (由 `docker-compose.full.yml` 管理):** + - **您的应用:** `frontend`, `backend`, `mysql`。 + - **Mailu 套件:** `front` (Mailu Nginx), `admin`, `smtp`, `imap`, `redis` 等全套服务。 + +--- + +## 如何运行 + +### 步骤 1: 准备工作 + +1. **安装 Docker**: 确保您的系统中已安装 Docker 和 Docker Compose。 +2. **配置 Mailu**: 打开 `mailu.env` 文件,**务必修改** `SECRET_KEY` 和 `ADMIN_PASSWORD` 为安全的值。域名和数据库配置已预填。 +3. **配置 DNS**: 根据 `info.md` 中的 DNS 记录示例,在您的域名提供商处完成 SPF、DKIM 和 DMARC 的配置。 + +### 步骤 2: 配置宿主机 Nginx + +将下面的配置块添加到您宿主机的 Nginx 中。这份配置统一处理了对您的应用和 Mailu 管理后台的访问。 + +```nginx +# /etc/nginx/conf.d/main.shenjianl.cn.conf + +server { + listen 80; + server_name main.shenjianl.cn; + + # --- 推荐配置 SSL --- + # listen 443 ssl http2; + # server_name main.shenjianl.cn; + # ssl_certificate /path/to/your/fullchain.pem; + # ssl_certificate_key /path/to/your/privkey.pem; + # -------------------- + + # 反向代理到前端 Vue.js 容器 + location / { + proxy_pass http://localhost:5181; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # 反向代理到后端 API 容器 + location /api { + proxy_pass http://localhost:5182; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # 反向代理到 Mailu Admin UI 和 Webmail + # 注意:Mailu 自己的 Nginx (front) 在 80 端口上运行 + location /mailu { + proxy_pass http://localhost:80; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} +``` +**配置完成后,请重载或重启您的 Nginx 服务。** + +### 步骤 3: 启动 Docker 服务 + +使用我们最终生成的 `docker-compose.full.yml` 文件来启动所有服务。 + +```bash +# 在项目根目录执行 +docker-compose -f docker-compose.full.yml up -d --build +``` + +--- + +## 访问���址 + +- **主应用入口**: `http://main.shenjianl.cn` +- **Mailu 管理后台**: `http://main.shenjianl.cn/mailu` +- **Mailu Webmail**: `http://main.shenjianl.cn/mailu/webmail` + +docker-compose up -d --build \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..abf12ef --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,12 @@ +FROM node:20-alpine + +WORKDIR /usr/src/app + +COPY package*.json ./ +RUN npm install + +COPY . . + +EXPOSE 5182 + +CMD [ "node", "app.js" ] diff --git a/backend/app.js b/backend/app.js new file mode 100644 index 0000000..462a527 --- /dev/null +++ b/backend/app.js @@ -0,0 +1,32 @@ +const express = require('express'); +const cors = require('cors'); +const db = require('./db'); + +const app = express(); +const port = 5182; + +app.use(cors()); +app.use(express.json()); + +// API to get messages for a recipient +app.get('/api/messages', async (req, res) => { + const { recipient } = req.query; + if (!recipient) { + return res.status(400).send('Recipient is required'); + } + + try { + const [rows] = await db.execute( + 'SELECT id, sender, subject, body, received_at FROM emails WHERE recipient = ? ORDER BY received_at DESC', + [recipient] + ); + res.json(rows); + } catch (error) { + console.error('Failed to fetch emails:', error); + res.status(500).send('Failed to fetch emails'); + } +}); + +app.listen(port, () => { + console.log(`Backend server listening at http://localhost:${port}`); +}); diff --git a/backend/db.js b/backend/db.js new file mode 100644 index 0000000..dec7378 --- /dev/null +++ b/backend/db.js @@ -0,0 +1,13 @@ +const mysql = require('mysql2'); + +const pool = mysql.createPool({ + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0 +}); + +module.exports = pool.promise(); diff --git a/backend/init.sql b/backend/init.sql new file mode 100644 index 0000000..94c90a3 --- /dev/null +++ b/backend/init.sql @@ -0,0 +1,18 @@ +CREATE TABLE IF NOT EXISTS emails ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + recipient VARCHAR(255) NOT NULL, + sender VARCHAR(255) NOT NULL, + subject VARCHAR(512), + body TEXT, + received_at DATETIME DEFAULT CURRENT_TIMESTAMP, + raw MEDIUMBLOB +); + +CREATE TABLE IF NOT EXISTS email_attachments ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + email_id BIGINT NOT NULL, + filename VARCHAR(255), + content_type VARCHAR(128), + content LONGBLOB, + FOREIGN KEY (email_id) REFERENCES emails(id) ON DELETE CASCADE +); diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 0000000..0ceb14a --- /dev/null +++ b/backend/package.json @@ -0,0 +1,16 @@ +{ + "name": "backend", + "version": "1.0.0", + "description": "Backend for email service", + "main": "app.js", + "scripts": { + "start": "node app.js" + }, + "dependencies": { + "express": "^5.1.0", + "mysql2": "^3.14.2", + "mailparser": "^3.7.4", + "cors": "^2.8.5", + "get-stream": "^9.0.1" + } +} diff --git a/backend/saveEmail.js b/backend/saveEmail.js new file mode 100644 index 0000000..cfd31a6 --- /dev/null +++ b/backend/saveEmail.js @@ -0,0 +1,54 @@ +#!/usr/bin/env node + +const { simpleParser } = require('mailparser'); +const db = require('./db'); + +// Using require for get-stream v5 as it's CommonJS +const getStream = require('get-stream'); + +async function saveEmail(rawEmail) { + try { + const parsed = await simpleParser(rawEmail); + + // Ensure 'to' and 'from' objects exist before accessing 'text' + const recipient = parsed.to ? parsed.to.text : 'undisclosed-recipients'; + const sender = parsed.from ? parsed.from.text : 'unknown-sender'; + const subject = parsed.subject; + const body = parsed.text || (parsed.html || ''); + + const [result] = await db.execute( + 'INSERT INTO emails (recipient, sender, subject, body, raw) VALUES (?, ?, ?, ?, ?)', + [recipient, sender, subject, body, rawEmail] + ); + + console.log(`Email saved with ID: ${result.insertId}`); + + if (parsed.attachments && parsed.attachments.length > 0) { + for (const attachment of parsed.attachments) { + await db.execute( + 'INSERT INTO email_attachments (email_id, filename, content_type, content) VALUES (?, ?, ?, ?)', + [result.insertId, attachment.filename, attachment.contentType, attachment.content] + ); + console.log(`Attachment ${attachment.filename} saved.`); + } + } + } catch (error) { + console.error('Failed to save email:', error); + // Exit with an error code to signal failure to the calling process (e.g., Mailu) + process.exit(1); + } +} + +(async () => { + try { + const rawEmail = await getStream(process.stdin); + if (rawEmail && rawEmail.length > 0) { + await saveEmail(rawEmail); + } else { + console.log('Received empty input, no email to save.'); + } + } catch (error) { + console.error('Error reading from stdin:', error); + process.exit(1); + } +})(); diff --git a/docker-compose.full.yml b/docker-compose.full.yml new file mode 100644 index 0000000..a5a10c0 --- /dev/null +++ b/docker-compose.full.yml @@ -0,0 +1,118 @@ +# docker-compose.full.yml +# 最终合并版本:包含您的应用 (frontend, backend) 和完整的 Mailu 服务套件。 + +version: '3.3' + +services: + + # ----------------------------------------- + # 您的应用服务 + # ----------------------------------------- + + backend: + build: ./backend + container_name: mail_backend + restart: always + environment: + DB_HOST: "43.143.145.172" + DB_USER: "root" + DB_PASSWORD: "kyff145972" + DB_NAME: "maildb" + ports: + - "5182:5182" + + frontend: + build: ./frontend + container_name: mail_frontend + restart: always + ports: + - "5181:8080" + depends_on: + - backend + + # ----------------------------------------- + # Mailu 官方服务套件 + # ----------------------------------------- + + redis: + image: redis:alpine + restart: always + volumes: + - "mailu_redis:/data" + + front: + image: ghcr.io/mailu/nginx:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_certs:/certs" + - "mailu_overrides_nginx:/overrides" + + resolver: + image: ghcr.io/mailu/unbound:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + dns: + - 8.8.8.8 + - 1.1.1.1 + # --- 用于调试的临时修改 --- + entrypoint: /bin/sh + command: -c "sleep 3600" + + admin: + image: ghcr.io/mailu/admin:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_data:/data" + - "mailu_dkim:/dkim" + depends_on: + - redis + + imap: + image: ghcr.io/mailu/dovecot:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_mail:/mail" + - "mailu_overrides_dovecot:/overrides" + depends_on: + - front + + smtp: + image: ghcr.io/mailu/postfix:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_overrides_postfix:/overrides" + depends_on: + - front + - resolver + + antispam: + image: ghcr.io/mailu/rspamd:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_filter:/var/lib/rspamd" + - "mailu_overrides_rspamd:/etc/rspamd/override.d" + depends_on: + - front + +volumes: + mailu_data: + mailu_certs: + mailu_dkim: + mailu_filter: + mailu_mail: + mailu_redis: + mailu_overrides_nginx: + mailu_overrides_dovecot: + mailu_overrides_postfix: + mailu_overrides_rspamd: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7b5b7c9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,115 @@ +# docker-compose.full.yml +# 最终合并版本:包含您的应用 (frontend, backend) 和完整的 Mailu 服务套件。 + +version: '3.3' + +services: + + # ----------------------------------------- + # 您的应用服务 + # ----------------------------------------- + + backend: + build: ./backend + container_name: mail_backend + restart: always + environment: + DB_HOST: "43.143.145.172" + DB_USER: "root" + DB_PASSWORD: "kyff145972" + DB_NAME: "maildb" + ports: + - "5182:5182" + + frontend: + build: ./frontend + container_name: mail_frontend + restart: always + ports: + - "5181:8080" + depends_on: + - backend + + # ----------------------------------------- + # Mailu 官方服务套件 + # ----------------------------------------- + + redis: + image: redis:alpine + restart: always + volumes: + - "mailu_redis:/data" + + front: + image: ghcr.io/mailu/nginx:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_certs:/certs" + - "mailu_overrides_nginx:/overrides" + + resolver: + image: ghcr.io/mailu/unbound:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + dns: + - 8.8.8.8 + - 1.1.1.1 + + admin: + image: ghcr.io/mailu/admin:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_data:/data" + - "mailu_dkim:/dkim" + depends_on: + - redis + + imap: + image: ghcr.io/mailu/dovecot:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_mail:/mail" + - "mailu_overrides_dovecot:/overrides" + depends_on: + - front + + smtp: + image: ghcr.io/mailu/postfix:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_overrides_postfix:/overrides" + depends_on: + - front + - resolver + + antispam: + image: ghcr.io/mailu/rspamd:2.0 + restart: always + env_file: mailu.env + hostname: mail.shenjianl.cn + volumes: + - "mailu_filter:/var/lib/rspamd" + - "mailu_overrides_rspamd:/etc/rspamd/override.d" + depends_on: + - front + +volumes: + mailu_data: + mailu_certs: + mailu_dkim: + mailu_filter: + mailu_mail: + mailu_redis: + mailu_overrides_nginx: + mailu_overrides_dovecot: + mailu_overrides_postfix: + mailu_overrides_rspamd: diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..6ff4c96 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,19 @@ +FROM node:20-alpine + +# Set working directory +WORKDIR /app + +# Copy package.json and package-lock.json +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Copy all other files +COPY . . + +# Expose port +EXPOSE 8080 + +# Run the app +CMD ["npm", "run", "serve"] diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..0c8a246 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,16 @@ +{ + "name": "frontend", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build" + }, + "dependencies": { + "vue": "^3.5.18", + "axios": "^1.11.0" + }, + "devDependencies": { + "@vue/cli-service": "~5.0.8" + } +} diff --git a/frontend/public/index.html b/frontend/public/index.html new file mode 100644 index 0000000..8b34744 --- /dev/null +++ b/frontend/public/index.html @@ -0,0 +1,17 @@ + + + + + + + + 临时邮件 + + + +
+ + + diff --git a/frontend/src/App.vue b/frontend/src/App.vue new file mode 100644 index 0000000..25e45ff --- /dev/null +++ b/frontend/src/App.vue @@ -0,0 +1,257 @@ + + + + + diff --git a/frontend/src/main.js b/frontend/src/main.js new file mode 100644 index 0000000..01433bc --- /dev/null +++ b/frontend/src/main.js @@ -0,0 +1,4 @@ +import { createApp } from 'vue' +import App from './App.vue' + +createApp(App).mount('#app') diff --git a/frontend/vue.config.js b/frontend/vue.config.js new file mode 100644 index 0000000..7dc6ac0 --- /dev/null +++ b/frontend/vue.config.js @@ -0,0 +1,6 @@ +const { defineConfig } = require('@vue/cli-service') + +module.exports = defineConfig({ + transpileDependencies: true + // devServer 代理配置已移除,所有代理均由外部 Nginx 处理。 +}) \ No newline at end of file diff --git a/info.md b/info.md new file mode 100644 index 0000000..153b5b2 --- /dev/null +++ b/info.md @@ -0,0 +1,349 @@ + +前端:**Vue** +后端:**Node.js + Express** +数据库:**MySQL** +邮件服务:**Mailu** + +我帮你重新整理并生成**完整且清晰**的架构图、流程图、技术栈表 + 项目结构: + +--- + +## 🧩 **一、架构图(新版:Vue + Express)** + +``` +┌────────────────────────────┐ +│ 用户 │ +│ ┌──────────────────────┐ │ +│ │ mail.shenjianl.cn 前端网站 │ ←─────┐ +│ │ (Vue) │ │ +│ └──────────────────────┘ │ +└────────────┬─────────────┘ + │ HTTP (REST API) + ▼ +┌────────────────────────────┐ +│ Node.js 后端 (Express) │ +│ - 生成随机邮箱地址 │ +│ - 查询收件箱 │ +│ - 邮件接收解析写数据库 │ +└────────────┬─────────────┘ + │ MySQL + ▼ +┌────────────────────────────┐ +│ MySQL │ +│ - emails 表 │ +│ - email_attachments 表 │ +└────────────┬─────────────┘ + │ + ▼ +┌────────────────────────────┐ +│ 邮件服务器(Mailu) │ +│ - SMTP 接收外部邮件 │ +│ - Catch-all 所有收件人 │ +│ - 调用 Node.js 脚本入库 │ +└────────────┬─────────────┘ + │ + ▼ +┌────────────────────────────┐ +│ DNS │ +│ - MX: mail.shenjianl.cn │ +│ - A: mail.shenjianl.cn → IP │ +└────────────────────────────┘ +``` + +--- + +## 📝 **二、流程图:接收 & 查看流程** + +``` +【外部发件人】 + │ + ▼ +发邮件到 abc123@shenjianl.cn + │ + ▼ +DNS MX 查找 mail.shenjianl.cn + │ + ▼ +Mailu 收到邮件 (SMTP) + │ + ▼ +调用 Node.js 脚本 (saveEmail.js) + │ + ▼ +simpleParser 解析邮件内容 + │ + ▼ +写入 MySQL: +recipient, sender, subject, body, received_at + │ + ▼ +用户访问网页: +mail.shenjianl.cn + │ + ▼ +Vue 前端请求后端 API: +GET /api/messages?recipient=abc123@shenjianl.cn + │ + ▼ +后端查询 MySQL 返回邮件列表 + │ + ▼ +前端展示收件箱 +``` + +--- + +## ⚙ **三、技术栈清单(新版)** + +| 层级 | 功能 | 技术选型 | +| -------- | -------------- | ----------------------------------- | +| 域名 & DNS | MX/A 解析 | 阿里云 DNS / Cloudflare | +| 邮件服务器 | 接收所有外部邮件 | Mailu(基于 Postfix/Dovecot) | +| 邮件解析 | 提取收件人/正文/主题/附件 | Node.js (mailparser) | +| 后端 API | 生成邮箱 / 查询收件箱 | Node.js + Express | +| 数据库 | 存储邮件信息 | MySQL | +| 前端 | 用户界面 / 展示收件箱 | Vue.js | +| 部署 & 管理 | 容器化 / 部署 | Docker + docker-compose | +| 安全 | HTTPS / 防滥用 | Let's Encrypt + Nginx 反代 + IP限流/黑名单 | + +--- + +## 🛠 **四、项目结构建议(新版)** + +``` +📦 project-root + ├── frontend/ # Vue 前端 + │ └── (组件/页面/接口) + ├── backend/ # Node.js 后端 + │ ├── app.js # Express 主程序 + │ ├── saveEmail.js # 接收邮件脚本:解析并写入数据库 + │ └── db.js # 数据库连接 + ├── docker-compose.yml # Mailu + Node.js + MySQL + ├── mailu.env # Mailu 配置 + ├── README.md +``` + +--- + +✅ **总结:** + +* 前端:Vue 只负责界面和展示 +* 后端:Express 提供 API + 接收邮件写 MySQL +* 邮件服务器:Mailu catch-all 接收所有地址 +* DNS:配置 MX / A 指向服务器 + +--- + +好的! +下面我给你**直接写好**适配新版架构的: +✅ `docker-compose.yml`(包含:Vue 前端 + Node.js Express 后端 + MySQL + Mailu 邮件服务器) +✅ MySQL 建表 SQL + +--- + +## ✅ **1️⃣ docker-compose.yml** + +> ⚠️ 注: + +* Vue 前端用 `npm run serve` 或 `npm run build` 后放 Nginx 也行,这里为了简单直接跑开发服务 +* Mailu 是官方 Docker 邮件套件,需要 `mailu.env` 配置 +* 建议生产用 HTTPS + Nginx,下面只是开发演示架构 + +```yaml +version: '3.8' + +services: + mysql: + image: mysql:8 + container_name: mail_mysql + restart: always + environment: + MYSQL_ROOT_PASSWORD: myrootpassword + MYSQL_DATABASE: maildb + MYSQL_USER: mailuser + MYSQL_PASSWORD: mailpassword + ports: + - "3306:3306" + volumes: + - mysql_data:/var/lib/mysql + + backend: + build: ./backend + container_name: mail_backend + restart: always + environment: + DB_HOST: mysql + DB_USER: mailuser + DB_PASSWORD: mailpassword + DB_NAME: maildb + ports: + - "3000:3000" + depends_on: + - mysql + + frontend: + build: ./frontend + container_name: mail_frontend + restart: always + ports: + - "8080:8080" + depends_on: + - backend + + mailu: + image: mailu/mailu:master + container_name: mail_server + restart: always + env_file: mailu.env + ports: + - "25:25" # SMTP + - "465:465" # SMTPS + - "143:143" # IMAP + - "993:993" # IMAPS + - "8081:80" # Mailu admin web UI(可选) + volumes: + - mailu_data:/data + depends_on: + - mysql + +volumes: + mysql_data: + mailu_data: +``` + +--- + +## 📦 **2️⃣ 建表 SQL** + +```sql +CREATE TABLE emails ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + recipient VARCHAR(255) NOT NULL, + sender VARCHAR(255) NOT NULL, + subject VARCHAR(512), + body TEXT, + received_at DATETIME DEFAULT CURRENT_TIMESTAMP, + raw MEDIUMBLOB +); + +CREATE TABLE email_attachments ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + email_id BIGINT NOT NULL, + filename VARCHAR(255), + content_type VARCHAR(128), + content LONGBLOB, + FOREIGN KEY (email_id) REFERENCES emails(id) ON DELETE CASCADE +); +``` + +--- + +## 📦 **3️⃣ mailu.env**(示例配置) + +```env +DOMAIN=shenjianl.cn +HOSTNAMES=mail.shenjianl.cn +SECRET_KEY=change-this-to-a-very-random-secret +ADMIN=admin +ADMIN_PASSWORD=adminpassword +DB_FLAVOR=mysql +DB_HOST=mysql +DB_USER=mailuser +DB_PASSWORD=mailpassword +DB_NAME=maildb +``` + +--- + +## ✅ **4️⃣ 项目结构(推荐)** + +``` +📦 project-root + ├── frontend/ # Vue 前端 + │ └── (页面/组件) + ├── backend/ # Node.js Express 后端 + │ ├── app.js # 提供 API + │ ├── saveEmail.js # 接收邮件脚本 + │ └── db.js # 数据库连接 + ├── docker-compose.yml + ├── mailu.env + └── README.md +``` + +--- + +✨ **这样就完成了:** + +* Vue 前端对接后端 API +* 后端(Express)接收请求、存储/查询邮件 +* Mailu 负责接收 SMTP 邮件并调用脚本写数据库 +* MySQL 存储邮件数据 + +--- + + +以下是针对你域名 `shenjianl.cn` 的**简单版 SPF、DKIM、DMARC DNS TXT 记录示范**,你可以直接复制,去你买域名的DNS管理后台添加。 + +--- + +## 1. SPF 记录 + +* **类型**:TXT +* **主机名**:`@` (代表根域名 shenjianl.cn) +* **值(内容)**: + +``` +v=spf1 mx ip4:你的服务器公网IP -all +``` + +> 把 `你的服务器公网IP` 换成你实际服务器的外网IP地址。 + +--- + +## 2. DKIM 记录(示例) + +假设你的邮件服务器给你生成了一个 selector,叫做 `default`,那么: + +* **类型**:TXT +* **主机名**:`default._domainkey` +* **值(内容)**: + +``` +v=DKIM1; k=rsa; p=这里填你的公钥内容 +``` + +> 注意:`p=` 后面是一个很长的字符串,由邮件服务器生成的公钥。 +> 你可以让 Mailu 生成 DKIM 密钥,然后复制粘贴到这里。 + +--- + +## 3. DMARC 记录 + +* **类型**:TXT +* **主机名**:`_dmarc` +* **值(内容)**: + +``` +v=DMARC1; p=quarantine; rua=mailto:admin@shenjianl.cn; pct=100 +``` + +解释: + +* `p=quarantine`:不合规邮件放到垃圾箱 +* `rua=mailto:admin@shenjianl.cn`:每隔一段时间会收到报告(你可以换成自己的邮箱) +* `pct=100`:所有邮件都应用该规则 + +--- + +# 总结 + +| 类型 | 主机名 | 内容示例 | +| --- | ------------------- | ---------------------------------------------------------------- | +| TXT | @ | `v=spf1 mx ip4:你的服务器公网IP -all` | +| TXT | default.\_domainkey | `v=DKIM1; k=rsa; p=你的公钥` | +| TXT | \_dmarc | `v=DMARC1; p=quarantine; rua=mailto:admin@shenjianl.cn; pct=100` | + +--- + +如果你还没有 DKIM 公钥或者不确定怎么生成,可以告诉我,我帮你写生成步骤。 + diff --git a/mailu.env b/mailu.env new file mode 100644 index 0000000..0a36ebf --- /dev/null +++ b/mailu.env @@ -0,0 +1,26 @@ +SECRET_KEY=d4f7a1b3c2e987f05a6d3b4c8e1f2097 +DOMAIN=shenjianl.cn +HOSTNAMES=mail.shenjianl.cn +POSTMASTER=admin + +DB_FLAVOR=mysql +DB_HOST=43.143.145.172 +DB_USER=root +DB_PASSWORD=kyff145972 +DB_NAME=maildb + +WEB_ADMIN=/mailu +WEB_WEBMAIL=/mailu/webmail + +ENABLE_UNPRIVILEGED_USER=false +PASSWORD_SCHEME=BLF-CRYPT +ENABLE_ADMIN=true +ENABLE_WEBMAIL=true +ENABLE_WEBDAV=false +ENABLE_ANTIVIRUS=false +ENABLE_ANTISPAM=true +DEFAULT_QUOTA=2G +ADMIN_PASSWORD=admin + +TLS_FLAVOR=notls +MESSAGE_SIZE_LIMIT=20000000