Python smtpd库是否支持TLS?求Python3下带TLS的邮件服务器实现方案
Python3 搭建支持TLS的SMTP服务器方案
确实,Python标准库自带的smtpd模块功能相当有限,不仅不支持TLS,在Python 3.10及以后的版本里还被标记为废弃了——用它来做生产级的邮件服务器根本不现实。不过针对Python3,有几个成熟的方案可以解决你的问题:
1. 优先选择 aiosmtpd 库
aiosmtpd是官方smtpd的异步替代实现,完全适配Python3,而且原生支持TLS。它基于asyncio,性能更优,文档也比较完善,是目前最推荐的方案。
先安装依赖
pip install aiosmtpd
快速搭建TLS SMTP服务器
首先你需要SSL证书,测试的话可以用openssl生成自签证书:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
然后编写服务器代码:
from aiosmtpd.controller import Controller from aiosmtpd.smtp import SMTP as Server, TLSSetup import ssl # 自定义邮件处理逻辑 class MailHandler: async def handle_DATA(self, server, session, envelope): # 打印收到的邮件信息,你可以在这里添加存储、转发等逻辑 print(f"📩 收到来自 {envelope.mail_from} 的邮件") print(f"📥 收件人列表: {envelope.rcpt_tos}") print(f"📝 邮件内容:\n{envelope.content.decode('utf-8')}") return '250 OK' # 配置TLS上下文 tls_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) tls_context.load_cert_chain(certfile="cert.pem", keyfile="key.pem") # 创建带TLS的SMTP服务器实例 smtp_server = Server(MailHandler(), tls_setup=TLSSetup(tls_context)) # 绑定地址和端口(465是标准SMTPS端口) controller = Controller(smtp_server, hostname='0.0.0.0', port=465) if __name__ == "__main__": print("🚀 TLS SMTP服务器已启动,监听端口465...") print("按回车键停止服务器") controller.start() try: input() finally: controller.stop()
运行这段代码后,你就有一个支持TLS的SMTP服务器了,收到邮件会在控制台打印详细信息,你可以根据需求修改MailHandler里的逻辑,比如把邮件存储到数据库或者转发到其他邮箱。
2. 基于标准库smtpd的手动TLS封装(不推荐)
如果你非要用已经废弃的smtpd模块,也可以手动用ssl包装套接字,但这种方式繁琐且性能不佳,只适合临时测试:
import smtpd import asyncore import ssl class TLSSMTPServer(smtpd.SMTPServer): def __init__(self, localaddr, remoteaddr, certfile, keyfile): super().__init__(localaddr, remoteaddr) self.cert = certfile self.key = keyfile def handle_accept(self): conn, addr = self.accept() # 将普通套接字包装为TLS套接字 ssl_conn = ssl.wrap_socket( conn, server_side=True, certfile=self.cert, keyfile=self.key, ssl_version=ssl.PROTOCOL_TLS ) self.handle_connection(ssl_conn, addr) # 自定义邮件处理器,这里用DebuggingServer会自动打印邮件信息 class CustomMailHandler(smtpd.DebuggingServer): def process_message(self, peer, mailfrom, rcpttos, data, **kwargs): print(f"\n来自 {peer} 的邮件:") print(f"发件人: {mailfrom}") print(f"收件人: {rcpttos}") print(f"内容:\n{data.decode('utf-8')}") return '250 OK' if __name__ == "__main__": server = TLSSMTPServer(('0.0.0.0', 465), None, "cert.pem", "key.pem") print("基于smtpd的TLS服务器启动,监听端口465...") try: asyncore.loop() except KeyboardInterrupt: print("\n服务器已停止")
再次强调:smtpd已经被官方废弃,未来会被移除,不建议在生产环境使用这个方案。
3. 其他可选方案
如果你的需求更复杂,比如需要完整的邮件服务器功能,可以考虑用Postfix搭配Python脚本处理邮件,但对于简单场景来说,aiosmtpd完全够用。另外还有pysmtpd这个第三方库,但它的维护活跃度不如aiosmtpd,优先选前者。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

