Lessons

Email Security: SPF, DKIM, DMARC

Level: Advanced Module: Mail Services 9 min read Lesson 31 of 66

Overview

  • What you’ll learn: How to implement the three pillars of email authentication — SPF, DKIM, and DMARC — to protect your domain from spoofing, reduce spam, and ensure your legitimate emails reach their recipients.
  • Prerequisites: Email Protocols, Postfix configuration, DNS management basics
  • Estimated reading time: 20 minutes

Introduction

Email was designed in an era of implicit trust. The original SMTP protocol has no built-in mechanism to verify that a sender is who they claim to be. This fundamental weakness has been exploited for decades through email spoofing — forging the “From” address to impersonate a trusted sender. Phishing attacks, business email compromise, and spam all rely on this vulnerability.

To address this problem, the email industry has developed three complementary authentication standards: SPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail), and DMARC (Domain-based Message Authentication, Reporting and Conformance). Together, these form a layered defense that allows receiving mail servers to verify the authenticity of incoming messages.

In this lesson, you will learn what each standard does, how to configure the required DNS records, how to set up DKIM signing with OpenDKIM on your Postfix server, and how to create a DMARC policy that protects your domain.

SPF: Sender Policy Framework

SPF (defined in RFC 7208) allows a domain owner to publish a DNS TXT record that specifies which IP addresses and mail servers are authorized to send email on behalf of that domain. When a receiving server gets an email claiming to be from your domain, it checks your SPF record to see if the sending server’s IP is authorized.

SPF Record Syntax

An SPF record is a DNS TXT record with a specific syntax. The record starts with v=spf1 and contains one or more mechanisms that define authorized senders:

# Example SPF record in DNS
example.com.  IN  TXT  "v=spf1 mx a:mail.example.com ip4:203.0.113.10 include:_spf.google.com -all"

# Breakdown of mechanisms:
# v=spf1        — Version identifier (required)
# mx            — Allow servers listed in the domain's MX records
# a:hostname    — Allow the IP address of the specified hostname
# ip4:address   — Allow a specific IPv4 address or CIDR range
# include:domain — Include the SPF record of another domain
# -all          — Fail (reject) all other senders

# SPF qualifiers:
# +  Pass (default, usually omitted)
# -  Fail (hard fail — reject)
# ~  SoftFail (accept but mark)
# ?  Neutral (no assertion)

# Verify your SPF record
$ dig +short TXT example.com | grep spf
"v=spf1 mx a:mail.example.com ip4:203.0.113.10 -all"

# Test SPF from the command line
$ sudo apt install spf-tools-perl -y
$ spfquery -ip 203.0.113.10 -sender user@example.com -helo mail.example.com
pass

Best practice is to use -all (hard fail) once you are confident your SPF record lists all legitimate senders. Start with ~all (soft fail) during testing to avoid losing mail.

DKIM: DomainKeys Identified Mail

DKIM (RFC 6376) uses public-key cryptography to sign outgoing emails. The sending server adds a digital signature to the email headers using a private key. The receiving server retrieves the corresponding public key from the sender’s DNS records and verifies the signature, confirming that the email was sent by an authorized server and was not tampered with in transit.

Setting Up OpenDKIM with Postfix

# Install OpenDKIM
$ sudo apt install opendkim opendkim-tools -y

# Generate a DKIM key pair
$ sudo mkdir -p /etc/opendkim/keys/example.com
$ sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s mail -v
opendkim-genkey: generating private key
opendkim-genkey: private key written to mail.private
opendkim-genkey: extracting public key
opendkim-genkey: DNS TXT record written to mail.txt

# View the public key for DNS
$ cat /etc/opendkim/keys/example.com/mail.txt
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
  "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." )

# Set permissions
$ sudo chown -R opendkim:opendkim /etc/opendkim
$ sudo chmod 600 /etc/opendkim/keys/example.com/mail.private

OpenDKIM Configuration

# Edit /etc/opendkim.conf
Syslog          yes
UMask           007
Mode            sv
Canonicalization relaxed/simple
Domain          example.com
Selector        mail
KeyFile         /etc/opendkim/keys/example.com/mail.private
Socket          local:/var/spool/postfix/opendkim/opendkim.sock
PidFile         /run/opendkim/opendkim.pid
TrustAnchorFile /usr/share/dns/root.key

# Create the socket directory
$ sudo mkdir -p /var/spool/postfix/opendkim
$ sudo chown opendkim:postfix /var/spool/postfix/opendkim

# Add Postfix to the opendkim group
$ sudo usermod -aG opendkim postfix

