首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >腾讯云主机上的 WordPress 发信:SPF、DKIM、DMARC 按顺序配,不动现有邮件

腾讯云主机上的 WordPress 发信:SPF、DKIM、DMARC 按顺序配,不动现有邮件

原创
作者头像
用户10345225
发布于 2026-11-04 15:48:25
发布于 2026-11-04 15:48:25
1070
举报

见过一种做法:查到一个 SPF 生成器,把记录贴进 DNS,再把 DMARC 直接写成 p=reject,觉得这样最严格、最安全。第二天财务说报价单被对方系统退回了——给这个域名发信的不止网站,还有企业邮箱、ERP、开票平台,它们都不在 SPF 里,DMARC 又要求严格拒绝。

认证可以分步做,每一步都能单独验证、单独回退。下面按「先不影响现有邮件」的顺序走一遍。

先列清单:这个域名上有谁在发信

动 DNS 之前,先把发信来源摸清楚。少列一个,后面收紧策略时就会挡掉它。

来源

走哪个服务

你能否改它的 DNS

发信量

备注

网站表单通知

云主机 / 邮件推送

是

每天几十封

本文重点

企业邮箱

邮箱服务商

是

每天几十封

通常已配好

财务 / 开票系统

第三方 SaaS

不一定

每周几封

最容易漏

群发 / 开发信

推送平台

是

按活动

单独子域名更稳

监控告警

自建脚本

不定

不定

常被遗忘

清单列完,再决定哪些来源是必须保住的。这一步做完,后面每改一条记录,你都知道自己在影响谁。

如果这台主机和站点是从别人手上接过来的,配置历史无从查起,可以先跑一遍 AumCreate 的站点检查工具:https://aumcreate.com/tools/site-check?utm_source=tencent&utm_medium=content&utm_campaign=tencent-wp-mail-dmarc-progressive 。它替不了你做认证,但能省掉「这条记录到底是谁加的」这种考古。

SPF 一个域名只能有一条,先把现有的并起来

SPF 是放在域名 TXT 里的一条 v=spf1 ... 记录,作用是告诉收件方「这些服务器有权用我的域名发信」。两条并存会直接 permerror,等于没配。

代码语言:bash
复制
dig +short example.com TXT | grep spf1

如果查出两条以上,先合并成一条再往下走。合并时盯的是查询预算,不是记录条数:

查询次数上限 10 次。 include: 每出现一次算一次查询,被 include 的那条 SPF 里如果还有 include,继续累加。超过 10 次,整条 SPF 失效。数的方法是逐条 dig 下去看返回里还有没有 include,手工记。

void lookup 上限 2 次。 查询一个不存在的域名算 void lookup,超过 2 次同样判失败。写错的 include 域名比不写更糟。

单条 TXT 的字符串长度上限 255 字符。 超了要拆成多段字符串,多数 DNS 服务商的输入框会自动处理,自己拼的时候留意。

结尾用 ~all 还是 -all:~all 是软失败,标成可疑但多数情况仍会收;-all 是硬失败,不在列表里的直接拒。现有系统不确定的时候先留 ~all,等 DMARC 观察期的报告证明没有漏网来源,再改 -all。

先上 DKIM,因为它只做加法

DKIM 是签名:发信方用私钥给邮件签名,公钥挂在 DNS 里,收件方拿公钥验。它不影响现有什么能发、什么不能发,所以放在第一步风险最低。

自建 Postfix 的话,OpenDKIM 的配置大致是这样。关键是 Mode sv 和 milter_default_action = accept——只签名、只验证,不做拒绝,milter 进程挂掉也不会把邮件拦下来。

代码语言:txt
复制
# /etc/opendkim.conf
Domain                  example.com
Selector                mail
KeyFile                 /etc/opendkim/keys/example.com/mail.private
SigningTable            refile:/etc/opendkim/signing.table
KeyTable                refile:/etc/opendkim/key.table
InternalHosts           /etc/opendkim/trusted.hosts
Mode                    sv
代码语言:txt
复制
# /etc/opendkim/signing.table
*@example.com   mail._domainkey.example.com

