الأدلة التقنية

شرح SPF وDKIM وDMARC للمبتدئين: كيف تثبت أن رسائلك منك فعلاً

لماذا يستطيع أي شخص أن يرسل باسم نطاقك، وكيف جاء كل من SPF وDKIM وDMARC ليسد ثغرة تركها الذي قبله، مع قراءة السجلات جزءاً جزءاً وطرق اختبار بريدك بالخدمات المجانية.

شرح SPF وDKIM وDMARC للمبتدئين: كيف تثبت أن رسائلك منك فعلاً

إذا سبق لك أن نشرت سجلات SPF وDKIM وDMARC لنطاقك لأن دليل التثبيت طلب ذلك، ثم نسختها كما هي دون أن تعرف لماذا يوجد ثلاثة سجلات وليس سجلاً واحداً، فأنت لست وحدك، فهذه السجلات تبدو للوهلة الأولى طلاسم مثل v=spf1 include:_spf.google.com ~all، ولكن كل واحد منها جاء ليجيب عن سؤال لم يستطع الذي قبله أن يجيب عنه، وعندما تعرف القصة من أولها تصبح قراءة السجل سهلة، وتعرف أين تبحث عندما تصل رسالتك إلى مجلد الرسائل المزعجة Spam أو ترفض.

وهذا المقال هو المرجع الذي تحيل إليه أدلة البريد على الموقع عندما تصل إلى هذه السجلات، فلا تكرر شرحها في كل دليل، وإذا كنت تبني بريد مؤسستك من البداية فالصورة الكاملة في دليل كيف تستضيف بريد مؤسستك بنفسك. وسوف نفترض أنك تعرف ما هو ال DNS وما هي سجلات TXT وMX وPTR، وإذا لم تكن كذلك فابدأ بمقال شرح DNS وسجلاته للمبتدئين ثم ارجع إلى هنا.

وسوف نناقش في هذا المقال ما يلي:

  • المشكلة الأصلية: لماذا يستطيع أي شخص أن يرسل رسالة باسم نطاقك، مع مثال حقيقي على سيرفر اختبار.
  • SPF: متى ظهر، وما الذي يفحصه، وكيف تقرأ السجل جزءاً جزءاً، وما الذي لا يحله.
  • DKIM: التوقيع الرقمي Digital Signature بلغة بسيطة، والمفتاح الخاص والمفتاح العام، وما الذي لا يحله أيضاً.
  • DMARC: الفكرة التي تربط الاثنين بالاسم الذي يراه القارئ، والسياسات الثلاث، وكيف تنتقل بينها على مراحل.
  • السجلات المساندة باختصار: PTR وMTA-STS وTLS-RPT وARC وBIMI، ولماذا أصبح كل هذا إلزامياً منذ 2024.
  • كيف تختبر بريدك بالخدمات المجانية وبالأمر dig، ثم الأخطاء الشائعة التي تكسر هذه السجلات.

لماذا يستطيع أي شخص أن يرسل باسمك؟

صمم بروتوكول نقل البريد البسيط Simple Mail Transfer Protocol، واختصاراً SMTP، في RFC 821 في أغسطس 1982، أي في زمن كانت فيه الشبكة مجموعة صغيرة من الجامعات والمراكز البحثية يعرف القائمون عليها بعضهم بعضاً، لذلك بني على الثقة الكاملة، فالسيرفر المرسل يقول «هذه رسالة من فلان» والسيرفر المستقبل يصدقه دون أي تحقق Validation، وهذا التصميم بقي كما هو في جوهره حتى المعيار الحالي RFC 5321، فالبروتوكول نفسه لا يحتوي على أي خطوة تسأل: هل يملك هذا السيرفر حق الإرسال باسم هذا النطاق؟

ولكي نفهم أين يكتب اسم المرسل أصلاً، تذكر الرسالة الورقية التي تصلك بالبريد العادي، ففيها عنوانان للمرسل: عنوان مكتوب على الظرف Envelope يستخدمه ساعي البريد ليعرف أين يعيد الرسالة إذا لم تصل، وتوقيع واسم داخل الرسالة نفسها يقرؤه المستلم، ولا أحد في مكتب البريد يفتح الظرف ليتأكد أن الاسم في الداخل يطابق الاسم على الظرف. والبريد الإلكتروني يعمل بالطريقة نفسها تماماً:

  • عنوان الظرف Envelope Sender: يرسله السيرفر في الأمر MAIL FROM أثناء محادثة SMTP، ويقرؤه السيرفر المستقبل فقط، ثم يحفظه في رأس الرسالة باسم Return-Path، وإليه تعاد رسائل الفشل Bounces. ويسمى أيضاً RFC5321.MailFrom نسبة إلى المعيار الذي عرفه.
  • عنوان الرسالة Header From: السطر From: داخل رؤوس الرسالة Headers، وهو الاسم الذي يعرضه برنامج البريد للقارئ، ويسمى RFC5322.From نسبة إلى معيار RFC 5322 الذي يعرف شكل الرسالة.

الصورة التالية تبين هذين العنوانين في رسالة واحدة منتحلة، فالظرف يحمل عنوان المهاجم الحقيقي، والرسالة في داخله تحمل اسم المدير التنفيذي لشركة أخرى، والقارئ لا يرى إلا ما في الداخل:

مخطط يبين سيرفر المهاجم يرسل رسالة عبر SMTP على المنفذ 25، على ظرفها العنوان MAIL FROM: bounce@attacker.example وفي داخلها السطر From: CEO ceo@example.com، والقارئ يرى في برنامج البريد اسم CEO فقط، مع ملاحظة أن SMTP لا يتحقق من أي من العنوانين
الظرف MAIL FROM يقرؤه السيرفر، والسطر From يقرؤه الإنسان، وSMTP لا يتحقق من أي منهما

ولكي ترى ذلك بعينك وليس على الورق فقط، سوف نرسل رسالة كهذه إلى سيرفر اختبار على جهازك وليس إلى سيرفر أحد، فنشغل Mailpit، وهو سيرفر SMTP للاختبار يستقبل كل الرسائل ويعرضها، في Container على شبكة Docker خاصة، ثم نرسل إليه من Container آخر بأداة swaks التي تكتب محادثة SMTP كاملة أمامك:

docker network create mail-lab
docker run -d --name mailpit --hostname mail.example.net --network mail-lab --network-alias mail.example.net axllent/mailpit:v1.27
docker run --rm -it --hostname mx.attacker.example --network mail-lab ubuntu:24.04 bash

وداخل ال Container الثاني نثبت swaks ونرسل رسالة ظرفها من attacker.example واسمها الظاهر من example.com:

apt-get update && apt-get install -y swaks curl
swaks --server mail.example.net --port 1025 --helo mx.attacker.example \
  --from [email protected] --to [email protected] \
  --h-From "CEO <[email protected]>" --h-Subject "Urgent wire transfer" \
  --body "Please pay the attached invoice today."

والمخرج سوف يكون كما يلي:

=== Trying mail.example.net:1025...
=== Connected to mail.example.net.
<-  220 mail.example.net Mailpit ESMTP Service ready
 -> EHLO mx.attacker.example
<-  250-mail.example.net greets mx.attacker.example
<-  250-SIZE 0
<-  250-ENHANCEDSTATUSCODES
<-  250 SMTPUTF8
 -> MAIL FROM:<[email protected]>
<-  250 2.1.0 Ok
 -> RCPT TO:<[email protected]>
<-  250 2.1.5 Ok
 -> DATA