# Configure Postfix to use OpenDKIM — add to /etc/postfix/main.cf:
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

# Restart services
$ sudo systemctl restart opendkim
$ sudo systemctl restart postfix

DMARC: Domain-based Message Authentication

DMARC (RFC 7489) ties SPF and DKIM together by allowing domain owners to publish a policy that tells receiving servers what to do when an email fails authentication. It also provides a reporting mechanism so you can monitor who is sending email using your domain.

# DMARC DNS record — published as a TXT record at _dmarc.example.com
_dmarc.example.com.  IN  TXT  "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-forensic@example.com; pct=100; adkim=r; aspf=r"

# DMARC policy tags:
# v=DMARC1    — Version (required)
# p=          — Policy: none (monitor), quarantine (spam folder), reject (bounce)
# rua=        — Aggregate report destination (daily XML summaries)
# ruf=        — Forensic report destination (individual failure reports)
# pct=        — Percentage of messages the policy applies to (1-100)
# adkim=      — DKIM alignment: r (relaxed) or s (strict)
# aspf=       — SPF alignment: r (relaxed) or s (strict)

# Verify your DMARC record
$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; pct=100"

# Recommended rollout approach:
# Phase 1: p=none    (monitor only — collect reports, no enforcement)
# Phase 2: p=quarantine (send failures to spam — test with pct=10, increase)
# Phase 3: p=reject  (reject failures — maximum protection)

Testing and Verification

After setting up all three mechanisms, verify that everything works correctly:

# Send a test email and check headers at the receiving end
# Look for these headers in the received email:
#   Authentication-Results: spf=pass, dkim=pass, dmarc=pass

# Use online tools to verify:
# - https://mxtoolbox.com/spf.aspx (SPF check)
# - https://mxtoolbox.com/dkim.aspx (DKIM check)
# - https://mxtoolbox.com/dmarc.aspx (DMARC check)

# Check DKIM key in DNS
$ dig +short TXT mail._domainkey.example.com
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkq..."

# Verify OpenDKIM is signing outgoing mail
$ sudo journalctl -u opendkim --since "1 hour ago" | grep "DKIM-Signature"
opendkim[5678]: ABC123: DKIM-Signature field added (s=mail, d=example.com)

Key Takeaways

  • SPF publishes authorized sending IPs in a DNS TXT record; use -all to hard-fail unauthorized senders once your record is complete and tested.
  • DKIM signs outgoing messages with a private key and publishes the public key in DNS; OpenDKIM integrates with Postfix via the milter interface.
  • DMARC ties SPF and DKIM together with a policy (none/quarantine/reject) and provides aggregate and forensic reporting to monitor authentication results.
  • Roll out DMARC gradually: start with p=none to monitor, move to p=quarantine for testing, and finally p=reject for full protection.
  • All three standards work through DNS TXT records and require no changes to the email content itself — they operate at the infrastructure level to authenticate the sending server and domain.

What’s Next

In the next lesson, you will learn about Exim4, an alternative Mail Transfer Agent that is the default MTA on Debian systems, and how it compares to Postfix.

繁體中文

概述

  • 學習目標:學習如何實作電子郵件驗證的三大支柱——SPF、DKIM 和 DMARC——以保護您的網域免受偽造、減少垃圾郵件,並確保您的合法電子郵件到達收件者。
  • 先決條件:電子郵件協定、Postfix 設定、DNS 管理基礎
  • 預計閱讀時間:20 分鐘

簡介

電子郵件是在隱含信任的時代設計的。原始的 SMTP 協定沒有內建機制來驗證寄件者是否是他們聲稱的人。這個根本性的弱點數十年來一直被利用於電子郵件偽造——偽造「寄件者」地址來冒充可信賴的寄件者。網路釣魚攻擊、商業電子郵件入侵和垃圾郵件都依賴這個漏洞。

為了解決這個問題,電子郵件產業開發了三個互補的驗證標準:SPF(寄件者政策框架)、DKIM(網域金鑰識別郵件)和 DMARC(基於網域的訊息驗證、報告和一致性)。這三者共同形成分層防禦,允許接收郵件伺服器驗證傳入訊息的真實性。

在本課程中,您將學習每個標準的作用、如何設定所需的 DNS 記錄、如何在 Postfix 伺服器上使用 OpenDKIM 設定 DKIM 簽章,以及如何建立保護您網域的 DMARC 政策。

SPF:寄件者政策框架

