コンテンツへスキップ
Guide

SPF、DMARC、DKIM: 完全な電子メール認証ガイド

| 9 min read

SPF、DMARC、DKIM がドメインをスプーフィングからどのように保護するかを学びます。 無料の API 呼び出しを使用して 3 つのレコードすべてを 30 秒で監査し、最も一般的な 6 つの構成ミスを修正します。

Email security authentication flow diagram
Photo by Towfiqu barbhuiya on Unsplash

ドメインはすべてのセキュリティ スキャンに合格します。 SSL 証明書は有効で、ヘッダーは厳密で、 CSP はロックダウンされています。 その後、あなたのドメインからフィッシングメールが顧客の受信箱に届きます。 「差出人」フィールドに会社名を入れてください。 メールは偽物ですが、被害は本物です。

これは、電子メールが 1982 年に送信者検証が組み込まれていないように設計されたために発生します。 誰でも SPF、DMARC、DKIM レコードを使用せずに、電子メールに任意の「差出人」アドレスを設定できます。 ドメインの場合、受信サーバーは偽造を検出する方法がありません。 フィッシング攻撃の 90% 以上で使用されているのは、 ドメイン スプーフィングや電子メール認証の設定ミスが扉を開きます。

このガイドでは、各レコードの機能、それらがどのように連携するか、および 3 つすべてを監査する方法について説明します。 任意のドメインで単一のスクリプトを使用して、 Botoi DNS セキュリティ API

電子メール認証の仕組み

3 つの DNS レコードが防御層として機能します。 それぞれが異なる問題を解決します。

  1. SPF 答え: 「このサーバーはこのドメインへの電子メールの送信を許可されていますか?」
  2. DKIM 答え: 「このメッセージは送信者のサーバーから送信された後に変更されましたか?」
  3. DMARC 回答: 「SPF または DKIM が失敗した場合はどうすればよいですか? レポートはどこに送信すればよいですか?」

誰かが送信者を騙る電子メールを送信した場合 you@example.com、受信 サーバーはこれらのレコードを順番にチェックします。 SPF と DKIM の両方が失敗し、DMARC が次のように言った場合 p=reject、メッセージは受信箱に届く前にドロップされます。 全部なしで 3 つ目は、攻撃者が悪用するギャップが存在することです。

SPF: あなたに代わって送信できる人

SPF (Sender Policy Framework) は、ドメインのルートにある DNS TXT レコードです。 それはすべてをリストします ドメインへの電子メールの送信を許可された IP アドレスとメール サーバー。 受信サーバーの場合 ~からメールを受け取る example.com、SPF レコードをチェックして、送信しているかどうかを確認します。 サーバーは承認リストに載っています。

単一の API 呼び出しでドメインの SPF レコードを確認します。

curl -s -X POST https://api.botoi.com/v1/dns-security/spf-check \\
  -H "Content-Type: application/json" \\
  -d '{"domain": "example.com"}'

応答:

{
  "success": true,
  "data": {
    "domain": "example.com",
    "has_spf": true,
    "record": "v=spf1 include:_spf.google.com ~all",
    "mechanisms": ["include:_spf.google.com", "~all"],
    "all_policy": "~all",
    "includes": ["_spf.google.com"],
    "valid": true
  }
}

確認する重要なフィールド:

  • has_spf: で始まる TXT レコードを作成します。 v=spf1 存在する? 偽の場合、 どのサーバーでもドメインからの電子メールを偽造することができます。
  • valid: レコードはエラーなしで解析されますか? SPF レコードは次の場合にサイレントに壊れます。 10 件の DNS ルックアップ制限を超えています。
  • all_policy: リストに記載されていない送信者に何が起こるかを定義する追跡メカニズム。 -all (ハード失敗) それらを拒否します。 ~all (ソフト失敗) 疑わしいものとしてマークされます。 +all 全員を許可すると、目的全体が無効になります。

10 ルックアップの制限

SPF レコードでは、最大 10 件の DNS ルックアップが可能です。 それぞれ include:a:mx:、 そして redirect: メカニズムは 1 回のルックアップとしてカウントされます。 入れ子になったインクルード も数えます。 Google Workspace、マーケティング ツール、トランザクション メール サービスを追加すると、 CRM を使用すると、すぐにこの制限に達します。