<-  354 Start mail input; end with <CR><LF>.<CR><LF>
 -> Date: Mon, 05 Oct 2026 05:23:09 +0000
 -> To: [email protected]
 -> From: CEO <[email protected]>
 -> Subject: Urgent wire transfer
 -> Message-Id: <[email protected]>
 -> X-Mailer: swaks v20240103.0 jetmore.org/john/code/swaks/
 ->
 -> Please pay the attached invoice today.
 ->
 ->
 -> .
<-  250 2.0.0 Ok: queued as 2Kk6vpcbNs2VBchxH83Khi
 -> QUIT
<-  221 2.0.0 mail.example.net Mailpit ESMTP Service closing transmission channel
=== Connection closed with remote host.

وعندما نطلب الرسالة كما حفظها السيرفر من واجهة Mailpit البرمجية API:

curl -s http://mail.example.net:8025/api/v1/message/latest/raw | grep -E "^(Return-Path|From|To|Subject):"
Return-Path: <[email protected]>
To: [email protected]
From: CEO <[email protected]>
Subject: Urgent wire transfer

في المخرج أعلاه لاحظ التالي:

  • السطر MAIL FROM:<[email protected]> هو الظرف، وقد حفظه السيرفر في Return-Path، والسطر From: CEO <[email protected]> هو ما يراه القارئ، والنطاقان مختلفان تماماً.
  • السيرفر رد بالقيمة 250 Ok على كل أمر ولم يسأل عن أي شيء، فلا توجد في SMTP خطوة تتحقق من أن المرسل يملك example.com، والسبب كما ذكرنا أن البروتوكول صمم قبل أن يكون هذا سؤالاً مهماً.
  • كل ما سوف نشرحه في هذا المقال هو طبقات أضيفت لاحقاً فوق SMTP دون تغييره، وكل طبقة تنشرها أنت في DNS نطاقك ويقرؤها السيرفر المستقبل، فإذا لم تنشرها فلا يوجد ما يمنع هذه الرسالة من الوصول.

وعندما تنتهي احذف بيئة الاختبار بالأمرين docker rm -f mailpit وdocker network rm mail-lab.

وقد يتساءل البعض: هل هذه مشكلة حقيقية أم مثال نظري؟ والإجابة أن أشهر استغلال لها هو احتيال البريد الإلكتروني للشركات Business Email Compromise، واختصاراً BEC، حيث تصل إلى موظف المالية رسالة باسم المدير أو المورد تطلب تحويلاً عاجلاً، وقد سجل التقرير السنوي لمركز شكاوى جرائم الإنترنت IC3 التابع لمكتب التحقيقات الفيدرالي FBI لعام 2024 وحده 21,442 شكوى من هذا النوع بخسائر بلغت 2.77 مليار دولار. ويجدر الإشارة هنا إلى أن هذه الشكاوى لا تأتي كلها من انتحال النطاق، فبعضها يرسل من حساب حقيقي سرقت كلمة مروره، وبعضها من نطاق يشبه نطاقك بحرف واحد، وسوف نرى أن SPF وDKIM وDMARC تغلق الباب الأول فقط، أي استخدام نطاقك أنت كما هو، ولا تغلق البابين الآخرين.

SPF: قائمة السيرفرات المسموح لها بالإرسال

أول فكرة خطرت للمهتمين بالمشكلة كانت بسيطة: إذا كان السيرفر المستقبل لا يعرف هل يحق لهذا العنوان أن يرسل باسم example.com، فلماذا لا ينشر صاحب النطاق نفسه قائمة بعناوين IP المسموح لها في DNS نطاقه؟ ومن هذه الفكرة ولد إطار سياسة المرسل Sender Policy Framework، واختصاراً SPF، الذي بدأ تطويره في صيف 2003 ونشر أول مرة خارج مطوريه في ديسمبر 2003، ثم صدر في أبريل 2006 كمعيار تجريبي Experimental في RFC 4408، وأخيراً أصبح معياراً رسمياً Standards Track في RFC 7208 في أبريل 2014، وهو المعيار المعتمد اليوم.

ما الذي يفحصه SPF بالضبط؟

عندما يتصل سيرفر بسيرفرك ويرسل MAIL FROM:<[email protected]>، يأخذ سيرفرك النطاق من عنوان الظرف، أي example.com، ويطلب سجل TXT الذي يبدأ بـ v=spf1 لهذا النطاق، ثم يقارن عنوان IP الذي اتصل به فعلاً بالقائمة الموجودة في السجل، فإذا وجده فالنتيجة pass، وإذا لم يجده فالنتيجة بحسب ما كتبه صاحب النطاق في آخر السجل. ولاحظ هنا أمرين مهمين: الأول أن SPF يفحص عنوان الظرف وليس السطر From الذي يراه القارئ، والثاني أن عنوان IP لا يمكن تزويره في اتصال TCP كامل، لأن السيرفر المستقبل يرد على هذا العنوان نفسه، وهذا ما يجعل SPF مفيداً.

الصورة التالية تبين سيرفرين يرسلان بعنوان الظرف نفسه [email protected]، أحدهما السيرفر الحقيقي والآخر منتحل، والسيرفر المستقبل يسأل DNS سؤالاً واحداً قبل أن يقرر:

مخطط يبين سيرفر example.com بالعنوان 203.0.113.10 وسيرفر مهاجم بالعنوان 198.51.100.7 يرسلان MAIL FROM: news@example.com إلى السيرفر المستقبل، والسيرفر المستقبل يسأل DNS عن سجل SPF للنطاق فيجد v=spf1 ip4:203.0.113.10 -all، فتكون نتيجة الأول SPF pass ونتيجة الثاني SPF fail
SPF يقارن عنوان IP المتصل بالقائمة التي نشرها صاحب النطاق في DNS

كيف تقرأ سجل SPF جزءاً جزءاً؟

لنأخذ مثالاً حقيقياً هو سجل google.com نفسه، فالأمر التالي يطلب سجلات TXT للنطاق، وسوف تجد بينها سجلات أخرى للتحقق من ملكية النطاق لخدمات مختلفة، لذلك نبحث عن السطر الذي يبدأ بـ v=spf1:

dig TXT google.com +short | grep spf1
"v=spf1 include:_spf.google.com ~all"

السجل يقول: «اسأل السجل الموجود في _spf.google.com عن القائمة، ومن لم يكن فيها فاعتبره مشكوكاً فيه»، ولنتبع ال include:

dig TXT _spf.google.com +short
"v=spf1 ip4:74.125.0.0/16 ip4:209.85.128.0/17 ip6:2001:4860:4864::/56 ip6:2404:6800:4864::/56 ip6:2607:f8b0:4864::/56 ip6:2800:3f0:4864::/56 ip6:2a00:1450:4864::/56 ip6:2c0f:fb50:4864::/56 ~all"

والجدول التالي يشرح كل جزء قد تقابله في سجل SPF، والأجزاء التي تحتاج إلى استعلام DNS عند الفحص مذكورة لأنها تهمنا في حد الاستعلامات العشرة الذي سوف نشرحه بعد قليل:

