الدرس 1 من 12 · أساسيات SMTP
رحلة رسالة بريد إلكتروني: SMTP وsubmission وIMAP
الهدف
فهم ما يحدث بين النقر على « إرسال » ووصول الرسالة إلى صندوق البريد، ومعرفة كيفية التحدّث بـ SMTP يدويًا مع خادم، وقراءة تاريخ الرسالة في ترويساتها.
الأساسيات
- أربعة أدوار: MUA (Thunderbird، Outlook، هاتف) يكتب الرسالة؛ وMSA يستقبل الإرسال الموثَّق (المنفذ 587 أو 465)؛ وMTA (Postfix) ينقل الرسالة من خادم إلى خادم (المنفذ 25)؛ وMDA (Dovecot) يضعها في صندوق البريد، الذي يقرؤه العميل عبر IMAP (المنفذ 993).
- للعثور على خادم المستلِم، يسأل MTA نظام DNS عن سجل MX الخاص بالنطاق.
- تتكوّن جلسة SMTP من خمسة أوامر:
EHLO،MAIL FROM،RCPT TO،DATA،QUIT. - الظرف (envelope) (
MAIL FROM،RCPT TO) يُستعمل للنقل؛ والترويسات (headers) (From:،To:،Subject:) هي ما يراه المستخدم. ويمكن أن يختلفا. - كل خادم تمرّ به الرسالة يضيف سطر
Received:في الأعلى: لذلك نقرأ التاريخ من الأسفل إلى الأعلى.
1. الفاعلون والمنافذ
poste de l'agence de Fès Internet ml-mail-01.masterlinux.lab
┌───────────────┐ 587 (STARTTLS) ┌──────────────┐ 25 (SMTP) ┌─────────────────────────────┐
│ MUA │ ── + mot de passe ─► │ MSA/MTA │ ─────────────► │ MTA Postfix ─► MDA Dovecot │
│ Thunderbird │ │ smtp.gmail… │ (MX du domaine) │ boîte Maildir │
└───────────────┘ └──────────────┘ └──────────────┬──────────────┘
IMAP 993 (TLS) │
téléphone du support ◄┘
أي: حاسوب وكالة فاس (MUA) يرسل عبر المنفذ 587 مع كلمة المرور إلى MSA/MTA، الذي ينقل الرسالة عبر المنفذ 25 إلى MX النطاق (Postfix ثم Dovecot وصندوق Maildir)، ثم يقرؤها هاتف فريق الدعم عبر IMAP 993.
| المنفذ | الاسم (/etc/services) |
الدور | التشفير |
|---|---|---|---|
| 25 | smtp | من خادم إلى خادم (الترحيل نحو MX) | STARTTLS اختياري |
| 587 | submission | إرسال المستخدمين، مع التوثيق | STARTTLS إلزامي |
| 465 | submissions | إرسال المستخدمين، TLS منذ بداية الاتصال | TLS ضمني |
| 143 | imap | قراءة صناديق البريد | STARTTLS |
| 993 | imaps | قراءة صناديق البريد | TLS ضمني |
| 110 / 995 | pop3 / pop3s | بروتوكول قديم لجلب البريد | — |
المنفذ 25 يُستعمل بين الخوادم. كثير من المشغّلين (في المغرب كما في غيره) يحجبون المنفذ 25 الصادر من الاتصالات المنزلية: على المستخدم الذي يرسل أن يمرّ عبر 587 أو 465، بعد التوثيق.
2. العثور على خادم المستلِم: سجل MX
dig MX masterlinux.lab +short
# 10 mail.masterlinux.lab. ← الأولوية 10 (الأصغر = المفضَّل)
# 20 mail2.masterlinux.lab. ← خادم احتياطي
dig A mail.masterlinux.lab +short
# 203.0.113.25
في غياب MX، يجرّب المُرسِل سجل A الخاص بالنطاق نفسه (قاعدة الرجوع في RFC 5321). ويمكن لنطاق لا يستقبل البريد أبدًا أن ينشر MX فارغًا (null MX): @ IN MX 0 ..
3. جلسة SMTP يدويًا
على خادم حقيقي، نختبر بـ swaks (الحزمة swaks) أو يدويًا بـ nc أو openssl s_client:
swaks --to support@masterlinux.lab --from ops@masterlinux.lab --server 127.0.0.1 --header "Subject: Test"
openssl s_client -connect mail.masterlinux.lab:25 -starttls smtp -crlf -quiet
الحوار سطرًا بسطر (C = العميل، S = الخادم):
S: 220 mail.masterlinux.lab ESMTP Postfix ← رسالة الترحيب (banner)
C: EHLO ml-poste-01
S: 250-mail.masterlinux.lab
S: 250-SIZE 10240000 ← الحجم الأقصى المقبول
S: 250-STARTTLS ← التشفير ممكن
S: 250 8BITMIME
C: MAIL FROM:<ops@masterlinux.lab> ← الظرف: المُرسِل (عنوان الرجوع)
S: 250 2.1.0 Ok
C: RCPT TO:<support@masterlinux.lab> ← الظرف: المستلِم
S: 250 2.1.5 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: ops@masterlinux.lab ← الترويسات (ما يراه المستخدم)
C: Subject: Premier envoi
C: ← سطر فارغ: نهاية الترويسات
C: Bonjour.
C: . ← نقطة وحدها: نهاية الرسالة
S: 250 2.0.0 Ok: queued as 3F2A61C0D2 ← المعرّف في طابور الرسائل
C: QUIT
S: 221 2.0.0 Bye
تُقرأ رموز الردّ من رقمها الأول: 2xx نجاح، 3xx تابِع، 4xx فشل مؤقّت (سيعيد المُرسِل المحاولة)، 5xx فشل نهائي (إرجاع إلى المُرسِل). ويحدّد الرمز الموسَّع (5.1.1، 4.7.1…) السبب: 5.1.1 = صندوق بريد غير معروف، 5.7.1 = مرفوض بقاعدة أمنية.
في مختبرات هذا التكوين
آلة المختبر غير متصلة بالشبكة. تشغّل ml-smtpd (خادم SMTP التدريبي في المختبر)، وهو يقرأ الملف الحقيقي /etc/postfix/main.cf ويردّ برسائل Postfix. يستمع على 127.0.0.1:25 و:587، ويسلّم رسائل النطاقات المحلية بصيغة Maildir، ويكتب /var/log/mail.log.
# 1. مثل sendmail -bs: جلسة SMTP على الإدخال القياسي
printf 'EHLO lab\r\nMAIL FROM:<ops@masterlinux.lab>\r\nRCPT TO:<support@masterlinux.lab>\r\nQUIT\r\n' | ml-smtpd --stdio
# 2. عبر الشبكة المحلية، باستعمال Python (يعرض set_debuglevel الحوار كاملًا)
python3 -c 'import smtplib; s=smtplib.SMTP("127.0.0.1", 25); s.set_debuglevel(1); s.noop(); s.quit()'
# 3. يدويًا باستعمال bash (إعادة التوجيه /dev/tcp)
exec 3<>/dev/tcp/127.0.0.1/25; head -1 <&3; printf 'QUIT\r\n' >&3; cat <&3
4. الظرف مقابل الترويسات
يشبه الظرف العنوانَ المكتوب على رسالة بريدية ورقية؛ أما الترويسات فهي رأس الرسالة في الداخل. ساعي البريد لا يقرأ إلا الظرف.
| الظرف (SMTP) | الترويسات (المحتوى) | |
|---|---|---|
| المُرسِل | MAIL FROM:<bounces@masterlinux.lab> |
From: Support <support@masterlinux.lab> |
| المستلِم | RCPT TO:<admin@masterlinux.lab> |
To:، Cc: (ولا شيء بالنسبة لـ Bcc) |
| من يستعمله | الخوادم، SPF، إشعارات الأخطاء | المستخدم، DMARC، المرشّحات |
| الأثر عند الوصول | Return-Path: يضيفه الخادم الأخير |
دون تغيير |
هذا ما يسمح لمنصة إرسال باستقبال إشعارات الأخطاء (bounces@…) مع عرض عنوان المتجر. وهو أيضًا ما يستغلّه المنتحلون: ومن هنا جاءت SPF وDKIM وDMARC (المستوى 4).
5. قراءة أسطر Received
Received: from mail-ed1-f45.google.com (mail-ed1-f45.google.com [209.85.208.45]) ← 3. استلمه خادمنا
by mail.masterlinux.lab (Postfix) with ESMTPS id 4B7F21C0A2 …
Received: by mail-ed1-f45.google.com with SMTP id … ← 2. نقل داخلي لدى Google
Received: from [192.168.1.23] ([41.250.88.17]) by smtp.gmail.com with ESMTPSA … ← 1. إرسال العميل
ESMTPS= مشفَّر (TLS)،ESMTPA= موثَّق،ESMTPSA= الاثنان معًا.- في
from X ([IP])، الاسم X يصرّح به العميل (وقد يكذب)؛ أما عنوان IP بين المعقوفين فيراه الخادم (موثوق إذا كان هذا الخادم موثوقًا). 192.168.1.23هو العنوان الخاص للحاسوب خلف جهاز الراوتر؛ و41.250.88.17هو العنوان العمومي الذي رآه Gmail.
grep -n '^Received:' /root/recu.eml # أسطر البداية
awk '/^Received:/,/;/' /root/recu.eml # كل سطر Received كاملًا (حتى التاريخ)
حالة واقعية
صباح يوم اثنين، يتلقّى فريق الدعم في متجر MasterLinux شكوى: « لم أتلقَّ ردّكم أبدًا ». عند إعادة قراءة ترويسات الرسالة المرسَلة، يلاحظ المسؤول أن حاسوب الدعم كان يرسل بـ ESMTP (بدون A) نحو المنفذ 25 لخادم قديم: كانت الرسالة تخرج دون توثيق فيصنّفها Gmail رسالة مزعجة (spam). ضبط برنامج البريد على 587 + STARTTLS + التوثيق حلّ المشكلة. قراءة أسطر Received قبل لمس الإعدادات توفّر ساعات من العمل.
الأخطاء الشائعة
- الخلط بين 25 و587: برنامج بريد مضبوط على 25 يعمل في المكتب ثم يفشل عبر 4G (المنفذ محجوب لدى المشغّل).
- تصديق الترويسة From:: يكتبها المُرسِل، مثل الاسم الذي يلي
fromفي Received. وحدها عناوين IP التي أضافتها خوادمك موثوقة. - نسيان
\r\nفي SMTP اليدوي: بعض الخوادم ترفض نهايات الأسطر المنفردة (\n) — وهذا بالذات أساس هجوم « SMTP smuggling » في 2023-2024، الذي صُحِّح في Postfix بواسطةsmtpd_forbid_bare_newline. - قراءة أسطر Received من الأعلى إلى الأسفل: السطر الأول هو الأحدث.
المختبر
على آلة المختبر، يؤدّي ml-smtpd دور ml-mail-01 للنطاق masterlinux.lab. ستقوم بما يلي: إرسال رسالة أولى عبر SMTP، وإرسال رسالة يختلف ظرفها عن ترويستها، وإحداث رفض 550 5.1.1، والعثور على عنوان IP الأصلي لرسالة حقيقية، وتلخيص منافذ البريد.
اختبار قصير
- ما سجل DNS الذي يحدّد الخادم الذي يستقبل بريد نطاق ما؟
- ما الفرق بين
MAIL FROMوالترويسةFrom:؟ - ماذا يعني رمز ردّ يبدأ بالرقم 4؟
- لماذا يرسل المستخدم عبر 587 وليس عبر 25؟
- بأي ترتيب نقرأ أسطر
Received:؟
الأجوبة
- سجل MX (مع أولويته؛ الأصغر = المفضَّل).
MAIL FROMجزء من ظرف SMTP (عنوان إرجاع الأخطاء، يستعمله SPF)؛ أماFrom:فترويسة من المحتوى تُعرض للمستخدم.- فشل مؤقّت: يحتفظ الخادم المُرسِل بالرسالة في طابور الرسائل ويعيد المحاولة لاحقًا.
- المنفذ 587 (submission) يشترط التوثيق والتشفير؛ أما المنفذ 25 فمخصّص للتبادل بين الخوادم وغالبًا ما يحجبه المشغّلون في الاتجاه الصادر.
- من الأسفل إلى الأعلى: كل خادم يضيف سطره فوق الأسطر السابقة.