ルックアップが 10 件を超えると、SPF レコード全体が無効になります。 API の valid フィールドがこれをキャッチします。 ネストされたインクルードを IP 範囲にフラット化するか、統合することで問題を修正します。 プロバイダー。

DMARC: チェックが失敗した場合の対処方法

DMARC (ドメインベースのメッセージ認証、レポート、および適合性) は SPF と DKIM を結び付けます 一緒に。 それはに住んでいます _dmarc.example.com TXT レコードとして送信し、受信を伝えます 認証に失敗したメッセージをどうするか、および送信先の 2 つのことをサーバーに提供します。 それらの失敗について報告します。

DMARC レコードを確認します。

curl -s -X POST https://api.botoi.com/v1/dns-security/dmarc-check \\
  -H "Content-Type: application/json" \\
  -d '{"domain": "example.com"}'

応答:

{
  "success": true,
  "data": {
    "domain": "example.com",
    "has_dmarc": true,
    "record": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100",
    "policy": "reject",
    "subdomain_policy": null,
    "reporting": {
      "rua": ["mailto:dmarc@example.com"],
      "ruf": []
    },
    "pct": 100,
    "alignment": {
      "dkim": "r",
      "spf": "r"
    }
  }
}

DMARCポリシー

policy フィールドは、失敗したメッセージに何が起こるかを決定します。

  • none: 何もアクションを実行しません。 モニターのみ。 報告は届くが、依然としてなりすましメールが届く 受信箱に到達します。
  • quarantine: 失敗したメッセージをスパムに移動します。 受信者は引き続きそれらを見つけることができます 彼らが見れば。
  • reject: 失敗したメッセージを完全に削除します。 最強のお守りですが、 設定ミスは、正規の電子メールを失うことを意味します。

安全な DMARC ロールアウト戦略

まっすぐに行く p=reject 危険です。 次のパスに従ってください。

  1. から始める p=none; rua=mailto:dmarc@example.com 2~4週間のレポートを収集する
  2. レポートを確認します。 認証に失敗した正当な送信者を特定します。 SPF インクルードと DKIM キーを修正します。
  3. に移動します p=quarantine; pct=10 失敗したメッセージの 10% を隔離する
  4. 増加 pct 正規のメールが影響を受けないことが確認されると、今後数週間で 25、50、そして 100 に増加します。
  5. に切り替えます p=reject; pct=100 自分のセットアップに自信が持てるようになったら

pct API 応答のフィールドには、このロールアウトのどの位置にいるかが示されます。 ドメイン で pct=100policy=reject 完全な保護を持っています。

DKIM: すべての電子メールの暗号化署名

DKIM (DomainKeys Identified Mail) は、すべてのメールのヘッダーに暗号化署名を追加します。 送信メッセージ。 送信サーバーは秘密キーを使用してメッセージに署名します。 受信サーバー DNS で公開されている公開キーと照合して検証します。 メッセージが転送中に変更された場合 (ヘッダーが変更され、本文が変更され、コンテンツを書き換えるメーリング リストを通じて転送されます)、 署名は失敗します。

DKIM レコードのライブ [selector]._domainkey.example.com。 セレクターはラベルです メールプロバイダーが割り当てる次のようなもの google Google Workspace の場合、または selector1 Microsoft 365の場合。

DKIM レコードを確認します。

curl -s -X POST https://api.botoi.com/v1/dns-security/dkim-check \\
  -H "Content-Type: application/json" \\
  -d '{"domain": "example.com", "selector": "google"}'

応答:

{
  "success": true,
  "data": {
    "domain": "example.com",
    "selector": "google",
    "has_dkim": true,
    "record": "v=DKIM1; k=rsa; p=MIIBIjANBgkq...",
    "key_type": "rsa",
    "public_key_length": 2048
  }
}