# /etc/opendkim/key.table
mail._domainkey.example.com   example.com:mail:/etc/opendkim/keys/example.com/mail.private

# /etc/opendkim/trusted.hosts
127.0.0.1
::1
localhost
代码语言:txt
复制
# /etc/postfix/main.cf
smtpd_milters           = inet:127.0.0.1:8891
non_smtpd_milters       = $smtpd_milters
milter_default_action   = accept

公钥发布到 mail._domainkey.example.com,值从控制台或 opendkim-genkey 生成,以你手上的公钥为准:

代码语言:bash
复制
dig +short mail._domainkey.example.com TXT

验证方式是给自己发一封,看邮件头里的 Authentication-Results 有没有 dkim=pass。这一步通过之前,不要动 SPF。

再改 SPF,重点是对齐

改 SPF 之前先想清楚:网站邮件到底是「主机直接发出去」还是「提交给邮件推送服务代发」。

腾讯云 CVM 默认对出站 25 端口有限制,需要单独申请解封;弹性公网 IP 的反向解析(PTR)也要提交工单,而且一个 IP 只对应一个 PTR。自建直发意味着端口、PTR、IP 信誉都得自己扛,新 IP 还得慢慢预热。对绝大多数站点来说,走 587 提交给邮件推送服务更省事,认证和信誉由服务方承担。

走代发的话,SPF 里要加的是服务方给的 include,不是主机 IP。同时注意对齐:DMARC 检查的是 From 头里的域名和 SPF/DKIM 的域名是否一致。代发场景下 Return-Path 往往是服务方的域,SPF 就算 pass,也可能因为域名不一致而不算对齐——这正是先配 DKIM 的原因,DKIM 签名用的是你自己的域,天生对齐。

DMARC 从 p=none 开始,观察够了再收紧

DMARC 记录长这样,先只观察:

代码语言:txt
复制
_dmarc.example.com  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com; fo=1; adkim=r; aspf=r"
  • p=none:只发报告,不影响投递。这是「先不影响现有邮件」的核心。
  • rua:聚合报告收件地址,每天一封,内容是 zip 包,里面是 XML。
  • adkim / aspf 用 r(宽松)起步,别一上来就 s(严格)。

报告不要攒着不看。解压后按来源 IP 汇总,看 pass 比例、哪些 IP 在 fail、fail 的那些 IP 是不是清单里的已知系统。有人用脚本解析 XML,也可以直接搜在线解析工具,把 zip 传上去看。

观察两到四周,确认没有意外来源之后,按这个节奏收紧,每一步之间留几天:

代码语言:txt
复制
v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc@example.com
v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc@example.com
v=DMARC1; p=reject; rua=mailto:dmarc@example.com

pct 是百分比,从 25 开始意味着只有四分之一的邮件按这个策略处理,出问题也只影响一部分。报告里出现你没见过的来源,先联系对方确认,别急着加进 SPF。

回退很简单:把记录改回上一条。前提是动之前把 TTL 调到几分钟,不然改了也要等缓存过期才生效。

子域名默认继承主域策略,如果子域名有独立的发信系统还没配好,可以单独写 sp=none,别让它跟着主域一起被拒。

WordPress 侧:切到 587 提交

认证配好之后,站内的发信方式也要跟着改。用一个 mu-plugin 接管 PHPMailer,不用装插件:

代码语言:php
复制
<?php
// wp-content/mu-plugins/smtp-relay.php
add_action( 'phpmailer_init', function ( $phpmailer ) {
    $phpmailer->isSMTP();
    $phpmailer->Host       = getenv( 'SMTP_HOST' ) ?: 'smtp.example.com';
    $phpmailer->Port       = 587;
    $phpmailer->SMTPAuth   = true;
    $phpmailer->Username   = getenv( 'SMTP_USER' ) ?: '';
    $phpmailer->Password   = getenv( 'SMTP_PASSWORD' ) ?: '';
    $phpmailer->SMTPSecure = 'tls';
    $phpmailer->From       = getenv( 'SMTP_FROM' ) ?: 'no-reply@example.com';
    $phpmailer->FromName   = 'Example';
    $phpmailer->Sender     = $phpmailer->From;
} );

