دليلك العملي لفهم شبكات لينكس: العناوين والمقابس وبروتوكولات IP وSSH وDNS

دليلك العملي لفهم شبكات لينكس: العناوين والمقابس وبروتوكولات IP وSSH وDNS

مدخل إلى معمارية شبكات لينكس الحديثة

تشغيل الخدمات واستضافتها على خوادم لينكس دون فهم مسار تدفق الحزم عبر النواة يُحوّل عمليات استكشاف الأخطاء إلى ضرب من التخمين العشوائي. استغنت التوزيعات الحديثة كلياً عن الأدوات التاريخية مثل netstat وifconfig، واعتمدت على حزم متقدمة تتعامل مباشرة مع واجهات النواة (Kernel Spaces). لفهم بيئة الشبكة الحالية، يجب بناء نموذج ذهني يربط بين عناوين الطبقة الثالثة، وإدارة المنافذ في الطبقة الرابعة، والبروتوكولات التأسيسية مثل SSH وDNS.

واجهات الشبكة وعناوين IP: نموذج توجيه الحزم

تبدأ معالجة البيانات من “واجهة الشبكة” (Network Interface)، وهي إما تمثيل برمجي لبطاقة عتادية مثل eth0 أو enp3s0، أو واجهة افتراضية بالكامل مثل واجهة الاسترجاع المحلي (Loopback) المسماة lo، والتي تستخدم العنوان 127.0.0.1 لمعالجة الاتصالات الداخلية التي لا تغادر الجهاز إطلاقاً.

تقسيم الشبكات والعنونة الخاصة

تعتمد خوادم لينكس في البيئات المحلية والسحابية على معيار RFC 1918 الذي يحدد نطاقات العناوين الخاصة غير القابلة للتوجيه على الإنترنت العام:

  • 10.0.0.0/8: يُستخدم بكثرة في مراكز البيانات الضخمة وشبكات الحاويات (Docker & Kubernetes).
  • 172.16.0.0/12: شائع في منصات السحابة والشبكات الافتراضية الخاصة (VPCs).
  • 192.168.0.0/16: النطاق المعتاد للشبكات المنزلية والمكتبية الصغيرة.

يعبر التدوين غير الفئوي CIDR (مثل /24) عن قناع الشبكة (Subnet Mask). وجود /24 يعني أن أول 24 بت مخصصة لعنوان الشبكة (255.255.255.0)، مما يترك 8 بتات توفر 254 عنواناً متاحاً للأجهزة المضيفة داخل نفس النطاق دون الحاجة إلى بوابة توجيه خارجية.

إدارة العناوين والتوجيه بحزمة iproute2

حزمت التوزيعات الحديثة (مثل Ubuntu 24.04 وDebian 12 وRHEL 9) أدوات حزمة iproute2 كبديل نهائي لحزمة net-tools القديمة. لفحص الواجهات والعناوين بصيغة مقتضبة، نستخدم:

ip -4 -br addr show

ولمعرفة المسار الذي تسلكه الحزم للخروج من الشبكة المحلية نحو الإنترنت، يتم استعراض “البوابة الافتراضية” (Default Gateway) بالأمر:

ip route show default

يعرض هذا الأمر عنوان الموجه (Router) والواجهة المسؤولة عن تمرير الحزم الخارجية، وبدونه يعجز الخادم عن الاتصال بأي عنوان خارج نطاق شبكته الفرعية المباشرة.

المنافذ والمقابس (Sockets): كيف تستمع الخدمات في لينكس؟

المقبس (Network Socket) هو ناتج دمج عنوان IP مع رقم منفذ (Port) محدد لتوجيه البيانات القادمة إلى العملية البرمجية (Process) المسؤولة عنها داخل نظام التشغيل.

أنواع المنافذ وآلية تقييد الاستماع (Binding)

تتوزع أرقام المنافذ من 1 إلى 65535، وتخضع لتقسيم صارم داخل نواة لينكس:

  • المنافذ المحجوزة (Privileged Ports 1–1023): لا يمكن لأي عملية الارتباط بها والاستماع عبرها ما لم تكن تملك صلاحيات المستخدم الجذر (Root) أو قدرة النظام CAP_NET_BIND_SERVICE. من أمثلتها HTTP (80) وHTTPS (443) وSSH (22).
  • المنافذ العادية والمؤقتة (1024–65535): متاحة للمستخدمين العاديين والتطبيقات غير المقيدة، وتُستغل المنافذ العليا منها (Ephemeral Ports) لإجراء الاتصالات الصادرة العشوائية.

