使用aiosmtpd搭建SMTP服务器:能收邮件但无法发送的问题排查
问题分析与解决
核心问题1:用错了服务器类
你启动的DebuggingServer是Python内置smtpd模块的调试工具,它的作用仅仅是接收邮件并打印到控制台,根本不会把邮件转发给目标收件服务器(比如Gmail的SMTP服务器)。这就是为什么你能在控制台看到邮件内容,但外部收件人收不到的直接原因。
核心问题2:SPF记录配置错误
- 一个域名只能有一条有效的SPF TXT记录,你配置了两条,会直接导致SPF验证失败——即使后续转发功能正常,邮件也会被拒收或扔进垃圾邮件。
- 第一条SPF里的
include: mydomain.com完全无效,include应该指向其他域名的SPF规则,指向自身会造成循环引用,毫无意义。
其他必注意的细节
- 本地SMTP的转发能力:如果要发送外部邮件(比如到@gmail.com),你需要搭建具备邮件中继/转发功能的MTA(邮件传输代理)。aiosmtpd只是基础框架,需要自定义处理逻辑来实现转发,或者搭配Postfix、Exim这类成熟的MTA,也可以配置中继到你的ISP提供的SMTP服务器。
- 端口与网络限制:很多家庭宽带ISP会封禁25端口(默认SMTP端口),如果你的服务器在家庭网络,要么联系ISP解封,要么改用587端口。
- 反向DNS(PTR)记录:Gmail这类主流邮件服务器会验证发件IP的反向DNS记录,你的公网IP 1.2.3.4必须能反向解析到
mail.mydomain.com,否则邮件会直接被拒收。
修复步骤
1. 替换调试服务器,实现邮件转发
放弃DebuggingServer,用aiosmtpd自定义转发逻辑,示例代码:
from aiosmtpd.controller import Controller from aiosmtpd.handlers import Proxy # 自定义转发处理器,允许转发到外部域名 class ForwardHandler(Proxy): async def handle_RCPT(self, server, session, envelope, address, rcpt_options): return '250 OK' # 启动转发服务器,自动解析目标域名的MX记录进行转发 handler = ForwardHandler(remote_host='0.0.0.0', remote_port=25) controller = Controller(handler, hostname='0.0.0.0', port=25) controller.start() print("SMTP转发服务器已启动在0.0.0.0:25") try: input("按回车停止服务器...\n") finally: controller.stop()
运行这段代码启动服务器,替代之前的命令行指令。
2. 修正SPF记录
删除其中一条SPF记录,保留有效的版本,比如:
mydomain.com TXT 1 minute "v=spf1 ip4:1.2.3.4 ~all"
如果后续使用了中继服务器,需要把中继服务器的IP或域名加入SPF,比如v=spf1 ip4:1.2.3.4 include:relay.example.com ~all
3. 配置反向DNS(PTR)
联系你的IP服务商,将公网IP 1.2.3.4的反向DNS记录设置为mail.mydomain.com,这是外部邮件服务器信任你的邮件的必要条件。
4. 调整端口(如果需要)
如果25端口被封禁,改用587端口启动服务器,同时修改发送邮件的代码:
smtpObj = smtplib.SMTP('127.0.0.1', 587)
内容的提问来源于stack exchange,提问作者user1618465
相关产品推荐
相关产品推荐

