Files
homelab-wiki/services/smtp-relay.md

3.4 KiB
Raw Permalink Blame History

title, lifecycle, evidence, last_reviewed, last_verified
title lifecycle evidence last_reviewed last_verified
SMTP relay 应用发信指南 unknown documented 2026-09-16 null

SMTP relay

为集群应用提供统一出站邮件入口:应用通过集群内 SMTP 连接 relay, relay 再使用 STARTTLS 与 XOAUTH2 向 Microsoft 365 提交邮件。 本页依据 homelab-infra apps/smtp-relay/README.md 与 Service/Deployment 配置整理, 本轮没有连接 relay、发送邮件或查询邮箱。

应用接入参数

参数 已记录值
SMTP host smtp-relay.smtp-relay.svc.cluster.local
SMTP port 25
应用到 relay 的 TLS 此内部链路按明文 SMTP 配置
应用到 relay 的认证 不提供用户名或密码
From / envelope sender [email protected]
relay 的上游 smtp.office365.com:587,STARTTLS + XOAUTH2

这里的无认证入口限于既定内部使用路径,不能直接把它暴露为外部发信入口。 其他发件身份需要对应的 Send As 授权,不能只在应用中随意改 From。 应用只需要 relay 参数,不需要读取或持有 Microsoft 365 refresh token。

发送一封接入测试邮件

下面在已能访问集群 Service 的应用环境中使用 Python 标准库。 将 SMTP_TEST_RECIPIENT 设置为自己控制的收件地址;执行会真实发送邮件,应先得到该次发信授权。 这份示例本轮未执行。

import os
import smtplib
from email.message import EmailMessage

recipient = os.environ["SMTP_TEST_RECIPIENT"]
sender = "[email protected]"
message = EmailMessage()
message["From"] = sender
message["To"] = recipient
message["Subject"] = "Homelab SMTP relay test"
message.set_content("SMTP relay integration test.")
with smtplib.SMTP("smtp-relay.smtp-relay.svc.cluster.local", 25, timeout=30) as smtp:
    refused = smtp.send_message(message, from_addr=sender, to_addrs=[recipient])
    if refused:
        raise SystemExit("收件人被拒绝,请检查 relay 状态")

客户端提交成功只表示 relay 接收,不保证最终送达。 维护者随后结合 relay 投递日志与收件箱确认完整链路;也检查垃圾邮件文件夹。 日志中的上游接收结果仍不能替代收件人侧确认。

失败时如何区分

  • 连接超时或域名失败:检查集群 DNS、Service 与应用网络范围。
  • relay 接收但不送达:检查投递队列、上游连接和认证,而不是给应用配置上游密码。
  • 535 5.7.3:源码提示检查 OAuth 身份是否为实际 sender,以及 token 是否需要重新初始化。
  • 5.7.60:检查 From、envelope sender 与 Microsoft 365 的发信授权是否匹配。

消费者接入不能通过重跑完整 Terraform、部署或 OAuth 初始化流程来试错。 refresh token 持久化在 smtp-relay-tokens PVC,SASL 层负责更新; 它是可变运行数据,不是可复制进 wiki 的配置。 源码的 device-code 流程使用 public client,维护说明明确 CLIENT_SECRET 留空; 不要照抄同一旧 README 中与之不一致的“创建 client secret”注释。

初始化、重新授权、DKIM 与恢复入口为 apps/smtp-relay/README.md。 其中 DKIM 等日期属于历史记录,本文不将其升级为新一次验证。 依赖为 Kubernetes/DNS、token PVC、Microsoft 365 邮箱与授权、上游网络及域名邮件配置。

来源文件的固定版本与工作区差异见来源追溯。