ما هو منفذ الشبكة وكيف تستمع خدمات Linux؟
افهم كيف يوجّه المنفذ حركة الشبكة إلى الخدمة الصحيحة، وتعلّم استخدام ss لمعرفة ما يستمع، والتمييز بين المنفذ المحلي والمنفذ العام.
ما هو المنفذ فعلياً
المنفذ هو رقم يتيح لخادم واحد تشغيل عدة خدمات في الوقت نفسه دون اختلاط حركة الشبكة بينها. لدى VPS الخاص بك عنوان IP واحد، لكنه قد يشغّل خادم ويب وخادم SSH وقاعدة بيانات في الوقت نفسه. عندما تصل حزمة، يحتاج نظام التشغيل إلى معرفة الخدمة المقصودة. يحدد رقم المنفذ ذلك. تصل حركة الويب إلى المنفذ 443، وحركة SSH إلى المنفذ 22. يوصّل عنوان IP الحزمة إلى خادمك، بينما يوصّلها المنفذ إلى البرنامج الصحيح على ذلك الخادم.
المنفذ رقم مكوّن من 16 بتاً: تتيح 16 بتاً القيم من 0 إلى 65535، ويكون الرقم 0 محجوزاً، لذلك تمتد المنافذ عملياً من 1 إلى 65535. تُسمّى المنافذ الأقل من 1024 المنافذ «المعروفة جيداً»، وتتطلب حساب root لفتحها. لذلك تستخدمها الخدمات القياسية: 22 لـSSH، و80 لـHTTP، و443 لـHTTPS، و53 لـDNS. ويمكن للبرامج العادية استخدام أي منفذ أعلى من 1024.
يوجد نوعان من المنافذ: TCP وUDP، ويكون رقم المنفذ في أحدهما منفصلاً عن الرقم نفسه في الآخر. TCP هو البروتوكول القائم على الاتصالات الذي تستخدمه معظم الخدمات، مثل SSH وHTTP وقواعد البيانات. أما UDP فهو عديم الاتصال ويُستخدم لأشياء مثل DNS وبعض شبكات VPN. عند فتح منفذ في جدار الحماية، تحدد عادةً نوع البروتوكول أيضاً، كما في 22/tcp.
الاستماع يعني أن برنامجاً ينتظر الاتصالات على منفذ
يطلب البرنامج الذي يريد استقبال الاتصالات من النواة أن «يستمع» على منفذ. منذ تلك اللحظة يصبح المنفذ مفتوحاً على الجهاز، ويرد البرنامج على أي اتصال يصل إليه، وفقاً لقواعد جدار الحماية. أما المنفذ الذي لا يستمع عليه أي برنامج، فيرفض الاتصالات ببساطة. لذلك يكون السؤال الأول في أي فحص أمني هو: ما الذي يستمع، وأين؟
الأمر الذي يجيب عن ذلك هو ss:
sudo ss -tlnpتعني الخيارات TCP (t)، وعرض مقابس الاستماع فقط (l)، وعرض أرقام المنافذ بصيغة رقمية (n، بحيث ترى 22 بدلاً من ssh)، وعرض العملية المالكة (p). مثال على نتيجة نموذجية:
State Recv-Q Local Address:Port Process
LISTEN 0 0.0.0.0:22 sshd
LISTEN 0 127.0.0.1:5432 postgres
LISTEN 0 [::]:80 nginxيخبرك العمود Process بالبرنامج الذي يملك كل منفذ. بهذه الطريقة يمكنك تحديد برنامج لم تقصد إبقاءه قيد التشغيل.
عمود العنوان المحلي هو الجزء المهم
اقرأ العنوان الموجود أمام كل منفذ بعناية، لأنه يحدد الجهة التي يمكنها الوصول إلى الخدمة. هناك ثلاث حالات ستراها باستمرار.
0.0.0.0:22 يعني «الاستماع على كل عناوين IPv4 التي يملكها هذا الجهاز»، بما فيها العنوان العام. ويمكن الوصول إلى الخدمة من الإنترنت عبر IPv4، إذا سمح جدار الحماية بذلك.
[::]:80 يعني الشيء نفسه بالنسبة إلى IPv6: الاستماع على كل عناوين IPv6، بما فيها العناوين العامة. تربط العديد من البرامج الخدمة بهذا العنوان افتراضياً، وعلى Linux تقبل مقبس :: اتصالات IPv4 أيضاً في كثير من الحالات.
127.0.0.1:5432 يعني «الاستماع على loopback فقط». 127.0.0.1 هو العنوان الذي يستخدمه الجهاز للاتصال بنفسه، ولا يمكن توجيهه من أي مكان آخر. ولا يمكن الوصول إلى خدمة مرتبطة بهذا العنوان إلا من الخادم نفسه، وليس من الإنترنت بأي حال، بغض النظر عن إعدادات جدار الحماية. سطر Postgres أعلاه آمن بحكم طريقة ربطه.
القاعدة العملية واضحة: يجب أن تربط قاعدة البيانات أو ذاكرة التخزين المؤقت أو لوحة الإدارة التي تستخدمها تطبيقاتك فقط بـ127.0.0.1، لا بـ0.0.0.0. فإذا لم تستمع الخدمة على عنوان عام، فلن يجد المهاجم منفذاً يمكنه الوصول إليه.
الاستماع لا يعني إمكانية الوصول
هناك تمييز آخر يزيل كثيراً من الالتباس. يعني فتح منفذ على الجهاز أن برنامجاً يستمع عليه، وهذا يختلف عن إمكانية الوصول إلى المنفذ من الخارج، أي أن جدار الحماية يسمح بالاتصال به. يجب أن يتحقق الشرطان حتى يتمكن عميل بعيد من الاتصال. كما يختلف مظهر الفشلين من جهة العميل: رفض الاتصال يعني أن شيئاً لم يكن يستمع على المنفذ، بينما يعني تعليق الاتصال ثم انتهاء مهلة الانتظار عادةً أن جدار الحماية أسقط الحزمة، وهذا بالضبط ما توضحه رسالتا SSH هاتان.
إذن، هناك طبقتان للتحكم. تحدد ما يستمع من خلال ضبط عنوان الربط لكل خدمة. وتحدد ما يمكن للعالم الخارجي الوصول إليه باستخدام جدار حماية. يستخدم الخادم المُدار جيداً الأمرين معاً: تربط الخدمات نفسها بالعناوين التي تحتاج إليها فقط، ويمنع جدار الحماية كل ما لم تسمح به صراحةً. قراءة ما يستمع باستخدام ss هي الخطوة الأولى؛ وتحديد ما يسمح به جدار الحماية هو الخطوة الثانية، ويتناولها موضوع مقدمة إلى firewalls باستخدام UFW.
هناك تفصيل دقيق يسبب المشكلات هنا. إن IPv4 وIPv6 منفصلان، وجدار الحماية الذي يغطي IPv4 فقط يترك خدمات [::] مفتوحة عبر IPv6. لهذا الفخ المحدد موضوع مستقل: فخ جدار الحماية في IPv6.
FAQ
كيف أعرف المنافذ المفتوحة على خادم Linux؟
شغّل sudo ss -tlnp لـTCP أو sudo ss -ulnp لـUDP. يعرض ذلك كل socket يستمع للاتصالات، والمنفذ، والعنوان المحلي المرتبط به، والعملية المالكة له. اقرأ العمود Local Address: تعني 0.0.0.0 أو [::] أن الخدمة مكشوفة على الشبكة، بينما تعني 127.0.0.1 أنها تستمع على الجهاز نفسه فقط.
ما الفرق بين 0.0.0.0 و127.0.0.1؟
تعني 0.0.0.0 «الاستماع على جميع عناوين IPv4»، بما في ذلك العنوان العام، ولذلك يمكن الوصول إلى الخدمة من الشبكة. أما 127.0.0.1 فهو loopback، أي العنوان الذي يستخدمه الجهاز للاتصال بنفسه. ولا يمكن توجيهه من أي مكان آخر، لذلك لا يمكن الوصول إلى الخدمة المرتبطة به إلا محلياً. اربط الخدمات الداخلية بـ127.0.0.1 حتى لا تكون مكشوفة أبداً.
هل أحتاج إلى فتح منفذ في الجدار الناري لكي تعمل الخدمة؟
فقط للخدمات التي يجب الوصول إليها من أجهزة أخرى. لا تحتاج الخدمة المرتبطة بـ127.0.0.1 إلى قاعدة في الجدار الناري، لأن أي جهة خارجية لا تستطيع الوصول إليها على أي حال. أما الخدمة التي تعمل على 0.0.0.0 أو [::] فتحتاج إلى قاعدة في الجدار الناري للسماح بحركة المرور، ويجب منعها افتراضياً إلى أن تضيف القاعدة المناسبة.
ما الفرق بين منفذ TCP ومنفذ UDP؟
يعتمد TCP على الاتصالات، وتستخدمه معظم الخدمات، مثل SSH وخوادم الويب وقواعد البيانات. أما UDP فلا يعتمد على الاتصالات، وتستخدمه DNS وبعض شبكات VPN. الرقم نفسه في TCP وUDP يشير إلى منفذين منفصلين، لذلك فإن 53/tcp و53/udp مختلفان. عند كتابة قواعد الجدار الناري، حدّد البروتوكول، مثل 22/tcp.