الجزءمعناهيحتاج استعلام DNS؟
v=spf1الإصدار، ويجب أن يكون أول السجل، وبه يعرف السيرفر أن هذا السجل هو سجل SPF من بين سجلات TXT الكثيرةلا
ip4:203.0.113.10 وip6:…عنوان أو نطاق عناوين Range بصيغة CIDR مثل /24 مسموح له بالإرسال، وهي أوضح طريقة وأسرعهالا
aالعناوين التي يشير إليها سجل A أو AAAA للنطاق نفسه، أو لاسم آخر إذا كتبت a:mail.example.comنعم
mxعناوين السيرفرات المذكورة في سجلات MX للنطاق، أي أن سيرفرات استقبال البريد مسموح لها بالإرسال أيضاًنعم
include:_spf.google.comاسأل سجل SPF لنطاق آخر، فإذا كانت نتيجته pass فهي pass هنا، وهكذا تسمح لمزود خارجي مثل Google Workspace أو Amazon SES بالإرسال باسمكنعم، وما بداخله يحسب أيضاً
redirect=_spf.google.comاستخدم سجل نطاق آخر بدلاً من هذا السجل كله، وتجده في سجل gmail.com مثلاًنعم
ptr وexistsآليات قديمة نادرة، وptr بالذات ينص المعيار على عدم استخدامها لأنها بطيئة وغير موثوقةنعم
-allأي عنوان غير مذكور يفشل فشلاً صريحاً Failلا
~allأي عنوان غير مذكور يفشل فشلاً لطيفاً SoftFail، أي «مشكوك فيه ولكن لا ترفضه بسبب هذا وحده»لا
?all و+allمحايد Neutral، أو «الكل مسموح له»، وكلاهما يلغي فائدة السجل، و+all بالذات أسوأ قيمة على الإطلاق لأنه يقول للعالم إن أي سيرفر يحق له الإرسال باسمكلا

والآليات تقرأ من اليسار إلى اليمين، وأول آلية تطابق العنوان تحدد النتيجة، لذلك يأتي all دائماً في النهاية كقاعدة لكل من لم يطابق ما قبله.

وقد يتساءل البعض: أيهما أفضل، -all أم ~all؟ والمنطق الأول يقول إن -all أشد وبالتالي أكثر أماناً، ولكن معيار DMARC الجديد RFC 9989 في القسم 7.1 ينبه إلى أن بعض السيرفرات ترفض الرسالة مباشرة عند -all أثناء محادثة SMTP، أي قبل أن تصل إلى فحص DKIM وDMARC، فتضيع رسائل مشروعة كان توقيع DKIM سوف ينقذها، كالرسائل التي مرت بخدمة تحويل Forwarding، ولا تظهر في تقارير DMARC أصلاً. لذلك عندما يكون لديك DKIM وDMARC مضبوطان فالقيمة ~all هي الخيار الأنسب، وهي ما يستخدمه google.com نفسه كما رأيت، ودع DMARC يقرر مصير الرسالة.

حد الاستعلامات العشرة

كل include وa وmx وptr وexists وredirect يجعل السيرفر المستقبل يطلب استعلام DNS إضافياً، ولو ترك هذا دون حد لاستطاع أي شخص أن ينشر سجلاً يجعل كل سيرفر بريد في العالم يرسل آلاف الاستعلامات، لذلك يحدد المعيار في القسم 4.6.4 عشرة استعلامات فقط لكل فحص، وما بداخل كل include يحسب معها، فإذا تجاوزتها فالنتيجة permerror، أي أن سجلك معطل بالكامل وكأنك لم تنشره، وليس أن الاستعلام الحادي عشر يهمل فقط.

وهذا الحد يصل إليه الكثيرون دون أن ينتبهوا، والسبب أن كل خدمة خارجية ترسل باسمك تطلب منك إضافة include خاص بها، ولنأخذ سجل github.com مثالاً حقيقياً على مؤسسة ترسل عبر عدة خدمات:

dig TXT github.com +short | grep spf1
"v=spf1 ip4:192.30.252.0/22 include:spf.protection.outlook.com include:_netblocks.google.com include:_netblocks2.google.com include:mail.zendesk.com include:_spf.salesforce.com include:servers.mcsv.net include:mktomail.com include:sendgrid.net ip4:62.253.2" "27.114 ip4:166.78.69.169 ip4:166.78.69.170 ip4:166.78.71.131 ~all"

في المخرج أعلاه لاحظ التالي:

  • ثمانية include في المستوى الأول وحده: Microsoft 365 وGoogle وZendesk للتذاكر وSalesforce وMailchimp وMarketo للتسويق وSendGrid، وكل واحد منها قد يحتوي على include آخر بداخله يحسب من العشرة، لذلك لا تعتمد على عد ما تراه في السطر الأول، واستخدم أداة تعد الاستعلامات كاملة كما سيأتي في قسم الاختبار.
  • السجل مقسم إلى نصين بين علامتي تنصيص "…" "…"، والسبب أن النص الواحد في سجل TXT لا يتجاوز 255 حرفاً، والسيرفر المستقبل يجمع النصين قبل القراءة، فالكسر في منتصف العنوان 62.253.2" "27.114 صحيح تماماً وليس خطأ.

ما الذي لا يحله SPF؟

هنا نصل إلى الفجوة التي جعلت SPF وحده غير كاف، وهي فجوتان:

  1. SPF لا ينظر إلى السطر From الذي يراه القارئ: ارجع إلى رسالة المهاجم في أول المقال، فلو نشر المهاجم سجل SPF صحيحاً لنطاقه attacker.example لنجح فحص SPF لرسالته بنتيجة pass، لأن الظرف من نطاقه هو وسيرفره مذكور فيه، بينما السطر From ما زال يقول [email protected]، فالفحص نجح والانتحال مر.
  2. التحويل Forwarding يكسره: إذا أرسلت رسالة إلى عنوان في جامعة يحولها تلقائياً إلى Gmail، فإن Gmail يرى الرسالة قادمة من عنوان IP سيرفر الجامعة وليس من سيرفرك، وسيرفر الجامعة غير موجود في سجلك، فيفشل SPF مع أن الرسالة حقيقية، وهذا المثال بالضبط يشرحه RFC 9989 في القسم 7.4.

لذلك كان المطلوب شيئاً يثبت أن الرسالة نفسها جاءت من صاحب النطاق ولم تتغير، بغض النظر عن السيرفر الذي سلمها في آخر خطوة، وهذا ما جاء به DKIM.

DKIM: توقيع يثبت مصدر الرسالة وأنها لم تتغير

في الفترة نفسها التي ظهر فيها SPF كانت Yahoo تعمل على مواصفة اسمها DomainKeys، وكانت Cisco تعمل على مواصفة أخرى اسمها Identified Internet Mail، وكلاهما يعتمد على التوقيع الرقمي، فاجتمعت الشركتان مع شركات أخرى خلال 2005 منها AOL وMicrosoft وIBM وPGP Corporation وSendmail ودمجتا المواصفتين في واحدة سميت DomainKeys Identified Mail، واختصاراً DKIM، وقدمتاها إلى IETF، فصدرت في مايو 2007 كمعيار في RFC 4871، ونشرت DomainKeys الأصلية في اليوم نفسه في RFC 4870 كوثيقة تاريخية Historic، ثم حل محلهما RFC 6376 في سبتمبر 2011 وهو المعيار المعتمد اليوم، مع تحديث مهم في RFC 8301 في يناير 2018 سوف نعود إليه عند الحديث عن طول المفتاح.

التوقيع الرقمي بلغة بسيطة

لكي نفهم لماذا جاء DKIM بهذا الشكل، لنفكر كيف يمكن لسيرفر أن يثبت للسيرفر المستقبل أن الرسالة منه فعلاً، ولنبدأ بالحل الساذج:

  • كلمة سر في رأس الرسالة: يضع سيرفرك كلمة سر متفقاً عليها في رأس كل رسالة، والمستقبل يقارنها، ولكن كيف تتفق على كلمة سر مع كل سيرفرات العالم؟ وأي شخص يستلم رسالة واحدة منك سوف يرى كلمة السر وينسخها في رسائله، وهذا الحل غير مناسب إطلاقاً.
  • هاش الرسالة Hash: يحسب سيرفرك بصمة الرسالة بدالة الهاش Hash Function، وهي دالة تعطي ناتجاً قصيراً ثابت الطول يتغير بالكامل إذا تغير حرف واحد من الرسالة، فيضعها في رأس الرسالة والمستقبل يعيد حسابها ويقارن، وهذا يكشف تعديل الرسالة بالخطأ، ولكن المهاجم يستطيع أن يكتب رسالته ويحسب هاشها بنفسه، فالهاش وحده لا يثبت من كتب الرسالة.
  • الهاش مع التوقيع بمفتاح خاص: وهذا هو الحل الصحيح، فلدى سيرفرك زوج من المفاتيح Key Pair مرتبطان رياضياً: مفتاح خاص Private Key سري لا يغادر السيرفر أبداً، ومفتاح عام Public Key تنشره لكل العالم في DNS. يحسب السيرفر الهاش ثم يوقعه بالمفتاح الخاص، والناتج هو التوقيع Signature، ولا يستطيع أحد أن ينتج توقيعاً صحيحاً دون المفتاح الخاص، بينما يستطيع أي شخص أن يتحقق من التوقيع بالمفتاح العام.