SPF(定義於 RFC 7208)允許網域擁有者發布 DNS TXT 記錄,指定哪些 IP 位址和郵件伺服器被授權代表該網域發送電子郵件。當接收伺服器收到聲稱來自您網域的電子郵件時,它會檢查您的 SPF 記錄以確認發送伺服器的 IP 是否被授權。

SPF 記錄語法

# DNS 中的 SPF 記錄範例
example.com.  IN  TXT  "v=spf1 mx a:mail.example.com ip4:203.0.113.10 -all"

# 機制說明:
# v=spf1        — 版本識別符(必需)
# mx            — 允許網域 MX 記錄中列出的伺服器
# a:hostname    — 允許指定主機名稱的 IP 位址
# ip4:address   — 允許特定的 IPv4 位址或 CIDR 範圍
# include:domain — 包含另一個網域的 SPF 記錄
# -all          — 拒絕所有其他寄件者

# 驗證您的 SPF 記錄
$ dig +short TXT example.com | grep spf

最佳做法是在確信 SPF 記錄列出所有合法寄件者後使用 -all(硬性失敗)。在測試期間先使用 ~all(軟性失敗)以避免郵件遺失。

DKIM:網域金鑰識別郵件

DKIM(RFC 6376)使用公鑰密碼學來簽署外寄電子郵件。發送伺服器使用私鑰在電子郵件標頭中添加數位簽章。接收伺服器從寄件者的 DNS 記錄中擷取對應的公鑰並驗證簽章,確認電子郵件是由授權伺服器發送且在傳輸中未被竄改。

在 Postfix 上設定 OpenDKIM

# 安裝 OpenDKIM
$ sudo apt install opendkim opendkim-tools -y

# 產生 DKIM 金鑰對
$ sudo mkdir -p /etc/opendkim/keys/example.com
$ sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s mail -v

# 檢視用於 DNS 的公鑰
$ cat /etc/opendkim/keys/example.com/mail.txt

# 設定權限
$ sudo chown -R opendkim:opendkim /etc/opendkim
$ sudo chmod 600 /etc/opendkim/keys/example.com/mail.private

# 設定 Postfix 使用 OpenDKIM — 添加到 /etc/postfix/main.cf:
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

# 重新啟動服務
$ sudo systemctl restart opendkim
$ sudo systemctl restart postfix

DMARC:基於網域的訊息驗證

DMARC(RFC 7489)將 SPF 和 DKIM 結合在一起,允許網域擁有者發布政策,告訴接收伺服器在電子郵件驗證失敗時該怎麼做。它還提供報告機制,讓您可以監控誰在使用您的網域發送電子郵件。

# DMARC DNS 記錄 — 發布為 _dmarc.example.com 的 TXT 記錄
_dmarc.example.com.  IN  TXT  "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; pct=100"

# DMARC 政策標籤:
# p=none       — 僅監控
# p=quarantine — 放入垃圾郵件資料夾
# p=reject     — 拒絕

# 驗證您的 DMARC 記錄
$ dig +short TXT _dmarc.example.com

重點摘要

  • SPF 在 DNS TXT 記錄中發布授權的發送 IP;在記錄完整並經過測試後使用 -all 硬性拒絕未授權的寄件者。
  • DKIM 使用私鑰簽署外寄郵件並在 DNS 中發布公鑰;OpenDKIM 透過 milter 介面與 Postfix 整合。
  • DMARC 將 SPF 和 DKIM 與政策(none/quarantine/reject)結合,並提供彙總和鑑識報告以監控驗證結果。
  • 逐步推出 DMARC:從 p=none 開始監控,轉到 p=quarantine 進行測試,最後使用 p=reject 進行完全保護。
  • 三個標準都通過 DNS TXT 記錄運作,不需要更改電子郵件內容本身——它們在基礎設施層級運作以驗證發送伺服器和網域。

下一步

在下一課中,您將學習 Exim4——一個替代的郵件傳輸代理,它是 Debian 系統上的預設 MTA,以及它與 Postfix 的比較。

日本語

概要

  • 学習内容:メール認証の3つの柱——SPF、DKIM、DMARC——を実装して、ドメインのなりすましを防ぎ、スパムを削減し、正当なメールが受信者に届くようにする方法を学びます。
  • 前提条件:メールプロトコル、Postfix の設定、DNS 管理の基礎
  • 推定読了時間:20分

はじめに

メールは暗黙の信頼の時代に設計されました。元の SMTP プロトコルには、送信者が主張する本人であることを確認する組み込みメカニズムがありません。この根本的な弱点は、メールスプーフィング——信頼できる送信者になりすますために「From」アドレスを偽造すること——を通じて数十年にわたって悪用されてきました。

