Node.js 如何通过自建本地SMTP服务器向Gmail、Yahoo等外部邮箱发邮件
核心问题根源
你现在的实现从根上就搞混了SMTP服务的角色,邮件压根没走到外发环节:
- 你用
smtp-server搭的服务,本质就是个纯收信的服务端。所有连到587端口进来的邮件数据,全被onData回调接住、解析完打个日志就结束了,全程没有任何“转发投递到外部邮箱域”的代码分支 - 你用
nodemailer发邮件的时候,只是通过SMTP协议把数据提交给了你自己搭的这个收信服务,服务端收到数据后啥外发动作都没做,自然所有邮件都被你自己的服务器截住了 - 现在代码里直接把AUTH命令关了,这服务器一旦暴露到公网,马上会被扫垃圾邮件的程序找到,变成无认证的开放中继,过不了几天你的IP就会被全球邮件服务商拉黑
想靠自己搭的SMTP发外部邮件,硬门槛一个都不能少
光把代码写对没用,缺了下面任意一个条件,你的邮件永远进不了Gmail、Yahoo的收件箱:
- 得有个固定的公网可路由IP,动态家宽IP直接就被主流邮件服务商拉黑了,发啥都拒收
- DNS配置必须全:
- 正向A记录:公网IP要指向你自己真正持有的合法域名,比如
smtp.你的域名.com - 反向PTR记录:公网IP的反向解析结果,必须和上面的A记录完全对上,Gmail这类服务商只要发现反向解析不对,直接退信
- 认证记录:给域名配好SPF、DKIM、DMARC,证明你是这个域名的合法发件方
- 正向A记录:公网IP要指向你自己真正持有的合法域名,比如
- 确认服务器的25端口没被运营商封,现在大部分云服务商、家宽默认封25端口,得单独找客服申请解封
- 发件人用的域名必须是你真实拥有、能正常解析的,不能随便编个
test.com就当发件人
具体怎么改
1. 补全收信后的逻辑分支
smtp-server只是个帮你处理SMTP协议握手、收数据的框架,本身根本不会帮你把邮件发出去。你得在onData的回调里加判断:
- 如果收件人是你自己托管的域的邮箱,就保留原来解析、存本地的逻辑
- 如果收件人是外部域的邮箱,就把收到的原始邮件流交给能往外投递的模块处理——这块根本不用你自己写查MX、和对方服务器握手的代码,直接用
nodemailer的内置MX直连能力就行
2. 把安全配置拉满
- 删掉
disabledCommands: ['AUTH']这行,把SMTP认证开了,只有输对账号密码的合法用户发的邮件,才允许走外发流程,不然成开放中继死得很快 - 删掉
nodemailer里tls: { rejectUnauthorized: false }这种跳过证书校验的配置,给你的SMTP服务配个对应域名的有效TLS证书,走正规加密连接
3. 别再自己连自己的587端口发测试了
你之前写的那个用nodemailer连自己公网IP的587端口发邮件的逻辑,只是往你的收信服务提交待发数据而已。真正的外发动作,是你的服务收到合法用户提交的邮件后,通过nodemailer自动查目标收件人域名的MX记录,直接找对方的收信服务器握手投递。
额外提醒:自建SMTP的维护成本极高,要持续盯着IP信誉、应对不同服务商的拦截规则,哪怕所有配置全对,刚搭好的新IP、新域名也有非常高的概率被标成垃圾邮件来源。
内容的提问来源于stack exchange,提问作者TopchetoEU
相关产品推荐
相关产品推荐