主要なフィールド:

  • has_dkim: このセレクタの公開鍵は公開されていますか? false の場合、DKIM このセレクターを使用して署名されたすべてのメッセージの検証は失敗します。
  • public_key_length: NIST は最小 2048 ビットを推奨しています。 1024 未満のキー ビットは因数分解できるほど弱いです。
  • key_type:RSAが標準です。 Ed25519 の方が高速で、より短いキーを使用しますが、 メールプロバイダーのサポートは限られています。

DKIM と電子メール転送

これが、SPF が構成されている場合でも DKIM が重要である理由です。 誰かがあなたのメールを転送すると、 転送サーバーの IP が SPF レコードにないため、SPF は失敗します。 しかし、DKIM署名 (コンテンツが変更されない限り) 転送後も存続します。 いずれかの SPF があれば DMARC は合格します または DKIM が調整されるため、DKIM は転送されたメッセージのセーフティ ネットになります。

3 つの連携方法

脅威 SPF DKIM DMARC
不正なサーバーからのなりすましメール 検出します 検出 (有効な署名なし) ポリシーを適用します
メッセージ本文が転送中に改ざんされた 検出しない 検出します ポリシーを適用します
正当な送信者からの転送メール 失敗します (サーバー IP が異なる) パス(署名はそのまま) DKIM が一致していれば合格
サブドメインのスプーフィング (user@fake.example.com) 保護なし 保護なし ブロック経由 sp=reject
認証失敗の可視化 なし なし 集計レポートを送信します

単一の記録では完全な範囲をカバーすることはできません。 DMARC を使用しない SPF は、障害が適用されないことを意味します。 SPF なしの DKIM は、有効なキーを持っている人なら誰でもドメインから送信できることを意味します。 両方なしの DMARC SPF と DKIM には強制するものはありません。

30 秒でドメインを監査

このシェル スクリプトは 3 つのレコードすべてをチェックし、合否の概要を出力します。 それはボットイを使用します DNSセキュリティAPI。 1 分あたり最大 5 つのリクエストには API キーは必要ありません。

#!/bin/bash
# Audit SPF, DMARC, and DKIM for a domain in 30 seconds
DOMAIN=\${1:-"example.com"}
DKIM_SELECTOR=\${2:-"google"}
API="https://api.botoi.com/v1/dns-security"
PASS=0
FAIL=0

echo "Auditing email authentication for \$DOMAIN"
echo "==========================================="

# SPF check
SPF=\$(curl -s -X POST "\$API/spf-check" \\
  -H "Content-Type: application/json" \\
  -d "{\\"domain\\": \\"\$DOMAIN\\"}")

HAS_SPF=\$(echo "\$SPF" | jq -r '.data.has_spf')
SPF_VALID=\$(echo "\$SPF" | jq -r '.data.valid')
SPF_RECORD=\$(echo "\$SPF" | jq -r '.data.record // "not found"')
ALL_POLICY=\$(echo "\$SPF" | jq -r '.data.all_policy // "none"')

if [ "\$HAS_SPF" = "true" ] && [ "\$SPF_VALID" = "true" ]; then
  echo "[PASS] SPF: \$SPF_RECORD"
  PASS=\$((PASS + 1))
else
  echo "[FAIL] SPF: \$SPF_RECORD"
  FAIL=\$((FAIL + 1))
fi

if [ "\$ALL_POLICY" = "+all" ]; then
  echo "  WARNING: +all allows any server to send as your domain"
fi

# DMARC check
DMARC=\$(curl -s -X POST "\$API/dmarc-check" \\
  -H "Content-Type: application/json" \\
  -d "{\\"domain\\": \\"\$DOMAIN\\"}")

HAS_DMARC=\$(echo "\$DMARC" | jq -r '.data.has_dmarc')
POLICY=\$(echo "\$DMARC" | jq -r '.data.policy // "not set"')
PCT=\$(echo "\$DMARC" | jq -r '.data.pct // 0')

if [ "\$HAS_DMARC" = "true" ]; then
  echo "[PASS] DMARC: policy=\$POLICY pct=\$PCT%"
  PASS=\$((PASS + 1))
else
  echo "[FAIL] DMARC: no record found"
  FAIL=\$((FAIL + 1))
fi