والتشبيه الأقرب هو الختم الرسمي على الورقة، فالختم نفسه في درج المدير لا يخرج من المكتب، وصورة الختم معروفة ومنشورة، فأي شخص يستطيع أن يقارن الختم على الورقة بالصورة المنشورة، ولكن لا أحد يستطيع أن يختم ورقة جديدة دون الختم نفسه، والفرق أن التوقيع الرقمي مرتبط بمحتوى الورقة، فإذا غيرت كلمة واحدة بعد الختم لم يعد التوقيع صحيحاً.

الصورة التالية تبين دورة DKIM كاملة: سيرفرك يوقع بالمفتاح الخاص، والمفتاح العام منشور مرة واحدة في DNS، والسيرفر المستقبل يجلبه مع كل رسالة ويتحقق:

مخطط يبين سيرفر المرسل example.com ومعه المفتاح الخاص يوقع هاش الرؤوس والمحتوى ويضيف الترويسة DKIM-Signature مع d=example.com وs=mail، والمفتاح العام منشور في DNS في السجل mail._domainkey.example.com، والسيرفر المستقبل يجلب المفتاح العام ويعيد حساب الهاش ويقارن، فإذا تطابق فالنتيجة pass وإذا تغيرت الرسالة فالنتيجة fail
المفتاح الخاص يبقى في سيرفرك، والمفتاح العام منشور في DNS لكل من يريد التحقق

الترويسة DKIM-Signature: ماذا تعني d= وs=؟

عندما يوقع سيرفرك الرسالة يضيف إليها ترويسة Header جديدة اسمها DKIM-Signature، وشكلها كما يلي، والقيم الطويلة مختصرة هنا:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=mail;
        h=from:to:subject:date:message-id;
        bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
        b=Kx3vT1aBq8…

في الترويسة أعلاه لاحظ التالي:

  • d=example.com هو النطاق الموقع Signing Domain، أي النطاق الذي يتحمل مسؤولية الرسالة، وهو أهم قيمة في الترويسة كما سوف نرى في DMARC.
  • s=mail هو المحدد Selector، أي اسم المفتاح، والسبب في وجوده أن النطاق الواحد قد يملك عدة مفاتيح في الوقت نفسه: مفتاح لسيرفرك ومفتاح لخدمة النشرات ومفتاح جديد أثناء تدوير المفاتيح Key Rotation، فيعرف المستقبل من s= أي مفتاح يطلب.
  • h= قائمة الرؤوس التي دخلت في التوقيع، وbh= هاش محتوى الرسالة Body Hash، وb= التوقيع نفسه.
  • a=rsa-sha256 خوارزمية التوقيع، وc=relaxed/relaxed طريقة توحيد Canonicalization المسافات وحالة الأحرف قبل الحساب، حتى لا يفشل التوقيع لأن سيرفراً في الطريق أضاف مسافة.

ومن s= وd= يبني السيرفر المستقبل اسم السجل الذي يطلب منه المفتاح العام بالشكل selector._domainkey.domain، أي mail._domainkey.example.com في مثالنا. ولنر مفتاحاً حقيقياً، فرسائل Gmail توقع بالمحدد 20251104 وقت كتابة المقال:

dig TXT 20251104._domainkey.gmail.com +short
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtOzIjTYVUYZDbm03lsL4MGxSUVJWALTSueNRnCvCdM5d0i26EVUH7jprqIFdBSnMXQDHCkwcH1bFjtbfHCzFfWlpzOWducPPU0E+ut0rRqIy4NKY8CJlW39Q+AHJ70h+k2VadmQt0A1Yijg/Dk73NuJAz8KDNgz2x14nDVkINRlynAU7EosarRRhVGKqlNrYd" "p/os6QYaetfYNdQRJDecOARNObGRET/sW0m5Ya5SBGsaw8VSGluCwSZh+zShTXaOyA1WnpHNtAoCQClFPn9vmm6Cb0Z2gYF0g/+qZ1FCnaj1+aaJGzhqVOXGtHGWM3dLpwC7Rul6STfFD521JeqpQIDAQAB"

في المخرج أعلاه لاحظ أن k=rsa نوع المفتاح، وp= المفتاح العام نفسه بترميز Base64، وأن المفتاح مقسم إلى نصين لأنه أطول من 255 حرفاً كما رأينا في سجل SPF لـ github، وهذا طبيعي في كل مفتاح RSA بطول 2048 بت. ولاحظ أيضاً أن المحدد يتغير مع الوقت، فالمحدد السابق 20230601 ما زال منشوراً ولكن بالقيمة p= فارغة، وهي الطريقة الرسمية لإلغاء Revoke مفتاح قديم.

وإذا كنت تبني الخادم بيدك فقد شرحنا إنشاء المفتاح بـ opendkim-genkey ونشره واختباره في دليل Postfix وDovecot، أما mailcow وStalwart فينشئان المفتاح ويعرضان لك السجل جاهزاً للنسخ.

ما الذي يحله DKIM، وما الذي لا يحله؟

DKIM أغلق الفجوتين اللتين تركهما SPF جزئياً، فالتوقيع مرتبط بالرسالة وليس بالسيرفر، لذلك يبقى صحيحاً عندما تمر الرسالة بخدمة تحويل لا تعدل محتواها، وأي تعديل على الرؤوس الموقعة أو المحتوى يكسر التوقيع فيكشف التلاعب Tampering، ويحصل النطاق الموقع على سمعة Reputation خاصة به عند Gmail وOutlook بغض النظر عن عنوان IP الذي أرسل منه.

ولكن ارجع مرة أخرى إلى رسالة المهاجم، فما الذي يمنعه من توقيع رسالته بمفتاح نطاقه هو؟ لا شيء، فسوف يضيف DKIM-Signature فيها d=attacker.example، وينشر مفتاحه في DNS نطاقه، فينجح فحص DKIM بنتيجة pass، والسطر From ما زال [email protected]. أي أن DKIM يجيب عن سؤال «من وقع هذه الرسالة؟» ولا يجيب عن سؤال «هل الموقع هو صاحب الاسم الذي يراه القارئ؟»، وهذا هو بالضبط السؤال الذي جاء DMARC ليجيب عنه.

DMARC: ربط الفحصين بالاسم الذي يراه القارئ

بحلول 2010 كان لدى المؤسسات الكبرى SPF وDKIM، ومع ذلك استمر انتحال نطاقاتها، والسبب الفجوة التي رأيناها: كلا الفحصين قد ينجح لنطاق آخر غير النطاق الظاهر للقارئ، ولم يكن لدى صاحب النطاق طريقة ليقول للمستقبلين «إذا لم تنجح رسالة باسمي في الفحص فارفضها»، ولا طريقة ليعرف من يرسل باسمه أصلاً. لذلك اجتمعت في ربيع 2011 مجموعة من المؤسسات من جهة المستقبلين AOL وComcast وGmail وHotmail وNetease وYahoo، ومن جهة المرسلين Bank of America وFacebook وLinkedIn وPayPal وغيرها، ونشرت مواصفة Domain-based Message Authentication, Reporting and Conformance، واختصاراً DMARC، في 30 يناير 2012.

