Appendix E. Mail Services (邮件服务)
Appendix E. Mail Services (邮件服务)
本附录讨论各种邮件服务场景下的 SPF 实施考虑。
E.1 Web-Based Mail Services (基于 Web 的邮件服务)
E.1.1 服务提供商视角
场景: 提供 webmail 服务(如 Gmail, Yahoo Mail, Outlook.com)
SPF 考虑:
1. 用户从多个域发送邮件
2. 所有邮件通过服务提供商的服务器发送
3. 需要适当的 SPF 记录
配置示例:
# 服务提供商的主域
mailprovider.com IN TXT "v=spf1 ip4:203.0.113.0/24 ip4:198.51.100.0/24 -all"
# 用户自定义域支持
# 用户需要在其域中包含服务提供商
user-domain.com IN TXT "v=spf1 include:_spf.mailprovider.com -all"
_spf.mailprovider.com IN TXT "v=spf1 ip4:203.0.113.0/24 ip4:198.51.100.0/24 -all"
E.1.2 自定义域配置
用户需求: 使用自定义域通过 webmail 服务发送邮件
配置步骤:
- 验证域所有权
服务提供商要求添加验证记录:
_verification.user-domain.com IN TXT "provider-verification-code"
- 配置 SPF
user-domain.com IN TXT "v=spf1 include:_spf.mailprovider.com -all"
- 配置 DKIM
# 服务提供商提供 DKIM 公钥
selector._domainkey.user-domain.com IN TXT "v=DKIM1; k=rsa; p=MIGfMA0..."
- 配置 DMARC
_dmarc.user-domain.com IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
E.2 Shared Hosting Services (共享主机服务)
E.2.1 挑战
问题: 多个客户共享相同的 IP 地址
hosting-provider.com: 203.0.113.10
customer1.com: 托管在 203.0.113.10
customer2.com: 托管在 203.0.113.10
customer3.com: 托管在 203.0.113.10
SPF 要求: 每个客户域都需要授权共享 IP
E.2.2 解决方案
方案 1: 统一 SPF 包含
# 主机提供商提供
_spf.hosting-provider.com IN TXT "v=spf1 ip4:203.0.113.0/24 -all"
# 客户配置
customer1.com IN TXT "v=spf1 include:_spf.hosting-provider.com -all"
customer2.com IN TXT "v=spf1 include:_spf.hosting-provider.com -all"
customer3.com IN TXT "v=spf1 include:_spf.hosting-provider.com -all"
方案 2: 直接 IP 授权
# 每个客户独立配置
customer1.com IN TXT "v=spf1 ip4:203.0.113.10 -all"
customer2.com IN TXT "v=spf1 ip4:203.0.113.10 -all"
优点: 简单, 无依赖 缺点: IP 变更时所有客户都需要更新
方案 3: 专用 IP(推荐用于大客户)
# 为重要客户分配专用 IP
important-customer.com IN TXT "v=spf1 ip4:203.0.113.50 -all"
E.2.3 最佳实践
主机提供商应该:
1. 提供清晰的 SPF 配置文档
2. 自动生成 SPF 记录(通过控制面板)
3. 通知客户 IP 地址变更
4. 提供 SPF 验证工具
客户应该:
1. 使用 include 方法引用主机提供商的 SPF
2. 定期验证 SPF 记录
3. 监控邮件送达率
E.3 Enterprise Mail Systems (企业邮件系统)
E.3.1 复杂环境
典型企业场景:
- 多个数据中心
- 多个出站邮件服务器
- 第三方邮件服务(营销、通知等)
- 办公室本地服务器
- 云服务集成
SPF 配置挑战:
1. DNS 查询限制(10 次)
2. 记录大小限制(512 字节)
3. 多个部门/业务单元
4. 频繁的基础设施变更
E.3.2 企业 SPF 架构
分层设计:
# 主域
company.com IN TXT "v=spf1 include:_spf-internal.company.com include:_spf-external.company.com -all"
# 内部服务器
_spf-internal.company.com IN TXT "v=spf1 ip4:10.0.0.0/8 ip4:203.0.113.0/24 -all"
# 外部服务
_spf-external.company.com IN TXT "v=spf1 include:_spf.salesforce.com include:sendgrid.net include:mailchimp.com -all"
# 部门子域
marketing.company.com IN TXT "v=spf1 include:_spf-marketing.company.com -all"
_spf-marketing.company.com IN TXT "v=spf1 include:sendgrid.net include:mailchimp.com -all"
IP 范围管理:
# 数据中心 A
_spf-dc-a.company.com IN TXT "v=spf1 ip4:203.0.113.0/25 -all"
# 数据中心 B
_spf-dc-b.company.com IN TXT "v=spf1 ip4:198.51.100.0/25 -all"
# 汇总
_spf-datacenters.company.com IN TXT "v=spf1 include:_spf-dc-a.company.com include:_spf-dc-b.company.com -all"
E.3.3 SPF 扁平化策略
问题: 超过 10 次 DNS 查询限制
解决方案: 定期扁平化
# 自动化脚本
def flatten_spf_includes():
"""
定期查询所有 include 域的 IP
生成扁平化的 SPF 记录
"""
includes = [
'_spf.salesforce.com',
'sendgrid.net',
'mailchimp.com'
]
ips = []
for domain in includes:
# 解析 SPF 记录并提取 IP
ips.extend(resolve_spf_ips(domain))
# 生成新的 SPF 记录
spf_record = f"v=spf1 {' '.join([f'ip4:{ip}' for ip in ips])} -all"
# 更新 DNS(通过 API)
update_dns_record('_spf-flattened.company.com', spf_record)
# 每周运行一次
注意: 扁平化后需要定期更新, 因为第三方 IP 可能变更
E.4 Email Marketing Services (邮件营销服务)
E.4.1 服务配置
常见服务:
- SendGrid
- Mailchimp
- Amazon SES
- Mailgun
SPF 配置示例:
SendGrid:
company.com IN TXT "v=spf1 include:sendgrid.net -all"
Mailchimp:
company.com IN TXT "v=spf1 include:servers.mcsv.net -all"
Amazon SES:
company.com IN TXT "v=spf1 include:amazonses.com -all"
组合使用:
company.com IN TXT "v=spf1 mx include:sendgrid.net include:servers.mcsv.net -all"
E.4.2 子域策略
最佳实践: 为营销邮件使用专用子域
# 主域(用于重要业务邮件)
company.com IN TXT "v=spf1 mx -all"
# 营销子域
marketing.company.com IN TXT "v=spf1 include:sendgrid.net -all"
# 通知子域
notifications.company.com IN TXT "v=spf1 include:amazonses.com -all"
优势:
1. 分离声誉(营销邮件不影响主域)
2. 更容易管理 SPF 记录
3. 更好的监控和报告
4. 符合 DMARC 最佳实践
E.4.3 DKIM 配置
与 SPF 配合:
# SPF
marketing.company.com IN TXT "v=spf1 include:sendgrid.net -all"
# DKIM(由 SendGrid 提供)
s1._domainkey.marketing.company.com IN CNAME s1.domainkey.u12345.wl.sendgrid.net
s2._domainkey.marketing.company.com IN CNAME s2.domainkey.u12345.wl.sendgrid.net
# DMARC
_dmarc.marketing.company.com IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:[email protected]"
E.5 Transactional Email Services (事务性邮件服务)
E.5.1 场景
事务性邮件:
- 注册确认
- 密码重置
- 订单通知
- 账单和收据
服务提供商:
- Amazon SES
- SendGrid
- Mailgun
- Postmark
E.5.2 配置
使用专用子域:
# 事务性邮件子域
transactional.company.com IN TXT "v=spf1 include:_spf.mailgun.org -all"
# DKIM
smtp._domainkey.transactional.company.com IN TXT "v=DKIM1; k=rsa; p=..."
应用程序配置:
# Django 示例
EMAIL_HOST = 'smtp.mailgun.org'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_FROM = '[email protected]'
# 发送邮件
send_mail(
subject='Password Reset',
message='Click here to reset...',
from_email='[email protected]',
recipient_list=['[email protected]']
)
E.5.3 监控
关键指标:
- 邮件送达率
- 退信率
- SPF pass 率
- DKIM pass 率
- DMARC 对齐率
- 投诉率
告警设置:
if delivery_rate < 95%:
alert("Delivery rate dropped below 95%")
if spf_pass_rate < 98%:
alert("SPF configuration issue detected")
E.6 Mobile and IoT Devices (移动和物联网设备)
E.6.1 挑战
移动设备:
- 动态 IP 地址
- 通过运营商网络发送
- 无法在 SPF 中列出
IoT 设备:
- 大量设备
- 分布在不同网络
- 直接发送邮件
E.6.2 解决方案
方案 1: 使用 SMTP 中继
设备 → SMTP 中继 → 接收方
配置:
- 设备通过认证连接到中继
- 中继服务器在 SPF 记录中授权
- 中继添加 DKIM 签名
SPF 配置:
iot-devices.company.com IN TXT "v=spf1 mx include:_spf-relay.company.com -all"
_spf-relay.company.com IN TXT "v=spf1 ip4:203.0.113.50 -all"
方案 2: API 发送
设备通过 HTTP API 发送邮件:
- 使用第三方服务(如 SendGrid API)
- 服务提供商的 SPF 记录覆盖
- 无需设备直接发送 SMTP
E.7 Best Practices Summary (最佳实践摘要)
E.7.1 通用建议
1. 使用子域分离不同类型的邮件
2. 实施 SPF + DKIM + DMARC 三重保护
3. 定期审查和更新 SPF 记录
4. 监控 DNS 查询限制
5. 使用 include 而不是直接列出所有 IP
6. 为关键服务使用专用 IP
7. 实施邮件认证监控
8. 建立事件响应流程
E.7.2 配置检查清单
发布前检查:
□ SPF 记录语法正确
□ DNS 查询数量 ≤ 10
□ 记录大小 < 512 字节
□ 所有发送服务器已授权
□ 使用适当的限定符(-all 或 ~all)
□ DKIM 已配置
□ DMARC 策略已发布
□ 测试邮件已发送并验证
持续监控:
□ 每周检查 DMARC 报告
□ 监控邮件送达率
□ 跟踪 SPF/DKIM 失败
□ 审查新的发送源
□ 更新第三方服务变更