Home
avatar

.Wang

1panel搭建邮局问题

近期准备开发一个“记账”系统,考虑到有重置密码,到表到邮箱的功能,于是在服务器上搭建了一个邮局服务。之后出现了一个问题,服务是可以正常接收邮件,代码没有报错,但是服务器却没有收到第三方的邮件,以及第三方邮件也没接收到服务器的邮件。

问题出现的原因是,1panel 搭建的邮局服务,我接着把涉及到的端口全部开放,后面查询资料说是需要 25 端口,但是我开放了 25 端口,还是没有解决问题。之后我看了一下服务器的 ip 所属的区域内 25 端口全部封禁,导致邮件无法发送。尽管服务器开启了 25 端口,但是由于区域内 25 端口封禁,导致邮件无法发送。后联系厂商之后,说该服务器区域暂不支持。

所以,暂时不考虑邮箱功能。所以我也就砍掉了对应的功能,只保留了登录功能。

接下来,大致记录一下邮局如何搭建:

  1. 准备好域名,服务器,服务器安装好 1panel 面板。
  2. 1panel 面板,应用市场找到 Maddy Mail Server 应用。然后接着安装就好了。
  3. 首次安装时运行不起来的,是因为需要配置对应的证书。具体的操作例如上图的步骤,一步步完成就可以了。

代码模板

import nodemailer from "nodemailer";
import dotenv from "dotenv";

// 加载环境变量
dotenv.config();

/**
 * 创建 Stalwart SMTP 传输器
 */
const createTransporter = () => {
	return nodemailer.createTransport({
		host: process.env.STALWART_SMTP_HOST || "localhost", // Stalwart SMTP 服务器地址
		port: parseInt(process.env.STALWART_SMTP_PORT || "587"), // SMTP 端口(587 用于 STARTTLS,465 用于 SSL)
		secure: process.env.STALWART_SMTP_SECURE === "true", // true 表示使用 SSL,false 表示使用 STARTTLS
		auth: {
			user: process.env.STALWART_SMTP_USER, // SMTP 用户名/邮箱
			pass: process.env.STALWART_SMTP_PASS, // SMTP 密码
		},
		// 调试与超时(方便排查 Unexpected socket close)
		logger: false, // 在控制台输出 SMTP 日志
		debug: false,
		connectionTimeout: 10_000, // 连接阶段超时 10 秒
		greetingTimeout: 10_000, // 等待服务器问候语超时
		socketTimeout: 20_000, // 整个会话的 socket 超时
		// 可选:TLS 选项
		tls: {
			rejectUnauthorized:
				process.env.STALWART_SMTP_TLS_REJECT_UNAUTHORIZED !== "false", // 在生产环境中建议设为 true
		},
	});
};

/**
 * 发送邮件
 * @param {Object} options - 邮件选项
 * @param {string|string[]} options.to - 收件人邮箱(支持字符串或数组)
 * @param {string} options.subject - 邮件主题
 * @param {string} options.text - 纯文本内容
 * @param {string} options.html - HTML 内容
 * @param {string} [options.from] - 发件人(可选,默认使用环境变量)
 * @param {string|string[]} [options.cc] - 抄送(可选)
 * @param {string|string[]} [options.bcc] - 密送(可选)
 */
export const sendEmail = async options => {
	try {
		const transporter = createTransporter();

		// 验证连接
		await transporter.verify();
		console.log("✓ SMTP 服务器连接成功");

		// 准备邮件选项
		const mailOptions = {
			from:
				options.from ||
				process.env.STALWART_SMTP_FROM ||
				process.env.STALWART_SMTP_USER,
			to: options.to,
			subject: options.subject,
			text: options.text,
			html: options.html,
			cc: options.cc,
			bcc: options.bcc,
		};
		// 发送邮件
		const info = await transporter.sendMail(mailOptions);
		console.log("✓ 邮件发送成功");
		console.log("  消息 ID:", info.messageId);
		console.log("  响应:", info.response);

		return info;
	} catch (error) {
		console.error("✗ 邮件发送失败:", error.message);
		throw error;
	}
};

sendEmail({
	to: "其他邮箱地址",
	subject: "测试邮件 - 使用 Stalwart",
	text: "这是一封通过 Stalwart 邮件服务器发送的测试邮件。",
	html: "<p>这是一封通过 <strong>Stalwart</strong> 邮件服务器发送的测试邮件。</p>",
})
	.then(() => {
		console.log("\n邮件发送完成!");
		process.exit(0);
	})
	.catch(error => {
		console.error("\n邮件发送失败:", error);
		process.exit(1);
	});

第三方资料

总结 技术调研 1panel

同系列的博文

技术调研-nvm 替换为 fnm
总结技术调研

技术调研-nvm 替换为 fnm

技术调研-github-pacakges
总结技术调研

技术调研-github-pacakges

技术调研-nvm1.1.12版本的一个问题
总结技术调研

技术调研-nvm1.1.12版本的一个问题

技术调研-rust-env没有继承问题
总结技术调研

技术调研-rust-env没有继承问题

技术调研-远程组件的介绍
总结技术调研

技术调研-远程组件的介绍

技术调研-远程组件实践
总结技术调研

技术调研-远程组件实践

设置