ثم نشرت المواصفة في مارس 2015 في RFC 7489، ولكن كوثيقة معلوماتية Informational عبر مسار التقديم المستقل وليس كمعيار من IETF، وبعد سنوات من العمل صدر في مايو 2026 المعيار الرسمي RFC 9989 على مسار المعايير Standards Track، ومعه RFC 9990 للتقارير المجمعة وRFC 9991 لتقارير الفشل، وثلاثتها تلغي RFC 7489. وصيغة السجل v=DMARC1 لم تتغير، فسجلك القديم ما زال يعمل، ولكن بعض الوسوم Tags تغيرت: حذف pct الذي كان يطبق السياسة على نسبة من الرسائل، وحل محله الوسم t=y للاختبار، وأضيف np لسياسة النطاقات الفرعية غير الموجودة.

الفكرة الأساسية: التطابق Alignment

DMARC لا يضيف فحصاً ثالثاً، وإنما يضيف شرطاً واحداً على الفحصين الموجودين: أن ينجح أحدهما على الأقل باسم النطاق نفسه الذي يظهر في السطر From، وهذا ما يسمى التطابق Alignment. أي أن DMARC يسأل:

  • هل نجح SPF، وهل النطاق في عنوان الظرف هو نفسه النطاق في From؟
  • هل نجح DKIM، وهل النطاق في d= هو نفسه النطاق في From؟

وإذا كانت إجابة أحد السؤالين «نعم» فالنتيجة dmarc=pass، وإلا فالنتيجة fail ويطبق المستقبل السياسة التي نشرها صاحب النطاق. الصورة التالية تبين رسالة نجح فيها SPF لنطاق خدمة الإرسال وليس لنطاقك، فلم يتطابق، بينما نجح DKIM بتوقيع نطاقك فتطابق، وهذا يكفي:

مخطط قرار DMARC لرسالة From: example.com، فحص SPF نجح للنطاق bounces.mailer.example فلم يتطابق مع From، وفحص DKIM نجح بالتوقيع d=example.com فتطابق، فالنتيجة DMARC pass، وفي الأسفل ما يحدث إذا لم يتطابق أي منهما: p=none تسليم الرسالة، وp=quarantine مجلد الرسائل المزعجة، وp=reject رفضها
يكفي فحص واحد ناجح ومتطابق مع From، وإلا طبق المستقبل سياسة النطاق

والآن ارجع إلى رسالة المهاجم للمرة الأخيرة، فقد ينجح SPF لنطاقه وقد ينجح DKIM لنطاقه، ولكن لا أحد منهما يطابق example.com الظاهر في From، فتفشل في DMARC، وإذا كانت سياسة example.com هي الرفض فلن تصل الرسالة إلى صندوق أحد. وبهذا الشكل نكون قد أغلقنا باب انتحال النطاق نفسه، أما النطاق المشابه مثل examp1e.com فهو نطاق آخر يملكه المهاجم ويستطيع أن ينشر له سجلات صحيحة، لذلك يبقى وعي المستخدم وفلاتر المحتوى خط الدفاع هناك.

ويوجد نوعان من التطابق: المرن Relaxed وهو الافتراضي، ويكفي فيه أن يشترك النطاقان في النطاق الرئيسي Organizational Domain، فالتوقيع بالنطاق mail.example.com يتطابق مع From: [email protected]، والصارم Strict ويشترط أن يكون النطاقان متطابقين حرفاً بحرف، وتختاره بالوسمين adkim=s وaspf=s، ويذكر المعيار أن معظم أصحاب النطاقات وجدوا التطابق المرن كافياً.

💡
هذا التطابق هو سبب المشكلة الأشهر مع خدمات الإرسال الخارجية: الخدمة تستخدم نطاقها هي في عنوان الظرف، فينجح SPF دون تطابق، ولذلك تطلب منك الخدمات الجادة أن توقع رسائلك بـ DKIM باسم نطاقك، أو أن تجعل عنوان الظرف نطاقاً فرعياً من نطاقك، كما شرحنا في قسم نطاق MAIL FROM الخاص بك في دليل Amazon SES.

قراءة سجل DMARC

سجل DMARC هو سجل TXT تنشره في الاسم _dmarc قبل نطاقك، ولنر سجلي google.com وgmail.com:

dig TXT _dmarc.google.com +short
dig TXT _dmarc.gmail.com +short
"v=DMARC1; p=reject; rua=mailto:[email protected]"
"v=DMARC1; p=none; sp=quarantine; rua=mailto:[email protected]"

في المخرج أعلاه لاحظ التالي:

  • v=DMARC1 الإصدار، ويجب أن يكون أول السجل.
  • p= السياسة Policy عند الفشل: none أي سلم الرسالة كأن شيئاً لم يكن ولكن أرسل لي التقارير، وquarantine أي ضعها في مجلد الرسائل المزعجة، وreject أي ارفضها أثناء محادثة SMTP.
  • sp= السياسة للنطاقات الفرعية Subdomains، وإذا لم تكتبه فتطبق قيمة p عليها.
  • rua= العنوان الذي تصل إليه التقارير المجمعة Aggregate Reports، وهي ملفات XML يومية غالباً يرسلها كل مستقبل كبير، فيها كل عنوان IP أرسل باسم نطاقك وعدد رسائله ونتيجة SPF وDKIM لكل منها، وهي أهم ما في DMARC كما سيأتي.
  • الأمر الملفت أن google.com يرفض كل رسالة تفشل، بينما gmail.com يكتفي بالقيمة none، وهذا يتفق مع ما ينص عليه RFC 9989 في القسم 7.4: النطاق الذي يستخدمه عامة الناس ويشاركون منه في القوائم البريدية Mailing Lists لا ينبغي أن ينشر p=reject، لأن القوائم البريدية تعدل الرسائل وتعيد إرسالها فتفشل في DMARC وترفض رسائل حقيقية، بينما نطاق مؤسسة يرسل منه موظفوها وأنظمتها فقط يستطيع أن يرفض.

من none إلى reject على مراحل

قد يبدو الأسلم أن تبدأ مباشرة بالقيمة p=reject، ولكن في أي مؤسسة حقيقية أنظمة كثيرة ترسل باسم النطاق دون أن يتذكرها أحد، مثل نظام التذاكر والرواتب والنشرات البريدية والطابعة التي ترسل المسح الضوئي، فإذا بدأت بالرفض اختفت رسائلها بصمت. لذلك ينص المعيار الجديد على ترتيب واضح: p=none مع التقارير شهراً على الأقل، ثم p=quarantine مدة مماثلة، ثم p=reject إذا قررت ذلك بعد مقارنة النتائج، والخطوات العملية كما يلي:

  1. انشر v=DMARC1; p=none; rua=mailto:[email protected] وأنشئ هذا الصندوق فعلاً.
  2. اقرأ التقارير، فكل مصدر مشروع يرسل باسمك ويفشل أضفه إلى SPF أو فعل له توقيع DKIM باسم نطاقك، وكل مصدر لا تعرفه هو غالباً محاولة انتحال كانت تمر حتى الآن دون أن تعلم.
  3. عندما تنجح كل رسائلك المشروعة انتقل إلى p=quarantine، ويمكنك أن تبدأ بها مع t=y فيطبق المستقبلون سياسة أخف بدرجة أثناء الاختبار.
  4. بعد فترة أخرى من التقارير النظيفة انتقل إلى p=reject، وأبق rua دائماً، فالتقارير تكشف لك النظام الجديد الذي أضافه أحدهم دون أن يخبرك.
