Odysec

郵件安全的五種靜默失效

WHITE PAPER2026-07-31Odysec

SPF、DKIM、DMARC 有一個共同的特性:設定錯了不會產生任何錯誤訊息。DNS 記錄照常存在、設定介面照常顯示綠色勾勾,故障只發生在別人的收件匣裡——收件方安靜地把您的防偽機制當成不存在,或者安靜地放行冒用您網域的信件。本文整理我們在郵件安全體檢服務的規則開發與真實網域檢測中,反覆遇到的五種靜默失效模式。每一種都附上成因、可自行執行的驗證方法與修正方式。

為什麼是「靜默」

郵件防偽三件套(SPF/DKIM/DMARC)的驗證發生在收件方的伺服器上。您這一端沒有任何程式在執行這些規則——您只是發布了幾筆 DNS 記錄,然後由全世界的收件方各自解讀。這個架構決定了它的故障模式:

換句話說,郵件安全設定的預設故障模式就是靜默失效。以下五種,是我們認為最值得逐一檢查的。

一、兩筆 SPF 記錄:整條 SPF 因此失效

依規範(RFC 7208 §3.2),一個網域只能有一筆 SPF 記錄。出現兩筆時,驗證結果是 permerror,收件方會把它當成「無法判定」——等於完全沒有設定 SPF

這一項的危險之處在於:兩筆記錄各自看起來都是對的。逐筆檢視時每一筆的語法都正確,DNS 查詢也都查得到,設定介面不會有任何警告。最常見的成因是新增郵件服務時(例如在既有的郵件服務商之外加了行銷寄信平台),照著新服務商的說明文件「新增一筆 TXT 記錄」——而不是把新的 include 併進原本那筆。

$ dig +short TXT example.com | grep -i v=spf1
"v=spf1 include:_spf.google.com ~all"
"v=spf1 include:spf.mailprovider.net ~all"   ← 兩筆=permerror

修正:把所有來源合併進同一筆記錄(多個 include 併在同一行),刪掉其餘。

v=spf1 include:_spf.google.com include:spf.mailprovider.net ~all

二、兩筆 DMARC 記錄:整個政策視為不存在

與 SPF 同型但後果更徹底。依 RFC 7489 §6.6.3,_dmarc 底下出現多筆記錄時,收件方應視為完全沒有政策——不是取其中一筆,是整組當作不存在。所以就算其中一筆寫著 p=reject,實際效果等同完全未設定 DMARC。

最常見的成因是郵件服務商的設定精靈:偵測到您「還沒有它建議的那筆 DMARC」時,引導您新增一筆,而不是修改既有的。兩家服務商的精靈各跑一次,就會留下兩筆。

$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
"v=DMARC1; p=none"        ← 第二筆讓 p=reject 也一併失效

修正:只保留一筆,刪掉其餘。合併時以較嚴格的政策為準。

三、SPF 展開超過 10 次 DNS 查詢

規範規定 SPF 驗證過程中,會觸發 DNS 查詢的機制(includeredirectamxexistsptr)合計最多 10 次,超過即 permerror=整條 SPF 失效。

這一項幾乎都是被動踩到的:您自己只寫了三、四個 include,看起來離上限很遠——但每個服務商的 SPF 內部又 include 了別人,遞迴展開後輕易超標。更麻煩的是,這個數字不受您控制:服務商調整自己的 SPF 結構時,您的展開次數會跟著變,可能在您完全沒有改動任何設定的情況下越過上限。沒有任何介面會提醒您,症狀只會是「某些收件方開始退信」。

驗證:手動遞迴展開每個 include 並累計查詢次數,或使用會計算展開次數的檢測工具(我們的郵件安全體檢會遞迴展開並回報實際次數)。

修正:移除已經不再使用的服務商 include;若確實需要多家服務,考慮 SPF 扁平化(將 include 展開為 IP 位址清單,但需搭配自動更新機制,否則服務商換 IP 時會再次靜默失效)。已達 8 次以上時建議現在就清理,預留服務商變動的緩衝。