if [ "\$POLICY" = "none" ]; then
  echo "  WARNING: policy=none only monitors, does not enforce"
fi

# DKIM check
DKIM=\$(curl -s -X POST "\$API/dkim-check" \\
  -H "Content-Type: application/json" \\
  -d "{\\"domain\\": \\"\$DOMAIN\\", \\"selector\\": \\"\$DKIM_SELECTOR\\"}")

HAS_DKIM=\$(echo "\$DKIM" | jq -r '.data.has_dkim')
KEY_TYPE=\$(echo "\$DKIM" | jq -r '.data.key_type // "unknown"')
KEY_LEN=\$(echo "\$DKIM" | jq -r '.data.public_key_length // 0')

if [ "\$HAS_DKIM" = "true" ]; then
  echo "[PASS] DKIM: selector=\$DKIM_SELECTOR key_type=\$KEY_TYPE key_length=\$KEY_LEN"
  PASS=\$((PASS + 1))
else
  echo "[FAIL] DKIM: no record for selector '\$DKIM_SELECTOR'"
  FAIL=\$((FAIL + 1))
fi

if [ "\$HAS_DKIM" = "true" ] && [ "\$KEY_LEN" -lt 2048 ] 2>/dev/null; then
  echo "  WARNING: DKIM key is \$KEY_LEN bits (2048 recommended)"
fi

# Summary
echo ""
echo "Results: \$PASS passed, \$FAIL failed"
[ "\$FAIL" -eq 0 ] && echo "All checks passed." || exit 1

実行してください:

bash audit.sh example.com google

最初の引数はドメインです。 2 番目は DKIM セレクターです。 スクリプトは3つのAPIを作成します (無料利用枠の制限内で) を呼び出し、各レコードをチェックし、弱い構成の警告にフラグを立てます。 いずれかのチェックが失敗した場合は、ゼロ以外のコードで終了します。 cron ジョブまたは CI パイプラインにドロップします。 継続的な監視のために。

JavaScript を使用したい場合は、非同期関数と同じ監査を次に示します。