📌
في 16 أكتوبر 2017 أصدرت وزارة الأمن الداخلي الأمريكية التوجيه الملزم BOD 18-01 لكل الجهات الحكومية الفيدرالية، وفيه هذا الترتيب نفسه: خلال 90 يوماً سجلات SPF وDMARC صحيحة لكل نطاق بالقيمة p=none على الأقل مع عنوان يستقبل التقارير، ثم خلال سنة واحدة من صدور التوجيه سياسة p=reject لكل النطاقات الرئيسية والسيرفرات التي ترسل البريد. أي أن جهة بحجم الحكومة الفيدرالية أعطت نفسها سنة كاملة من التقارير قبل الرفض، والسبب نفسه الذي ذكرناه: لا أحد يعرف كل ما يرسل باسم نطاقه حتى يقرأ التقارير.

سجلات وأدوات تكمل الصورة

SPF وDKIM وDMARC هي الأساس، ولكنك سوف تقابل أسماء أخرى في لوحات الخوادم وفي أدوات الاختبار، وهذا تعريف قصير بكل منها حتى تعرف أين يقع.

PTR والاستعلام العكسي المتطابق FCrDNS

سجل PTR يربط عنوان IP باسم، أي عكس سجل A، ويضبط في لوحة مزود السيرفر وليس في لوحة النطاق، وسيرفرات البريد الكبرى تشترط أن يكون للعنوان المرسل سجل PTR، وأن يشير الاسم الناتج بسجل A إلى العنوان نفسه، وهذا ما يسمى الاستعلام العكسي المتطابق Forward-Confirmed Reverse DNS، واختصاراً FCrDNS. ولنر عنواناً حقيقياً من سيرفرات Google:

dig -x 209.85.220.41 +short
dig A mail-sor-f41.google.com +short
mail-sor-f41.google.com.
209.85.220.41

العنوان يعطي الاسم، والاسم يعيد العنوان نفسه، فالدائرة مغلقة، ولاحظ أن هذا العنوان يقع داخل النطاق 209.85.128.0/17 الذي رأيناه في سجل _spf.google.com. والسيرفر الذي لا يملك هذا السجل سوف يرفض بريده Gmail كما تنص إرشادات المرسلين، مهما كانت سجلات SPF وDKIM صحيحة.

MTA-STS وTLS-RPT: تشفير الطريق بين السيرفرات

السجلات السابقة تثبت من أرسل الرسالة، ولكنها لا تحمي الرسالة أثناء انتقالها، فالتشفير بين السيرفرات عبر STARTTLS اختياري في الأصل، ويستطيع من يقف في منتصف الطريق أن يحذف عرض التشفير فتنتقل الرسالة نصاً واضحاً. لذلك جاء MTA-STS في RFC 8461 في سبتمبر 2018، وفيه تنشر سياسة تقول «لا تسلم بريد نطاقي إلا عبر TLS بشهادة صحيحة»، ومعه TLS-RPT في RFC 8460 الذي يرسل لك تقارير عن محاولات التسليم التي فشل فيها TLS. وهذا شكل السجلين لدى google.com:

dig TXT _mta-sts.google.com +short
dig TXT _smtp._tls.google.com +short
"v=STSv1; id=20210803T010101;"
"v=TLSRPTv1;rua=mailto:[email protected]"

وكلاهما اختياري، ولكنه سهل إذا كان خادمك يولده، وقد شرحنا إعداده يدوياً في دليل Postfix وDovecot.

ARC: شهادة الوسيط

رأينا أن القوائم البريدية وخدمات التحويل تكسر SPF، وأحياناً تكسر DKIM أيضاً عندما تضيف تذييلاً إلى الرسالة أو تعدل عنوانها، فتفشل الرسالة الحقيقية في DMARC. وسلسلة الاستلام الموثقة Authenticated Received Chain، واختصاراً ARC، في RFC 8617 الصادر في يوليو 2019 كمعيار تجريبي، تجعل كل وسيط يسجل نتائج الفحص كما وجدها ويوقعها، فيستطيع المستقبل الأخير أن يقول «هذه الرسالة كانت سليمة عندما وصلت إلى القائمة البريدية» إذا كان يثق بالوسيط. وهذا أمر يخص من يدير الوسيط وليس صاحب النطاق المرسل، ويذكر RFC 9989 أنه لم ينتشر على نطاق واسع حتى الآن، لذلك لا تحتاج أن تفعل شيئاً من جهتك.

BIMI: شعارك بجانب رسائلك

مؤشرات العلامة التجارية لتعريف الرسائل Brand Indicators for Message Identification، واختصاراً BIMI، تعرض شعار مؤسستك بجانب رسائلها في Gmail وغيره، وهي ما زالت مسودة Internet-Draft وليست معياراً، وشروطها أن يكون DMARC في وضع التطبيق أي quarantine أو reject، ثم تشترط Gmail شهادة VMC أو CMC تصدرها جهات معتمدة بعد التحقق من حقك في الشعار، والشهادة VMC تتطلب علامة تجارية مسجلة، وتدفع لها رسوماً سنوية تختلف بحسب الجهة. لذلك هي خطوة تجميلية للمؤسسات التي تملك علامة مسجلة وميزانية، ولا علاقة لها بوصول رسائلك.

لماذا أصبح كل هذا إلزامياً؟

لسنوات طويلة كانت هذه السجلات نصيحة يتجاهلها كثيرون، ثم أعلنت Google في أكتوبر 2023 أنها سوف تشترط من فبراير 2024 على من يرسل أكثر من 5000 رسالة يومياً إلى حسابات Gmail أن يوثق رسائله، وأعلنت Yahoo متطلبات مشابهة في الوقت نفسه. والمطلوب اليوم كما في إرشادات المرسلين لدى Google:

  • لكل مرسل مهما كان حجمه: SPF أو DKIM، وسجلا DNS صحيحان في الاتجاهين أي PTR يطابق الاسم، والاتصال عبر TLS، ونسبة شكاوى الرسائل المزعجة أقل من 0.3%.
  • لمن يرسل أكثر من 5000 رسالة يومياً: SPF وDKIM معاً، وسجل DMARC ولو بالقيمة p=none، وأن يتطابق النطاق في From مع نطاق SPF أو DKIM، وإلغاء الاشتراك بنقرة واحدة One-click Unsubscribe في الرسائل التسويقية.

ثم لحقت بهما Microsoft، حيث أعلنت في أبريل 2025 أن النطاقات التي ترسل أكثر من 5000 رسالة يومياً إلى Outlook.com وHotmail وLive يجب أن تنجح في SPF وDKIM وأن يكون لها DMARC بالقيمة p=none على الأقل متطابقاً مع أحدهما، وأنها ابتداءً من 5 مايو 2025 ترفض الرسائل المخالفة بالخطأ 550; 5.7.515 Access denied. أي أن أكبر ثلاثة مزودين للبريد الشخصي في العالم يطلبون اليوم الشيء نفسه، وحتى إذا كنت ترسل أقل من 5000 رسالة يومياً فهذه السجلات هي ما يفرق بين صندوق الوارد ومجلد الرسائل المزعجة.

كيف تختبر بريدك؟

بعد أن تنشر السجلات لا تفترض أنها تعمل، فالخطأ في حرف واحد يجعل السجل كأنه غير موجود دون أي رسالة خطأ تراها، وفيما يلي الأدوات التي ننصح بها، وكلها مجانية في استخدامها الأساسي.

رسالة إلى Gmail ثم «Show original»

