You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python虚拟环境SMTP证书验证失败及Cron认证异常求助

问题分析与解决:Python SMTP邮件发送在Cron中认证失败

问题梳理

  • 本地运行Python 3.10的SMTP代码连接Office365正常
  • 公司Ubuntu服务器手动运行时,因证书问题报错unable to get local issuer certificate,改用ssl._create_unverified_context()后手动运行恢复正常
  • 但通过Cron执行同脚本时,抛出Authentication unsuccessful, the user credentials were incorrect.,手动运行凭据可正常使用

可能原因与解决方法

1. Cron环境变量缺失

Cron运行时的环境变量与用户手动登录环境不同,os.environ.get("EMAIL")和os.environ.get("EMAIL_PASSWORD")可能无法正确读取到凭据值,导致认证失败。

解决方法:

  • 直接在Cron任务中指定环境变量:
    * * * * * EMAIL=your_office365_email@domain.com EMAIL_PASSWORD=your_app_password /path/to/venv/bin/python /path/to/script.py >> /path/to/cron_log.log 2>&1
    
  • 或在脚本开头加载用户的环境配置文件(以bashrc为例):
    import os
    # 加载用户环境变量,路径根据实际用户名调整
    with open('/home/your_username/.bashrc') as f:
        for line in f:
            if '=' in line and not line.startswith('#'):
                key, val = line.strip().split('=', 1)
                os.environ[key] = val
    

2. 虚拟环境路径未正确指定

Cron可能默认使用系统Python,而非你创建的虚拟环境中的Python版本,导致依赖或配置不匹配。

解决方法:

  • 在Cron任务中使用虚拟环境Python的绝对路径,而非仅写python:
    * * * * * /home/your_username/venv/bin/python /path/to/script.py >> /path/to/cron_log.log 2>&1
    
  • 或先激活虚拟环境再执行脚本:
    * * * * * source /home/your_username/venv/bin/activate && python /path/to/script.py >> /path/to/cron_log.log 2>&1
    

3. 网络代理/防火墙限制

Cron运行时的网络环境可能未配置公司代理,导致无法正常连接Office365 SMTP服务器,进而触发凭据错误的误导性提示。

解决方法:

  • 在脚本中添加代理配置(根据公司实际代理地址调整):
    import smtplib
    import ssl
    import os
    
    smtp_server = "smtp.office365.com"
    port = 587
    sender_email = os.environ.get("EMAIL")
    password = os.environ.get("EMAIL_PASSWORD")
    
    context = ssl._create_unverified_context()
    server = smtplib.SMTP(smtp_server, port)
    
    # 设置公司代理
    server.set_proxy("your_proxy_host", port=your_proxy_port)
    
    try:
        server.starttls(context=context)
        server.login(sender_email, password)
        # 后续发送邮件逻辑
    except Exception as e:
        print(e)
    finally:
        server.quit()
    
  • 或在Cron任务中直接设置代理环境变量:
    * * * * * HTTP_PROXY=http://proxy_host:proxy_port HTTPS_PROXY=http://proxy_host:proxy_port /path/to/venv/bin/python /path/to/script.py >> /path/to/cron_log.log 2>&1
    

4. 修复证书验证问题(替代未验证上下文)

使用ssl._create_unverified_context()存在安全风险,建议正确配置证书:

  • 下载DigiCert Global Root CA证书(Office365使用的根证书),保存到服务器本地路径
  • 在脚本中指定证书文件:
    context = ssl.create_default_context(cafile='/path/to/DigiCertGlobalRootCA.crt.pem')
    

调试建议

  • 在脚本中添加日志打印(调试后删除敏感信息),确认Cron运行时是否获取到正确的凭据:
    print(f"Sender Email: {sender_email}")
    print(f"Password exists: {bool(password)}")
    
  • 查看Cron日志输出,通过tail -f /path/to/cron_log.log获取完整错误信息
  • 模拟Cron的干净环境运行脚本,排查环境差异:
    env -i /bin/bash -c "/path/to/venv/bin/python /path/to/script.py"
    

内容的提问来源于stack exchange,提问作者Fresh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:10:25