Postfix日志出现SSL_accept错误,Rust lettre程序VPS发信失败
问题根因
你遇到的tlsv1 alert unknown ca(SSL alert 48)是你的Rust lettre程序作为TLS客户端,不信任邮件服务端出示的SSL证书导致的,握手阶段直接终止连接,所以没有后续SMTP命令执行。
矛盾现象解释
你提到的手动通过Rainloop发信正常、本地运行程序发信正常,部署到VPS就失败的差异点原因如下:
- 你认为「邮件服务器未安装SSL证书」是错误判断:你使用的是465端口SMTPS服务,Postfix必须配置证书才能正常提供SMTPS服务,CyberPanel搭建过程中大概率已经自动给邮件服务配置了自签证书,或者绑定了其他未被公共根证书库信任的证书。
- 本地运行程序正常:要么是你本地开发时lettre配置了跳过证书校验,要么你本地系统根证书库信任了该证书,也可能你本地测试时用的是非加密端口提交邮件。
- Rainloop手动发信正常:Rainloop作为Web邮件客户端,要么部署在同一台机器走本地非加密端口提交,要么你访问Rainloop的浏览器已经信任了该自签证书,或者Rainloop本身配置了跳过邮件服务端的证书校验。
解决步骤
- 确认Postfix的证书配置
执行以下命令查看当前Postfix使用的证书:
postconf | grep smtpd_tls_chain_files postconf | grep smtpd_tls_cert_file
如果输出的是自签证书路径,建议直接在CyberPanel后台给邮件域名一键申请Let's Encrypt证书,公共CA签发的证书会被所有系统根证书库默认信任。
- 调整Rust lettre配置(二选一即可)
- 生产环境推荐:只要你给邮件服务器配置了公共CA签发的有效证书,保持lettre默认配置即可,它会自动读取VPS的系统根证书库完成校验。
- 测试环境临时方案:手动配置lettre跳过证书校验,注意不要在生产环境使用,存在中间人攻击风险,参考代码:
let transport = SmtpTransport::relay("你的邮件域名")? .port(465) .tls(Tls::Smtp(SmtpTls::builder().danger_accept_invalid_certs(true).build())) .credentials(credentials) .build();
- 可选方案
如果不想申请公网证书,可以手动把Postfix使用的自签证书添加到VPS的系统根证书库中,Debian/Ubuntu系统操作如下:
# 把Postfix使用的证书复制到根证书存储目录 cp /你的证书路径/cert.pem /usr/local/share/ca-certificates/postfix-selfsigned.crt # 更新根证书库 update-ca-certificates
内容的提问来源于stack exchange,提问作者CrimsonTide0
相关产品推荐
相关产品推荐