密码只从环境变量读,不要写进代码,也不要提交到版本库。注入方式跟着你的运行环境走:php-fpm 在池配置里给进程加环境变量,systemd 用 Environment=,容器用 secret;值本身放进密钥管理系统,文件里只留 SMTP_PASSWORD=<你的密钥> 这种占位说明。

代码语言:bash
复制
# 在启动 PHP 的环境里注入,不要出现在仓库里
export SMTP_PASSWORD="$(your-secret-tool read smtp/password)"

Sender 影响的是信封发件人(Return-Path),From 影响的是收件人看到的发件人。两者域名一致,对齐才稳。有些推送服务会强制改写 Return-Path,以服务商文档为准。

发一封测试信,看完整头和认证结果:

代码语言:bash
复制
swaks --to you@example.com --from no-reply@example.com \
  --server smtp.example.com:587 --tls \
  --auth LOGIN --auth-user "$SMTP_USER" --auth-password "$SMTP_PASSWORD"

认证全过还是进垃圾箱,按这个顺序查

先看头,别猜。Authentication-Results 里 SPF、DKIM、DMARC 三个都 pass 且对齐,才轮到查别的。

顺序是:认证结果 → 域名和 IP 信誉(查黑名单)→ 退信率和投诉率 → 内容(链接数量、纯文本替代、图片占比)→ 链路(Received 跳数、投递延迟)→ 互动信号(打开、回复、被标垃圾)。

前两项是硬门槛,后几项是打分项。很多人卡在「认证都过了为什么还是进垃圾箱」,八成是域名太新、发信量突然放大,或者名单里躺着一堆早就失效的地址。新域名和新 IP 要慢慢加量,第一天发五十封、第二天发一百封,比一次发五千封安全。

群发平台能保证什么,不能保证什么

平台负责的是基础设施:IP 池、认证、退信处理、速率控制。它不能保证进收件箱——收件方的过滤规则、用户投诉、名单质量都在平台之外。

写进合同的应该是可核查的东西:退信率、投诉率的处理阈值,出现黑名单时谁负责申诉,退款条件。别接受「保证送达率 99%」这种说法,没有哪家能对别人的收件箱做承诺。

外贸开发信:分组、频率、清洗

  • 按来源分组发,不要把所有名单塞进一次群发。
  • 硬退信(地址不存在)立刻移除,不重试。
  • 软退信设重试上限,试三次还不行就暂停,别一直打。
  • 发信量做阶梯,新域名从每天几十封起。
  • 每封信带可用的退订方式,退订请求立即生效。
  • 内容以文字为主,链接不超过必要的几个,图片不要堆。
  • 长期没互动的联系人单独放一个组,降频或停止发送。

上线验收

  • dig 查 SPF,确认只有一条,include 数量在 10 以内。
  • dig 查 mail._domainkey,公钥能取到。
  • 发一封测试信,三个认证结果都是 pass,且 DKIM 域与 From 域一致。
  • DMARC 记录是 p=none 起步,rua 地址能收到报告。
  • 网站表单邮件走 587 提交,不再依赖主机 25 端口。
  • 报告连续两周没有意外来源,再改 pct 和 p。
  • 每一步改动前的记录值都留了一份,随时能改回去。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 先列清单:这个域名上有谁在发信
  • SPF 一个域名只能有一条,先把现有的并起来
  • 先上 DKIM,因为它只做加法
  • 再改 SPF,重点是对齐
  • DMARC 从 p=none 开始,观察够了再收紧
  • WordPress 侧:切到 587 提交
  • 认证全过还是进垃圾箱,按这个顺序查
  • 群发平台能保证什么,不能保证什么
  • 外贸开发信:分组、频率、清洗
  • 上线验收
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档