telnet可正常发送企业邮件,Python smtplib脚本提示Relay access denied如何解决
问题原因
- EHLO标识与校验规则不匹配:Telnet测试时你使用
helo username@company.net传递了企业邮箱域名作为身份标识,而Python smtplib调用无参ehlo()时会默认发送本机内网IP(日志显示为ehlo [172.20.0.11]),企业邮件服务器的中继规则一般会校验该标识,未纳入信任列表的IP/域名会直接触发中继拒绝。同时部分企业服务器对EHLO的校验规则比HELO更严格,你Telnet用HELO测试通过,Python用EHLO请求就可能被拦截。 - 邮件内容不符合标准格式:SMTP协议要求邮件必须包含
From、To等必要头字段,你当前代码的msg仅包含纯文本内容Hello,没有任何邮件头信息,服务器会判定为异常发信触发拦截。 - 未完成SMTP身份认证:绝大多数企业邮箱服务器即使是同域发信,也要求账号完成SMTP认证后才允许发信,你当前代码没有添加身份校验逻辑,会被服务器判定为未授权中继请求。
- 运行主机未加入白名单:如果Telnet测试和Python脚本不是在同一台主机运行,当前运行Python的主机IP没有被加入邮件服务器的中继白名单,也会触发该报错。
解决方案
按优先级可以依次尝试以下修改:
- 对齐Telnet测试的HELO/EHLO逻辑
优先将无参ehlo()修改为带域名参数的helo(),完全和Telnet测试逻辑对齐:
# 替换原有的server.ehlo() server.helo("company.net") # 替换为你Telnet测试时helo后面跟的域名
如果确认服务器支持EHLO,也可以给ehlo传域名参数:
server.ehlo("company.net")
- 补全标准邮件格式
使用Python内置的email库构造合规的邮件内容,同时也方便后续添加附件需求,修复后完整代码示例:
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart # 发信配置 from_addr = 'naoufal.brahmi.external@atos.net' to_addr = 'naoufal.brahmi.external@atos.net' # 不需要SMTP认证可以删除密码配置 email_password = '你的企业邮箱密码' smtp_server_addr = 'sddlogin' smtp_port = 25 # 构造邮件对象 msg = MIMEMultipart() msg['From'] = from_addr msg['To'] = to_addr msg['Subject'] = '测试邮件' # 添加正文 msg.attach(MIMEText('Hello', 'plain', 'utf-8')) # 发信流程 server = smtplib.SMTP(smtp_server_addr, smtp_port) server.set_debuglevel(1) # 和telnet测试保持一致用helo,传企业邮箱域名 server.helo(from_addr.split('@')[1]) # 不需要SMTP认证可以注释下一行 server.login(from_addr, email_password) # 发送邮件 server.sendmail(from_addr, to_addr, msg.as_string()) print("邮件发送成功") server.quit()
- 确认主机白名单配置
如果修改后还是报错,确认你运行Python脚本的主机IP是否已经加入企业邮件服务器的中继白名单,或者联系邮件管理员确认发信权限。
注意事项
后续需要添加附件时,只需要构造MIMEBase类型的附件对象,调用msg.attach()添加到邮件对象中即可,不需要修改发信核心逻辑。
内容的提问来源于stack exchange,提问作者Hugo_Ludo_38
相关产品推荐
相关产品推荐