四、DMARC 報告寄往外部網域,但缺少授權記錄

DMARC 的 rua 彙總報告是您唯一的能見度來源:有誰在冒用您的網域、自己的哪個寄件系統驗證失敗,都只能從報告得知。而這裡有一個多數檢測工具不查、卻是「報告永遠收不到」實際成因的機制:

rua 指向其他網域的信箱時(例如 example.com 的報告寄到 example-corp.net),接收方網域必須發布一筆授權記錄明示同意,否則多數回報者——包括 Google 與 Microsoft——不會寄送報告。您會以為報告機制在運作,實際上一封都收不到;而「沒有收到任何東西」這種故障,不會產生任何錯誤通知。

授權記錄的方向極容易搞反,規則是:記錄放在收報告的網域上、以被報告的網域命名

名稱:example.com._report._dmarc.example-corp.net
類型:TXT
內容:v=DMARC1
(example.com 發布報告 → example-corp.net 收;記錄加在 example-corp.net)

驗證:檢查自己的 rua 位址網域是否與主網域不同;不同時,查詢上述格式的 TXT 記錄是否存在。

五、反向案例:DKIM 的空 selector 不是故障

前四種是「看起來正常、實際失效」;第五種相反——看起來像故障、實際上是正常的,危險在於它會誘導錯誤的修復動作。

查詢 DKIM selector 時,常會發現某些 selector 的 TXT 記錄存在、但 p= 公鑰內容是空的。部分檢測工具會把它報成錯誤(「DKIM 金鑰無效」),但這多半是服務商預留給金鑰輪替的空位——Proton、Google 等服務商都會建立多個 selector,輪替時才填入新金鑰。空的 selector 依規範(RFC 6376 §3.6.1)語意是「此金鑰已撤銷」,收件方會正確地跳過它去驗其他 selector,不影響現行簽章的驗證。

把它當故障處理的常見結果,是管理者動手「修好它」——刪掉服務商建立的 CNAME、或自行填入內容——反而破壞了服務商的輪替機制。判讀原則:只要有至少一個 selector 帶有效公鑰、且該 selector 與服務商後台顯示的一致,空 selector 不需處理。

附帶一提 DKIM 檢測的固有限制:selector 名稱無法列舉,任何外部工具(包括我們的)都只能猜測常見名稱。外部工具說「找不到 DKIM」時,可能是您用了自訂 selector,也可能真的沒設——這項永遠要以郵件服務商後台為準。

自我檢查清單

檢查項指令期望結果
SPF 記錄數dig +short TXT 網域 | grep -ci v=spf1恰好 1
DMARC 記錄數dig +short TXT _dmarc.網域 | grep -ci v=dmarc1恰好 1
SPF 展開次數遞迴展開所有 include 累計≤ 10,建議 ≤ 8
跨網域 rua 授權dig +short TXT 網域._report._dmarc.收報告網域rua 為外部網域時須存在
DMARC 政策檢視 p=目標為 reject;p=none 只有能見度、沒有防護
驗證時的一個陷阱。剛修改過的記錄用公共 resolver(如 1.1.1.1)查詢,可能回快取的舊值,看起來像修改沒有生效。修改後的驗證請對權威伺服器查詢,或用兩個不同的公共 resolver 交叉確認。

本文的方法與限制

以上五種模式全部實作在我們的免費郵件安全體檢中,輸入網域即可對照本文逐項檢查;該服務只查詢公開的 DNS 記錄,不連線您的郵件主機,也不需要任何授權。誠實揭露其限制:DNS 層的檢測不驗證郵件的實際投遞行為——記錄全部正確、投遞仍可能因其他原因失敗;DKIM 只能探測常見 selector(見第五節)。檢測結果應與您郵件服務商後台的狀態互相對照。