أسهل اختبار وأصدقه أن ترسل رسالة من خادمك إلى حساب Gmail، ثم تفتحها وتضغط على النقاط الثلاث بجانب زر الرد وتختار Show original، فيعرض لك Gmail في أعلى الصفحة جدولاً بنتيجة SPF وDKIM وDMARC، وتحته الرسالة الخام كاملة، وفيها الترويسة Authentication-Results التي كتبها سيرفر Gmail، وشكلها كما يلي لرسالة من example.com:

Authentication-Results: mx.google.com;
       dkim=pass [email protected] header.s=mail header.b=Kx3vT1aB;
       spf=pass (google.com: domain of [email protected] designates 203.0.113.10 as permitted sender) [email protected];
       dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=example.com

في الترويسة أعلاه لاحظ التالي:

  • dkim=pass [email protected] header.s=mail: التوقيع صحيح، والنطاق الموقع example.com والمحدد mail.
  • spf=pass … [email protected]: عنوان الظرف، والعنوان 203.0.113.10 مسموح له في سجل SPF.
  • dmarc=pass … header.from=example.com: النطاق الظاهر في From تطابق مع أحد الفحصين، وp= سياستك كما قرأها Gmail، وdis=NONE أي أنه لم يطبق عليها أي عقوبة.
  • إذا رأيت dmarc=fail مع dkim=pass فقارن النطاق في header.i بالنطاق في header.from، فغالباً المشكلة في التطابق وليست في التوقيع.

mail-tester.com

mail-tester.com يعطيك عنواناً مؤقتاً ترسل إليه رسالة من خادمك، ثم يعرض تقريراً بدرجة من 10 فيه SPF وDKIM وDMARC وسجل PTR وقوائم الحظر Blacklists وتقييم SpamAssassin لمحتوى الرسالة، وميزته أنه يختبر رسالة حقيقية من خادمك وليس السجلات فقط. والاستخدام المجاني ثلاثة اختبارات خلال 24 ساعة، فأرسل رسالة تشبه رسائلك الحقيقية وليس كلمة «test» وحدها.

MXToolbox

مجموعة أدوات على الويب تفحص كل سجل على حدة: فحص SPF الذي يفك كل include ويعد الاستعلامات العشرة، وفحص DKIM وتعطيه النطاق والمحدد، وفحص DMARC، وفحص قوائم الحظر لعنوان IP سيرفرك، ومحلل الرؤوس الذي تلصق فيه الرسالة الخام من «Show original». ويوجد أيضاً اختبار الوصول الذي ترسل فيه رسالة إلى [email protected] فيصلك تقرير بالرد.

Google Admin Toolbox

أدوات Google المجانية، وأهمها لك Messageheader الذي يحلل الرسالة الخام ويعرض المسار الذي مرت به والتأخير في كل خطوة ونتائج الفحص، وDig الذي ينفذ استعلامات DNS من سيرفرات Google إذا لم يكن لديك dig. أما CheckMX فهو مصمم للنطاقات التي تستخدم Google Workspace ويقارن سجلاتها بإعداداتها، لذلك نتائجه لا تعنيك إذا كان بريدك على خادمك.

learndmarc.com

إذا أردت أن ترى كل ما شرحناه يتحرك أمامك فهذه أفضل أداة تعليمية، فموقع learndmarc.com من شركة URIports يعطيك عنواناً ترسل إليه رسالة، ثم يرسم لك خطوة بخطوة المحادثة بين السيرفرين وفحص SPF ثم DKIM ثم التطابق ثم قرار DMARC، مع الشرح بجانب كل خطوة، ويوجد فيه أيضاً تحليل الرؤوس الملصقة واختبار قصير من عشرة أسئلة.

internet.nl

اختبار البريد في internet.nl من منصة معايير الإنترنت الهولندية، وهي شراكة بين مجتمع الإنترنت والحكومة الهولندية، تعطيه اسم النطاق فقط فيفحص DMARC وDKIM وSPF، ثم التشفير بين السيرفرات STARTTLS وDANE، وتوقيع DNSSEC، وIPv6، ويشرح لك كل نتيجة وما يجب أن تفعله، وهو أشد من غيره، فلا تقلق إذا لم تحصل على الدرجة الكاملة من أول مرة.

الأمر dig لكل سجل

الأدوات السابقة تعتمد على الأمر نفسه في النهاية، وعندما تعرف الأوامر تفحص سجلاتك في ثوان من الطرفية Terminal، وهذه الأوامر لنطاق example.com كمرجع سريع، فاستبدله بنطاقك:

dig TXT example.com +short | grep spf1
dig TXT mail._domainkey.example.com +short
dig TXT _dmarc.example.com +short
dig MX example.com +short
dig -x 203.0.113.10 +short
dig TXT _mta-sts.example.com +short
dig TXT _smtp._tls.example.com +short

وبالترتيب: سجل SPF، ثم المفتاح العام لمحدد DKIM اسمه mail فاستبدله بالمحدد الذي يعرضه خادمك، ثم سجل DMARC، ثم سجلات MX، ثم الاستعلام العكسي لعنوان سيرفرك، ثم سجلا MTA-STS وTLS-RPT. وإذا عاد الأمر دون أي مخرج فالسجل غير منشور أو اسمه مكتوب بشكل خاطئ، وتذكر أن التعديل الجديد قد يتأخر في الظهور بحسب مدة التخزين المؤقت للسجل القديم.

Google Postmaster Tools

الأدوات السابقة تختبر الإعداد، أما Postmaster Tools فيعرض كيف يرى Gmail رسائلك فعلاً مع الوقت: نسبة الشكاوى، ونسبة نجاح SPF وDKIM وDMARC، وسمعة نطاقك. وتحتاج أن تثبت ملكية النطاق بسجل TXT، ولاحظ أن اللوحات لا تظهر فيها بيانات حتى يرسل نطاقك عدداً كافياً من الرسائل يومياً إلى Gmail، لذلك فهي مفيدة لمن يرسل النشرات أكثر من صندوق شخص واحد.

أخطاء شائعة تكسر هذه السجلات

سجلا SPF للنطاق نفسه

عندما تضيف خدمة جديدة تطلب منك «أضف هذا السجل»، فيضيف كثيرون سجل TXT ثانياً يبدأ بـ v=spf1 بجانب الأول، والمعيار ينص على أن وجود أكثر من سجل SPF يعطي النتيجة permerror، أي أن السجلين يلغيان بعضهما ويصبح نطاقك دون SPF. لذلك يجب أن يكون لكل نطاق سجل SPF واحد فقط، وكل خدمة جديدة تضاف إليه كـ include داخل السجل نفسه.

القيمة +all

يضعها البعض عندما تفشل رسائله ولا يعرف السبب، فتختفي المشكلة، ولكنها تقول لكل سيرفرات العالم إن أي عنوان IP مسموح له بالإرسال باسمك، أي أنك ألغيت SPF وأعطيت المنتحل نتيجة pass مجانية، وهي أسوأ قيمة على الإطلاق، والحل الصحيح أن تعرف المصدر الذي يفشل من تقارير DMARC وتضيفه وحده.

تجاوز الاستعلامات العشرة

كما رأينا في سجل github، كل خدمة خارجية تضيف include، وبعضها يحتوي على عدة include بداخله، فتتجاوز العشرة دون أن تلاحظ، وتصبح النتيجة permerror لكل رسائلك. لذلك افحص السجل في MXToolbox بعد كل إضافة، واحذف خدمات لم تعد تستخدمها، واستبدل a وmx بعناوين ip4 صريحة لسيرفراتك إذا ضاق الحد، فهي لا تحسب من العشرة.

مفتاح DKIM قصير أو مكسور عند النسخ