تحدد قيمة عنوان الاستماع (Binding IP) نطاق ظهور الخدمة:

  • 127.0.0.1: الخدمة معزولة تماماً؛ لا يمكن الوصول إليها إلا من داخل نفس الخادم محلياً.
  • 0.0.0.0: تستمع الخدمة على كافة واجهات الخادم المادية والافتراضية، مما يجعلها متاحة للشبكة الخارجية إذا لم يحجبها جدار الحماية.

مراقبة المقابس باستخدام أداة ss

حلت أداة ss (Socket Statistics) محل netstat المتقادمة. تستعلم ss مباشرة من مساحة النواة عبر واجهة Netlink، مما يجعلها أسرع بمراحل في الخوادم المحملة بآلاف الاتصالات المفتوحة. الأمر المعياري لفحص المنافذ المستمعة ومعرفة أرقام العمليات هو:

sudo ss -tulnp

الخيارات تعني: -t لبروتوكول TCP، و-u لبروتوكول UDP، و-l للمنافذ المستمعة فقط، و-n لعرض الأرقام بدلاً من تحويلها إلى أسماء خدمات، و-p لإظهار اسم ومعرف العملية (PID).

بروتوكول SSH: الوصول البعيد الآمن

يعتمد بروتوكول Secure Shell (SSH) على معمارية العميل والخادم لتوفير قناة اتصال مشفرة عبر المنفذ 22 افتراضياً. يتحكم خادم OpenSSH (المعروف باسم sshd) في قبول الجلسات والمصادقة وتطبيق الصلاحيات.

المصادقة بالمفاتيح المشفرة الحديثة

أصبح استخدام كلمات المرور للولوج إلى خوادم لينكس ممارسة غير مقبولة أمنياً نظراً لتعرضها لهجمات التخمين المستمرة. المعيار الحالي في توليد المفاتيح يعتمد على خوارزمية المنحنيات الإهليلجية Ed25519، بعد إيقاف دعم توقيعات SHA-1 RSA الضعيفة افتراضياً في إصدارات OpenSSH 8.8 والإصدارات اللاحقة.

يتم توليد المفتاح على جهاز العميل عبر الأمر:

ssh-keygen -t ed25519 -C "admin@company.internal"

يُحفظ المفتاح الخاص حصراً على جهاز المستخدم، بينما يُنقل المفتاح العام إلى الخادم داخل الملف:

~/.ssh/authorized_keys

تأمين خادم OpenSSH وتفعيل المقابس

تعتمد توزيعات لينكس الحديثة (مثل إصدارات Ubuntu الأخيرة) على ميزة systemd Socket Activation لخدمة SSH عبر الوحدة ssh.socket، حيث يستمع النظام على المنفذ 22 ولا يُطلق عملية sshd إلا عند استلام طلب اتصال فعلي توفيراً للموارد.

لتأمين الخادم، يُستحسن إنشاء ملف ضبط إضافي داخل المجلد /etc/ssh/sshd_config.d/ لمنع ولوج حساب root بكلمة مرور، وإلغاء المصادقة بكلمات المرور تماماً:

PermitRootLogin prohibit-password
PasswordAuthentication no

معمارية DNS وحل أسماء النطاقات في لينكس

لا يقتصر حل الأسماء في لينكس على إرسال استعلام فوري إلى خادم خارجي، بل يتبع تسلسلاً هرمياً دقيقاً تديره مكتبة C القياسية (glibc) بالتنسيق مع شياطين النظام.

مسار التحليل الداخلي: من الملفات إلى الشبكة

يحدد الملف /etc/nsswitch.conf أولوية البحث عن العناوين عبر السطر:

hosts: files dns

يبحث النظام أولاً في الملف المحلي /etc/hosts لمطابقة الأسماء يدوياً، فإن لم يجد تطابقاً ينتقل إلى طبقة استعلام DNS.

لغز العنوان 127.0.0.53 وشيطان systemd-resolved

يلاحظ مدراء الأنظمة في التوزيعات الحديثة احتواء الملف /etc/resolv.conf على خادم أسماء واحد فقط وهو 127.0.0.53. هذا العنوان ليس خادماً خارجياً، بل هو مصادقة محلية (Local Stub Resolver) يديرها شيطان systemd-resolved.

يعمل systemd-resolved كحلقة وسيطة تقوم بتخزين الإجابات مؤقتاً (Caching) وإرسال الاستعلامات إلى خوادم DNS الفعلية المستلمة من بروتوكول DHCP أو ملفات إعداد الشبكة الثابتة (Netplan / NetworkManager). لفحص خوادم DNS النشطة فعلياً على الواجهات، تُستخدم الأداة المخصصة:

resolvectl status

سكربت شامل لتشخيص وتدقيق شبكة الخادم

السكربت التالي مكتوب بلغة Bash، ويقوم بتدقيق طبقات الشبكة الثلاث (عناوين IP، المنافذ المفتوحة، ومسار استعلامات DNS) بشكل آلي بالاعتماد التام على الحزم البرمجية الحديثة فقط دون استدعاء أي أداة متقادمة:

#!/usr/bin/env bash
# ==============================================================================
# Linux Networking Audit & Health Check Script
# Validates IP assignments, default routing, listening sockets, and DNS resolver
# ==============================================================================

set -euo pipefail

echo "=== [1/4] Checking Active Network Interfaces and IPs ==="
ip -4 -br addr show

echo -e "\n=== [2/4] Verifying Default Gateway Route ==="
if ip route show default | grep -q 'default'; then
    ip route show default
else
    echo "CRITICAL: No default gateway detected! Internet connectivity will fail."
    exit 1
fi

echo -e "\n=== [3/4] Auditing Listening TCP/UDP Sockets ==="
# -t (TCP) -u (UDP) -l (Listening) -n (Numeric) -p (Process details)
sudo ss -tulnp

echo -e "\n=== Checking SSH Port State ==="
if sudo ss -tuln | grep -q ':22 '; then
    echo "PASS: SSH daemon is actively listening on port 22."
else
    echo "WARNING: Port 22 is not listening. Verify ssh.service or ssh.socket."
fi

echo -e "\n=== [4/4] Testing DNS Resolution Pipeline ==="
if command -v resolvectl >/dev/null 2>&1; then
    echo "Active DNS upstream servers via systemd-resolved:"
    resolvectl dns
else
    echo "Upstream nameservers defined in /etc/resolv.conf:"
    grep '^nameserver' /etc/resolv.conf
fi

echo -e "\nPerforming end-to-end lookup test for 'kernel.org'..."
if command -v dig >/dev/null 2>&1; then
    dig +noall +answer +stats kernel.org A
else
    echo "Tool 'dig' is missing. Install 'bind9-dnsutils' or use 'getent hosts kernel.org'"
    getent hosts kernel.org
fi

echo -e "\n=== Network Audit Completed Successfully ==="

شرح آلية عمل السكربت سطراً بسطر

  • #!/usr/bin/env bash: توجيه النظام لتنفيذ السكربت عبر مفسر Bash المعتمد في مسارات البيئة.
  • set -euo pipefail: تفعيل وضع الحماية الصارم لإيقاف السكربت فور وقوع أي خطأ، ومنع استخدام متغيرات غير معرّفة، والتعامل مع الأخطاء غير المعلنة داخل سلاسل الأوامر المتتالية.
  • ip -4 -br addr show: استعراض جميع الواجهات المتصلة وعناوين IPv4 بصيغة موجزة تُظهر اسم الواجهة وحالتها وعنوانها مباشرة.
  • ip route show default: التأكد من توفر مسار البوابة الافتراضية؛ وإذا لم يُعثر على مسار خروج، يُوقف السكربت نفسه فوراً مع إرسال رسالة خطأ حرجة.
  • sudo ss -tulnp: فحص المقابس المستمعة وعرض معرفات العمليات المرتبطة بها لمعرفة البرمجيات المسيطرة على المنافذ.
  • sudo ss -tuln | grep -q ':22 ': فحص مشروط للتحقق من أن منفذ SSH يعمل ويستمع على اتصالات العملاء لتجنب انقطاع إدارة الخادم.
  • command -v resolvectl: التحقق من توفر أداة resolvectl الحديثة لقراءة خوادم DNS المرتبطة بـ systemd-resolved، مع توفير بديل احتياطي لقراءة /etc/resolv.conf إذا كانت التوزيعة لا تدير النظام بالـ systemd.
  • dig +noall +answer +stats kernel.org A: تنفيذ استعلام حي للتحقق من قدرة الخادم على تحويل الأسماء إلى عناوين IP حسابياً وعرض زمن الاستجابة، مع الرجوع لأمر getent hosts في حال عدم تثبيت حزمة bind9-dnsutils.

الأخطاء الشائعة في شبكات لينكس وحلولها العملية

1. التعديل اليدوي على ملف /etc/resolv.conf