async function auditEmailAuth(domain, dkimSelector = "google") {
  const api = "https://api.botoi.com/v1/dns-security";
  const headers = { "Content-Type": "application/json" };

  const [spf, dmarc, dkim] = await Promise.all([
    fetch(\`\${api}/spf-check\`, {
      method: "POST",
      headers,
      body: JSON.stringify({ domain }),
    }).then((r) => r.json()),

    fetch(\`\${api}/dmarc-check\`, {
      method: "POST",
      headers,
      body: JSON.stringify({ domain }),
    }).then((r) => r.json()),

    fetch(\`\${api}/dkim-check\`, {
      method: "POST",
      headers,
      body: JSON.stringify({ domain, selector: dkimSelector }),
    }).then((r) => r.json()),
  ]);

  return {
    domain,
    spf: {
      exists: spf.data.has_spf,
      valid: spf.data.valid,
      record: spf.data.record,
      allPolicy: spf.data.all_policy,
    },
    dmarc: {
      exists: dmarc.data.has_dmarc,
      policy: dmarc.data.policy,
      pct: dmarc.data.pct,
      reporting: dmarc.data.reporting?.rua || [],
    },
    dkim: {
      exists: dkim.data.has_dkim,
      selector: dkimSelector,
      keyType: dkim.data.key_type,
      keyLength: dkim.data.public_key_length,
    },
  };
}

// Usage
const report = await auditEmailAuth("example.com", "google");
console.log(JSON.stringify(report, null, 2));

一般的なプロバイダー構成

各電子メール プロバイダーには、独自の SPF インクルード ドメインと DKIM セレクターがあります。 ここに値があります 最も一般的なプロバイダーの場合:

プロバイダー SPFを含む DKIMセレクター
Google ワークスペース include:_spf.google.com google
マイクロソフト 365 include:spf.protection.outlook.com selector1selector2
アマゾンSES include:amazonses.com UUID ベース (SES コンソールを確認してください)
送信グリッド include:sendgrid.net s1s2
消印 include:spf.mtasv.net ドメインごと (消印の DNS 設定を確認してください)
メイルチンパンジー / マンドリル include:servers.mcsv.net k1

複数のプロバイダーを使用する場合、SPF レコードには、それらすべてが 1 つの TXT エントリに含まれます。 例えば: v=spf1 include:_spf.google.com include:sendgrid.net ~all。 見る プロバイダーを追加するときの 10 件のルックアップ制限。

重要なポイント

  • SPF どのサーバーがドメインに電子メールを送信できるかを制御します。 で確認してください の /v1/dns-security/spf-check 終点。 10 ルックアップ制限に注意してください。 避ける +all
  • DMARC SPF または DKIM が失敗した場合に何が起こるかを定義します。 から徐々に展開していきます p=nonep=reject を使用して pct 分野。 常に設定する ある rua レポートを受け取るアドレス。
  • DKIM 暗号署名を使用してメッセージの整合性を証明します。 2048 ビットを使用する キーが最小であることを確認し、セレクターが次のもので公開されていることを確認します。 /v1/dns-security/dkim-check
  • 3 つのレコードはすべて連動します。 SPF だけでは、転送された電子メールのなりすましを阻止できません。 DKIM単独 失敗時に何をすべきかを受信者に指示しません。 SPF と DKIM を使用しない DMARC には何も強制する必要がありません。
  • チェックを自動化します。 スケジュールに従って、または CI で監査スクリプトを実行して、DNS ドリフト、プロバイダーを捕捉します。 配信性に影響を与える前に、移行や誤ったレコードの削除を防止します。

FAQ

What is an SPF record and why do I need one?
SPF (Sender Policy Framework) レコードは、ドメインに代わって電子メールを送信することが許可されているすべてのサーバーをリストする DNS TXT エントリです。 これがなければ、インターネット上のどのサーバーでも、ドメインから送信されたように見える電子メールを送信でき、受信メール サーバーは違いを見分ける方法がありません。 ほとんどのドメインには、電子メール プロバイダーを含む SPF レコードが少なくとも 1 つ必要です。
自分のドメインに DMARC レコードがあるかどうかを確認するにはどうすればよいですか?
_dmarc.yourdomain.com で DNS TXT レコードをクエリします。 これは、dig、nslookup を使用するか、ドメイン名を使用して botoi DMARC check API に POST リクエストを送信することで実行できます。 API は、ポリシー、パーセンテージ、レポート アドレスを含む完全な解析されたレコードを返します。
Do I need DKIM if I already have SPF?
はい。 SPF と DKIM はさまざまな問題を解決します。 SPF は、送信サーバーが承認されていることを確認します。 DKIM は、メッセージの内容が転送中に変更されていないことを検証します。 電子メールを転送すると SPF の調整は失われますが、DKIM 署名は保持されます。 DMARC では、少なくとも 1 つが通過する必要があるため、両方が存在することで、転送または中継が発生した場合の回復力が得られます。
DMARC ポリシーをすぐに拒否するように設定するとどうなりますか?
受信サーバーは、SPF と DKIM の両方の調整に失敗したすべてのメッセージをドロップします。 レコードの設定が間違っていたり、サードパーティの送信者を忘れていたり、考慮していない転送ルールがある場合、正規の電子メールは警告なしに破棄されます。 レポートを収集するには p=none から始めて、10% の p=quarantine に移動し、すべての正当なメールが認証に合格したことを確認した後にのみ p=reject を設定します。
電子メール認証記録をどれくらいの頻度で監査する必要がありますか?
少なくとも、DNS の変更後、電子メール プロバイダーの移行後、または新しい送信サービス (マーケティング ツール、トランザクション電子メール、CRM) を追加するたびに確認してください。 毎週の自動チェックにより、SPF 10 のルックアップ制限の超過や DKIM キーの期限切れなどのサイレント破損が検出されます。 botoi DNS セキュリティ API エンドポイントを使用すると、CI または cron ジョブでこれを簡単に自動化できます。

botoiで開発を始めよう

150以上のAPIエンドポイント。検索、テキスト処理、画像生成、開発者ユーティリティに対応。無料プラン、クレジットカード不要。