RFC 8301 يمنع التوقيع بـ rsa-sha1 ويشترط ألا يقل المفتاح عن 1024 بت، وينصح بـ 2048 بت على الأقل، فإذا كان لديك مفتاح قديم بطول 512 أو 1024 فأنشئ مفتاحاً جديداً بمحدد جديد، وانشره، ثم بدل التوقيع إليه، ثم ألغ القديم بالقيمة p= فارغة. والخطأ الآخر الأكثر شيوعاً يحدث عند النسخ، فالمفتاح بطول 2048 أطول من 255 حرفاً، وبعض لوحات DNS تقبل النص الطويل وتقسمه بنفسها، وبعضها تحتاج أن تقسمه أنت إلى نصين بين علامات تنصيص كما رأيت في مفتاح Gmail، وإذا نسخته من ملف فيه أسطر جديدة أو مسافات أو علامات تنصيص إضافية داخل قيمة p= فسوف يفشل التحقق من كل رسالة. لذلك بعد النشر اطلب السجل بالأمر dig وقارن قيمة p= بالمفتاح الذي يعرضه خادمك حرفاً بحرف، أو استخدم opendkim-testkey أو نافذة فحص DNS في لوحة خادمك.

p=reject من أول يوم

كما شرحنا، كل نظام نسيته يرسل باسم نطاقك سوف تختفي رسائله بصمت، ولن تعرف حتى يتصل بك أحد ليسأل لماذا لم تصله فاتورته، لذلك ابدأ بالقيمة none مع rua واقرأ التقارير قبل أي خطوة.

نسيان النطاقات الفرعية

سياسة p في نطاقك الرئيسي تنطبق على نطاقاته الفرعية ما لم تكتب sp=، وهذا جيد للحماية، ولكنه يعني أن نطاقاً فرعياً مثل news.example.com ترسل منه خدمة نشرات دون توقيع متطابق سوف يرفض إذا كانت سياستك reject، وفي الاتجاه المعاكس فالمهاجم يستطيع أن ينتحل نطاقاً فرعياً غير موجود مثل billing.example.com، لذلك راجع sp=، واستخدم الوسم الجديد np=reject للنطاقات الفرعية غير الموجودة، وانشر لكل نطاق فرعي يرسل البريد سجلات SPF وDKIM خاصة به.

نسيان المرسلين الخارجيين

نظام التذاكر وخدمة النشرات وبرنامج إدارة علاقات العملاء CRM ونظام الرواتب كلها ترسل باسم نطاقك من سيرفرات لا تملكها، وكل واحد منها يحتاج إلى أمرين: أن يضاف إلى SPF، وأن يوقع بـ DKIM باسم نطاقك وليس باسم نطاقه، وإلا فشل في DMARC. وإذا كنت ترسل نشراتك بنفسك مع listmonk فهو يرسل عبر سيرفر SMTP تختاره أنت، فالتوقيع يأتي من ذلك السيرفر، وتأكد أنه يوقع باسم النطاق الذي تكتبه في From.

أين تطبق هذا؟

كل خادم من خوادم البريد التي شرحناها يتعامل مع هذه السجلات بطريقته: mailcow ينشئ مفتاح DKIM ويعرض نافذة تفحص كل سجل وحالته، وPostfix مع Dovecot تكتب فيه كل شيء بيدك مع OpenDKIM وOpenDMARC وتختبر الانتحال بنفسك، وStalwart يولد ملف السجلات كاملاً وينشره ويدور المفاتيح، وإذا كان مزودك يغلق المنفذ 25 فدليل Amazon SES يشرح كيف تحافظ على التطابق عبر وسيط إرسال:

دليلتثبيت خادم البريد mailcow باستخدام Dockerأن تدير خادم بريدك بنفسك يعني أن تضمن وصول رسائلك إلى صندوق الوارد لا إلى الرسائل المزعجة. يشرح هذا الدليل تثبيت mailcow، وضبط سجلات DNS المطلوبة، وحل مشكلات التسليم الشائعة.دليلبناء خادم بريد بيدك مع Postfix وDovecot على Ubuntuنبني خادم بريد كاملاً من حزم Ubuntu دون Docker، ونضبط SPF وDKIM وDMARC بأنفسنا ونجرب انتحال النطاق لنرى الرفض بأعيننا، فتعرف دور كل مكون وأين تبحث عندما تتوقف رسالة.دليلتثبيت خادم البريد Stalwart باستخدام Docker Composeخادم بريد كامل في برنامج واحد بدل عدة مكونات تضبط كلاً منها على حدة. يشرح هذا الدليل تثبيت Stalwart على Ubuntu، ونشر سجلات DNS التي يولدها لك، والشهادة والنسخ الاحتياطي والتحديث.دليلإرسال بريد خادمك عبر Amazon SES مع mailcow وPostfix وStalwartإذا كان مزودك يحجب المنفذ 25 أو كانت رسائل سيرفرك الجديد تصل إلى Spam، فسوف نرسل البريد الصادر عبر Amazon SES ويبقى الاستقبال والصناديق على سيرفرك، مع DKIM وMAIL FROM وDMARC والارتدادات، والإعداد الدقيق لكل خادم بريد وأي تطبيق.دليلكيف تستضيف بريد مؤسستك بنفسك: دليل عملي من القرار إلى التشغيلمتى تستضيف بريد شركتك أو جامعتك بنفسك ومتى يكون البريد المستضاف أنسب، وما الذي تجهزه قبل البدء، وكيف تنقل المستخدمين على مراحل دون أن تضيع رسالة، مع مسار قراءة يجمع كل أدلة البريد على الموقع.

الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

  • SMTP لا يتحقق من المرسل، وفي كل رسالة عنوانان: الظرف MAIL FROM الذي يقرؤه السيرفر، والسطر From الذي يقرؤه الإنسان، والمنتحل يكتب ما يشاء في الاثنين.
  • SPF يقارن عنوان IP المرسل بقائمة في DNS لنطاق الظرف، وينكسر مع التحويل ولا ينظر إلى From، وله سجل واحد فقط لكل نطاق وعشرة استعلامات كحد أقصى.
  • DKIM توقيع بالمفتاح الخاص يتحقق منه أي شخص بالمفتاح العام في selector._domainkey، يثبت أن الرسالة لم تتغير ويصمد مع التحويل، ولكن النطاق الموقع قد يكون أي نطاق.
  • DMARC يشترط أن ينجح أحد الفحصين باسم النطاق نفسه الظاهر في From، ويعطيك التقارير لتعرف من يرسل باسمك، وانتقل من none إلى quarantine ثم reject على مراحل.
  • المعيار الحالي لـ DMARC هو RFC 9989 منذ مايو 2026، والوسم pct حذف منه، وGoogle وYahoo منذ 2024 وMicrosoft منذ مايو 2025 تشترط هذه السجلات على من يرسل بكميات كبيرة.
  • لا تفترض أن السجلات تعمل: أرسل إلى Gmail واقرأ «Show original»، وافحص بـ mail-tester وMXToolbox وlearndmarc، وراقب تقارير DMARC بعد كل خدمة جديدة.

سجل التحديثات

  • أكتوبر 2026: كتابة المقال، مع مخرجات dig حقيقية لنطاقات google.com وgmail.com وgithub.com واختبار الانتحال على Mailpit 1.27 وswaks 20240103.0.
نشرة عرب رووت | ArabRoot

معرفة تستحق مكاناً في بريدك.

مقالات مختارة وأدوات مفيدة وأفكار لمشروعك القادم، في رسالة واحدة كل أسبوع.

يمكنك إلغاء الاشتراك متى شئت. الخصوصية

تم استلام طلبك. افتح بريدك واضغط رابط التأكيد لإتمام الاشتراك.