المشكلة: يقوم المستخدم بتعديل ملف /etc/resolv.conf مباشرة لإضافة خوادم أسماء مثل nameserver 1.1.1.1، ولكن التعديلات تُمسح بالكامل عند إعادة تشغيل النظام أو تجديد اتصال DHCP.

السبب والحل: هذا الملف أصبح مجرد وصلة رمزية (Symlink) تشير إلى ملف تديره خدمات النظام التلقائية مثل systemd-resolved أو Netplan. لتغيير خوادم الأسماء بشكل دائم في الأنظمة الحديثة، يجب تعديل ملف إعداد الشبكة في /etc/netplan/*.yaml وإضافة نطاقات DNS تحت قسم nameservers، ثم تطبيق التعديل بالأمر sudo netplan apply.

2. خلط عزل المنفذ المحلي 127.0.0.1 بقيود جدار الحماية

المشكلة: تشغيل تطبيق ويب (مثل خادم Node.js أو قاعدة بيانات) ومحاولة الوصول إليه من جهاز خارجي فتفشل المحاولة. يظن المدير أن جدار الحماية (UFW أو Firewalld) يحجب المنفذ، رغم أن الجدار معطل كلياً.

السبب والحل: التطبيق تم ربطه برمجياً بعنوان الاسترجاع الداخلي 127.0.0.1:3000 بدلاً من الربط بجميع الواجهات. حل المشكلة يكمن في تعديل إعدادات التطبيق ليصبح عنوان الاستماع 0.0.0.0:3000 ليسمح للنواة باستقبال الحزم الواردة من بطاقات الشبكة المادية.

3. تعطل الولوج عبر SSH بسبب تصاريح الملفات المتساهلة

المشكلة: يضع المسؤول مفتاحه العام داخل authorized_keys لكن الخادم يستمر في المطالبة بكلمة المرور أو يرفض جلسة الاتصال برسالة Permission denied (publickey) دون سبب واضح في الطرفية.

السبب والحل: يرفض شيطان sshd أمنياً قراءة المفاتيح إذا كانت التصاريح تسمح للمستخدمين الآخرين على النظام بالقراءة أو الكتابة داخل مجلد الإعداد. الحل الصارم هو إعادة ضبط الأذونات بالقيم المعيارية التالية:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519

4. الخلط بين فشل حل DNS وانقطاع الشبكة الفعلي

المشكلة: تنفيذ الأمر ping google.com وفشله، مما يدفع المسؤول إلى الاستنتاج الخاطئ بأن الخادم فقد اتصاله بالإنترنت والبدء في العبث بإعدادات البوابة والواجهات.

السبب والحل: يجب فصل طبقة توجيه الحزم (Routing) عن طبقة حل الأسماء (Resolution). يتم التشخيص دائماً عبر فحص عنوان IP خام لا يعتمد على الأسماء مثل ping 1.1.1.1. فإذا نجح الاتصال بالرقم وفشل بالاسم، تكون المشكلة محصورة كلياً في إعدادات DNS ومسار الوصول لخادم الأسماء وليست في اتصال الخادم بالشبكة.

متى تعتمد هذه الأدوات ومتى تتجاوزها لحلول متقدمة؟

الأدوات الأساسية التي تم تفصيلها (مثل iproute2 وss وdig وresolvectl) تمثل حجر الزاوية الذي لا غنى عنه لأي مهندس يتعامل مباشرة مع الخوادم المستقلة (Bare-metal)، أو الأجهزة الافتراضية الفردية (VMs)، أو لتشخيص أعطال الحاويات من الداخل عند انهيار الاتصال. تمنحك هذه الأوامر رؤية تشريحية دقيقة لما تراه النواة في تلك اللحظة بالذات دون طبقات وسيطة تحجب الحقيقة.

في المقابل، لا يُنصح بالاعتماد على التعديل اليدوي لهذه الأدوات في البيئات السحابية المؤتمتة ذات الحجم الكبير، أو العناقيد الموزعة (Kubernetes Clusters). في مثل هذه البيئات المعقدة التي تُبنى فيها شبكات تراكبية (Overlay Networks مثل VXLAN أو Geneve)، تصبح إدارة القواعد يدوياً مصدراً للفوضى؛ ويُستعاض عنها بأدوات البنية التحتية البرمجية (IaC) مثل Terraform، ومعايير التعريف التصريحي الثابت مثل Netplan وCloud-init، وحلول إدارة ومراقبة تدفق الحزم المتقدمة كشبكات الخدمات (Service Meshes) مثل Cilium وIstio المعتمدة على تقنيات eBPF الحديثة لتوجيه وتأمين حركة البيانات على مستوى النواة آلياً.