この問題に対処するために、メール業界は3つの補完的な認証標準を開発しました:SPF(Sender Policy Framework)、DKIM(DomainKeys Identified Mail)、DMARC(Domain-based Message Authentication, Reporting and Conformance)。これらは一緒になって、受信メールサーバーが受信メッセージの真正性を検証できる階層防御を形成します。

このレッスンでは、各標準の機能、必要な DNS レコードの設定方法、Postfix サーバーでの OpenDKIM による DKIM 署名の設定方法、ドメインを保護する DMARC ポリシーの作成方法を学びます。

SPF:Sender Policy Framework

SPF(RFC 7208 で定義)により、ドメイン所有者はそのドメインに代わってメールを送信することが許可されている IP アドレスとメールサーバーを指定する DNS TXT レコードを公開できます。

SPF レコード構文

# DNS の SPF レコード例
example.com.  IN  TXT  "v=spf1 mx a:mail.example.com ip4:203.0.113.10 -all"

# メカニズムの説明:
# v=spf1        — バージョン識別子(必須)
# mx            — ドメインの MX レコードにリストされたサーバーを許可
# a:hostname    — 指定されたホスト名の IP アドレスを許可
# ip4:address   — 特定の IPv4 アドレスまたは CIDR 範囲を許可
# include:domain — 別のドメインの SPF レコードを含める
# -all          — 他のすべての送信者を拒否(ハードフェイル)

# SPF レコードの確認
$ dig +short TXT example.com | grep spf

ベストプラクティスは、SPF レコードがすべての正当な送信者をリストしていることを確認した後に -all(ハードフェイル)を使用することです。テスト中は ~all(ソフトフェイル)から始めてください。

DKIM:DomainKeys Identified Mail

DKIM(RFC 6376)は公開鍵暗号を使用して送信メールに署名します。送信サーバーが秘密鍵を使用してメールヘッダーにデジタル署名を追加し、受信サーバーが送信者の DNS レコードから対応する公開鍵を取得して署名を検証します。

Postfix での OpenDKIM の設定

# OpenDKIM のインストール
$ sudo apt install opendkim opendkim-tools -y

# DKIM 鍵ペアの生成
$ sudo mkdir -p /etc/opendkim/keys/example.com
$ sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s mail -v

# DNS 用の公開鍵を表示
$ cat /etc/opendkim/keys/example.com/mail.txt

# 権限の設定
$ sudo chown -R opendkim:opendkim /etc/opendkim
$ sudo chmod 600 /etc/opendkim/keys/example.com/mail.private

# Postfix で OpenDKIM を使用するよう設定 — /etc/postfix/main.cf に追加:
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

# サービスの再起動
$ sudo systemctl restart opendkim
$ sudo systemctl restart postfix

DMARC:ドメインベースのメッセージ認証

DMARC(RFC 7489)は SPF と DKIM を結びつけ、ドメイン所有者がメール認証に失敗した場合に受信サーバーがどうすべきかを指示するポリシーを公開できるようにします。また、ドメインを使用してメールを送信している人を監視するためのレポートメカニズムも提供します。

# DMARC DNS レコード — _dmarc.example.com の TXT レコードとして公開
_dmarc.example.com.  IN  TXT  "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; pct=100"

# DMARC ポリシータグ:
# p=none       — 監視のみ
# p=quarantine — スパムフォルダに送信
# p=reject     — 拒否

# DMARC レコードの確認
$ dig +short TXT _dmarc.example.com

重要ポイント

  • SPF は DNS TXT レコードで許可された送信 IP を公開します。レコードが完成しテスト済みになったら -all で未許可の送信者をハードフェイルします。
  • DKIM は秘密鍵で送信メッセージに署名し、DNS で公開鍵を公開します。OpenDKIM は milter インターフェースを介して Postfix と統合されます。
  • DMARC は SPF と DKIM をポリシー(none/quarantine/reject)で結びつけ、認証結果を監視するための集約レポートとフォレンジックレポートを提供します。
  • DMARC は段階的にロールアウトします:p=none で監視から始め、p=quarantine でテストし、最終的に p=reject で完全保護にします。
  • 3つの標準はすべて DNS TXT レコードを通じて機能し、メールコンテンツ自体の変更は不要です——送信サーバーとドメインを認証するためにインフラストラクチャレベルで動作します。

次のステップ

次のレッスンでは、Debian システムのデフォルト MTA である代替メール転送エージェント Exim4 と、Postfix との比較について学びます。

You Missed