SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-21

كيف تعرف أن منفذًا مفتوح على Linux؟

تعرّف إلى ما يستمع فعلاً باستخدام ss، ثم اختبر المنفذ من الخارج عبر nc أو nmap. افهم لماذا يتعطل المنفذ المحجوب، بينما يرفض المغلق فورًا.

تحقّق من فتح منفذ على Linux: حدّد السؤال الصحيح أولاً

للتحقّق من فتح منفذ على Linux، حدّد أولاً السؤال الذي تطرحه، لأنّ معنى «مفتوح» يختلف باختلاف موضع التحقّق. على الخادم نفسه، يعني الفتح أنّ عملية مرتبطة بذلك المنفذ وتنتظر الاتصالات. من جهاز آخر، يعني الفتح أنّ حزمة تصل إلى تلك العملية وتتلقى رداً منها. وعندما لا يعود أي رد، يصبح السؤال الفعلي هو: أي جهاز أسقط الحزمة؟ يجيب sudo ss -ltnp عن السؤال الأول. ويجيب nc -z أو nmap عن السؤال الثاني. أما عدادات جدار الحماية وtcpdump فتجيب عن السؤال الثالث.

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

ما الذي يستمع على هذا الخادم؟ اقرأ مخرجات ss

تأتي ss مع iproute2، ولذلك فهي موجودة في كل توزيعة حالية. أما netstat فتأتي مع net-tools، ولم تعد Ubuntu تثبّتها افتراضياً منذ سنوات، لذلك تجيب netstat -tulpn غالباً عن netstat: command not found. تعلّم ss وتجنب هذه النتيجة المخيبة.

sudo ss -ltnp

تعرض -l المقابس التي تستمع فقط. وتقيّد -t القائمة بـTCP. وتطبع -n الأرقام بدلاً من محاولة حل الأسماء، لذلك يعرض الأمر النتيجة فوراً. وتعرض -p العملية المالكة، وهي تحتاج إلى root؛ ومن دون sudo يكون عمود Process فارغاً لكل عملية لا تملكها. استبدل -t بـ-u لعرض UDP.

State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
LISTEN 0      4096   127.0.0.53%lo:53    0.0.0.0:*   users:(("systemd-resolve",pid=612,fd=14))
LISTEN 0      128    0.0.0.0:22          0.0.0.0:*   users:(("sshd",pid=921,fd=3))
LISTEN 0      511    127.0.0.1:8080      0.0.0.0:*   users:(("node",pid=1442,fd=19))
LISTEN 0      128    [::]:22             [::]:*      users:(("sshd",pid=921,fd=4))

يحدّد عمود Local Address كل شيء، وهو العمود الذي يتجاوزه الناس سريعاً عند القراءة.

  • تعني 0.0.0.0:22 كل عناوين IPv4 على الجهاز، ولذلك يمكن الوصول إليها من الخارج إذا سمح جدار الحماية بذلك.
  • تعني [::]:22 الشيء نفسه بالنسبة إلى IPv6.
  • تعني 127.0.0.1:8080 loopback فقط. ولا يمكن لأي جهاز خارج هذا الخادم الوصول إليها.
  • تعني 10.20.0.5:5432 عنوان واجهة واحداً دون غيره، وهذا شائع في إعدادات الشبكات الخاصة.
  • يكون عمود Process الفارغ عادةً بسبب غياب sudo، وليس بسبب غياب العملية.

للاستعلام عن منفذ واحد، صفِّ النتائج داخل ss بدلاً من استخدام grep على القائمة بأكملها:

sudo ss -ltnp 'sport = :8080'
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
sudo fuser 8080/tcp

تعني النتيجة الفارغة من الأوامر الثلاثة أن لا شيء يشغل ذلك المنفذ. قد تكون الخدمة متوقفة، أو فشلت في البدء، أو تستمع في مكان آخر. اقرأ systemctl status <unit> وjournalctl -u <unit> -n 50 قبل أن تغيّر قاعدة واحدة في جدار الحماية.

لماذا يكلّفك استخدام 127.0.0.1 في Local Address ساعات من العمل

لا يمكن الوصول إلى socket المرتبط بـ 127.0.0.1 من مضيف آخر، ولا تغيّر أي قاعدة جدار ناري ذلك. يوجّه kernel العنوان 127.0.0.0/8 إلى واجهة loopback فقط، وتُسقط أي حزمة تحمل عنوان الوجهة هذا عند وصولها عبر بطاقة شبكة فعلية باعتبارها حزمة غير صالحة. لذلك تعمل العملية، ويعرض ss أنها تستمع، ويُبلغ ufw allow 8080 عن نجاح، لكن الاتصال من حاسوبك المحمول يظل يفشل. ويفشل فوراً مع Connection refused، لأن الحزمة تصل إلى عنوانك العام، ولا تجد socket مرتبطاً به، فيرسل kernel إعادة ضبط TCP.

ترتبط برامج كثيرة بـloopback عمداً، ويكون ذلك الإعداد الافتراضي الصحيح لقاعدة بيانات أو واجهة إدارية. لديك خياران واضحان. غيّر عنوان الارتباط في إعدادات البرنامج نفسه (listen_addresses في postgresql.conf، وbind في redis.conf، أو وسيطة المضيف التي يقبلها تطبيقك)، ثم افتح المنفذ في الجدار الناري. أو اتركه على loopback، ووصل إليه عبر مكوّن آخر، مثل reverse proxy باستخدام nginx، أو نفق SSH من حاسوبك المحمول:

ssh -L 8080:127.0.0.1:8080 user@203.0.113.10

يحافظ Docker على التمييز نفسه في publish flag. يربط -p 8080:8080 بـ0.0.0.0 ويعرّض الحاوية للإنترنت. ويربط -p 127.0.0.1:8080:8080 بـloopback ويبقيها محلية.

كيفية التحقق من أن منفذًا مفتوح على Linux من جهاز آخر

نفّذ هذا الاختبار من شبكة مختلفة. يثبت الاختبار من الخادم أن مسار loopback يعمل فقط. وحتى الاتصال بعنوان IP العام الخاص بك من الخادم يتجاوز جدار الشبكة لدى مزود الخدمة، لأن هذا المرشح يعمل خارج VPS.

nc -zv -w 3 203.0.113.10 443

يتصل -z ثم يغلق الاتصال من دون إرسال بيانات. يتوقف -w 3 عن المحاولة بعد ثلاث ثوانٍ، وهذا الخيار مهم: من دون مهلة، تترك حزمة مُسقطة العميل يعيد محاولة SYN لأكثر من دقيقتين قبل أن توقف النواة ذلك. تكون النتيجة الناجحة كما يلي:

Connection to 203.0.113.10 443 port [tcp/https] succeeded!

إذا كانت الأداة غير موجودة (nc: command not found)، ثبّت netcat-openbsd على Debian أو Ubuntu، أو استخدم إعادة توجيه الشبكة المضمّنة في bash، التي لا تحتاج إلى أي حزمة:

timeout 3 bash -c '</dev/tcp/203.0.113.10/443' && echo open || echo "no answer"

هذه الصيغة من ميزات bash، لذلك شغّلها باستخدام bash. أما /bin/sh على Debian وUbuntu فهو dash، ولا يدعم /dev/tcp، ويُبلغ بأن المسار غير موجود. لفحص نطاق من المنافذ، أو عندما تريد عرض الحالة باسمها، استخدم nmap مع المضيفين الذين تتحمل مسؤوليتهم:

sudo nmap -Pn -p 22,80,443 203.0.113.10
sudo nmap -Pn -p 1-1024 203.0.113.10

يتجاوز -Pn اكتشاف المضيف. تحجب معظم خوادم VPS طلبات ICMP echo، لذلك يقرر nmap، من دون -Pn، أن المضيف متوقف ولا يفحص أي شيء. يطبع nmap open عندما يجيب شيء ما ويقبل الاتصال، وclosed عندما يجيب شيء ما بإعادة ضبط الاتصال، وfiltered عندما لا يجيب أي شيء على الإطلاق. بالنسبة إلى خدمة ويب، يفصل curl -sS -o /dev/null -w '%{http_code}\n' https://example.com بين عطل في الشبكة وعطل في التطبيق، لأن رمز الحالة يثبت أن المسار بأكمله عمل.

لماذا يعلّق المنفذ المحظور ويرفض المنفذ المغلق فوراً

رفض فوري. وصلت الحزمة إلى الجهاز، وردّ عليها شيء ما.

nc: connect to 203.0.113.10 port 443 (tcp) failed: Connection refused

ينتج هذا السطر نفسه عن سببين مختلفين. إما ألا تكون هناك عملية مرتبطة بذلك العنوان والمنفذ، فيرد kernel بإعادة ضبط TCP، أو تكون قاعدة جدار ناري قد رفضت الحزمة بإعادة ضبط أو برسالة ICMP تفيد بأن المنفذ غير قابل للوصول. الرفض إجابة مؤكدة، ويعود خلال دورة اتصال واحدة.

توقّف مؤقت، ثم انتهاء مهلة. أسقط شيء ما الحزمة ولم يرسل أي رد.

nc: connect to 203.0.113.10 port 443 (tcp) timed out: Operation now in progress

هذا ما تفعله قاعدة DROP، وكذلك جدار ناري لدى مزود الخدمة أو security group سحابية. الصمت هو علامة الإسقاط، لأن المرسل لا يستطيع التمييز بين إسقاط الحزمة وتوقف المضيف عن العمل.

تحدد الأعراض موضع الفحص التالي. تعني حالة الرفض أن الحزم تعبر الشبكة بشكل سليم، لذا ارجع إلى ss -ltnp وتحقق من عنوان الربط ورقم المنفذ. وتعني حالة انتهاء المهلة أن الحزم تُسقط، لذا افحص الجدران النارية من الخارج إلى الداخل. يشرح الفرق بين الرفض وانتهاء المهلة في SSH هذا التقسيم نفسه للمنفذ 22، وهو الموضع الذي يواجهه معظم الأشخاص.

يوفّر ufw السلوكين عمداً: إذ تسقط ufw deny 8080 الحزمة، بينما ترسل ufw reject 8080 رفضاً. في nftables، الهدفان هما drop وreject، وفي iptables هما -j DROP و-j REJECT. تكون السياسات الافتراضية في الغالب إسقاطاً، ولذلك تؤدي قاعدة مفقودة إلى تعليق الاتصال بدلاً من ظهور رسالة خطأ.

من يحظر المنفذ؟ اعمل من الخارج إلى الداخل

sudo ufw status verbose
sudo iptables -L INPUT -n -v --line-numbers
sudo nft list ruleset

تُعدّ عدادات -v الجزء المفيد. شغّل اختبار nc من الخارج، ثم شغّل أمر iptables مرة أخرى، وابحث عن العداد الذي تغيّر: فالقاعدة التي يزداد عدد حزمها هي القاعدة التي تتعامل مع حركة الشبكة الواردة منك. وبذلك تستبدل التخمين بالأدلة.

يُجرى الاختبار الحاسم على الخادم، مع مراقبة الشبكة أثناء اتصالك من الخارج:

sudo tcpdump -ni any tcp port 8080

يعني وصول SYN من دون عودة SYN-ACK أن الحزمة وصلت إلى VPS وأن المضيف أسقطها. وهذا يعني أن جدار الحماية لدى المزوّد يعمل، بينما لا تعمل قواعدك المحلية كما ينبغي. أما عدم ظهور أي مخرجات، فيعني أن الحزمة لم تصل أصلاً. وفي هذه الحالة يكون السبب هو جدار الحماية لدى المزوّد، أو security group، أو عنوان IP غير صحيح. يزيل هذا التفريق وحده معظم العمل.

قد تنتج طبقتان نتائج تبدو غير منطقية. الأولى هي IPv6: إذا كان لاسم المضيف سجل AAAA، فقد يتصل العميل عبر IPv6 بينما تغطي القاعدة IPv4 فقط. لذلك اختبر كل عائلة باستخدام nc -4 وnc -6 قبل أن تعتمد أياً من النتيجتين. يشرح قواعد ufw ومنافذ IPv6 على VPS هذا التعارض. والثانية هي Docker: يستجيب منفذ حاوية منشور من الإنترنت حتى عندما يعرض ufw status أن هذا المنفذ محظور، لأن هذه الحزم تُعالَج قبل أن تراها سلسلة ufw أصلاً. يشرح سبب نشر Docker للمنافذ مباشرةً متجاوزاً ufw الآلية وطريقة الإصلاح، بينما يقدّم قواعد ufw التي يجب ضبطها على VPS جديد مجموعة القواعد الأساسية التي يجدر بك إعدادها أولاً.

لماذا تكون إجابات UDP ملتبسة بحكم التصميم

لا يستخدم UDP مصافحة، لذلك لا يوجد شيء يمكن أن ينجح فيه الاختبار الاستكشافي. يخرج nc -zu 203.0.113.10 53 بحالة 0 فور مغادرة الحزمة، وهذا يثبت أن جهازك أرسلها، ولا يثبت شيئاً عن الطرف البعيد. عندما يكون منفذ UDP مغلقاً، يرد المضيف عادةً برسالة ICMP تفيد بعدم إمكانية الوصول إلى المنفذ، ولا تُبلِّغ النواة المقبس المتصل بهذا الخطأ إلا عند عملية الكتابة التالية، لذلك قد يفوّت اختبار يرسل حزمة واحدة هذه الرسالة. وتحجب الجدران النارية رسائل ICMP عادةً، ما يزيل حتى هذا المؤشر. لذلك يعرض nmap الحالة open|filtered لمعظم منافذ UDP: فعدم وصول أي رد هو النتيجة نفسها التي ينتجها كل من خدمة مفتوحة لا ترسل رداً ومنفذ محجوب.

اختبر UDP باستخدام البروتوكول الذي تريد التحقق منه. يجيب خادم DNS على dig +short @203.0.113.10 example.com بعنوان أو من دون رد. ويعرض طرف WireGuard سطراً حديثاً يتضمن latest handshake في sudo wg show. ثم أثبت وصول الحزم من جانب الخادم:

sudo tcpdump -ni any udp port 51820

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

قائمة تحقق مرتبة بالطريقة التي تحدد العطل بأسرع وقت

  1. على الخادم، شغّل sudo ss -ltnp 'sport = :8080'. عدم ظهور أي مخرجات يعني أنه لا توجد خدمة تستمع، لذا أصلح الخدمة أولاً.
  2. عند ظهور مخرجات، اقرأ عمود Local Address. يعني 127.0.0.1 أن الوصول من خارج الخادم مستحيل إلى أن تعيد ربط الخدمة أو تضع proxy أمامها.
  3. من شبكة أخرى، شغّل nc -zv -w 3 <public ip> 8080.
  4. تعيدك حالة الرفض إلى الخطوة 1. العنوان أو المنفذ أو الجهاز ليس ما تظنه.
  5. تعني مهلة الانتظار إسقاط الحزم. شغّل sudo tcpdump -ni any tcp port 8080 على الخادم وأعد الاختبار.
  6. تصل حزمة SYN ولا يعود أي رد: المشكلة في جدار حماية المضيف. ابحث عن القاعدة التي يتحرك عدادها في sudo iptables -L INPUT -n -v.
  7. لا تصل حزمة SYN: المشكلة في جدار حماية مزود الخدمة، أو security group، أو عنوان IP غير صحيح.

FAQ

كيف أتحقق من المنافذ المفتوحة على خادم Linux الخاص بي؟

شغّل sudo ss -ltnp لمنافذ TCP وsudo ss -lunp لمنافذ UDP. يمثّل كل سطر مقبساً واحداً في وضع الاستماع. يوضح عمود Local Address الجهات التي يمكنها الوصول إليه: يقبل 0.0.0.0 و[::] الاتصالات من أي مكان يسمح به جدار الحماية، بينما يقبل 127.0.0.1 الاتصالات من الجهاز نفسه فقط. يتطلب عمود Process صلاحيات root، لذلك شغّله باستخدام sudo، وإلا فسيظهر فارغاً. يُعد ss جزءاً من iproute2، ويكون مثبتاً دائماً. أما netstat فهو جزء من net-tools، ولا يكون مثبتاً عادةً.

لماذا يعرض ss خدمتي في وضع الاستماع، مع أنني لا أستطيع الاتصال بها؟

هناك سببان شائعان، ويفصل بينهما أمر واحد. إذا كان Local Address هو 127.0.0.1، فالخدمة مرتبطة بواجهة loopback ولا يمكن الوصول إليها من أي مضيف آخر، لأن kernel يوجّه هذا النطاق إلى واجهة loopback فقط. إذا كان 0.0.0.0 وما زالت الاتصالات تفشل، فشغّل sudo tcpdump -ni any tcp port <port> على الخادم، ثم اتصل من خارج الخادم. يعني وصول SYN دون رد أن قاعدة في جدار الحماية المحلي تسقط الحزمة. أما عدم وصول أي حزمة فيعني أنها أُوقفت قبل وصولها إلى VPS، وعادةً يكون السبب جدار حماية لدى المزوّد أو security group.

ما الفرق بين اتصال مرفوض واتصال تنتهي مهلته؟

الرفض هو رد. وصلت الحزمة إلى المضيف، فعاد TCP reset أو ICMP port unreachable. يعني ذلك أنه لا توجد خدمة في وضع الاستماع على ذلك العنوان والمنفذ، أو أن قاعدة ما رفضت الاتصال. أما انتهاء المهلة فهو صمت: أسقطت قاعدة الحزمة دون إرسال رد، لذلك يعيد العميل المحاولة حتى يتوقف. يوجّهك الرفض إلى الخدمة وعنوان الربط الخاص بها. أما انتهاء المهلة فيوجّهك إلى جدار الحماية، ويجب أن تبدأ بفحص جدار الحماية الأقرب إلى الخارج.

كيف أتحقق من أن منفذ UDP مفتوح؟

لا يمكنك الحصول على إجابة موثوقة بنعم باستخدام فحص عام، لأن UDP لا يستخدم مصافحة، ولأن الخدمة الصامتة تبدو مثل الحزمة التي أسقطها جدار الحماية. يعيد nc -zu نجاحاً بمجرد أن يرسل الحزمة، ويعرض nmap open|filtered للسبب نفسه. اختبر المنفذ باستخدام البروتوكول نفسه بدلاً من ذلك: استخدم dig +short @<host> example.com لـDNS، أو sudo wg show لنظير WireGuard يملك مصافحة حديثة. ولإثبات وصول الحزم، شغّل sudo tcpdump -ni any udp port <port> على الخادم أثناء إرسال العميل.

هل ما زلت أستطيع استخدام telnet host port لاختبار منفذ؟

يعمل ذلك مع TCP، ويعني Escape character is '^]' أن الاتصال قُبل. اخرج منه باستخدام Ctrl+]، ثم quit. هناك سببان يجعلان nc -z الأداة الأفضل: لا يكون telnet مثبتاً في معظم صور الخوادم الحالية، بينما يتيح nc تحديد مهلة باستخدام -w، ويضبط exit status يمكن اختباره في script. وعندما لا تتوفر أي منهما، لا يحتاج timeout 3 bash -c '</dev/tcp/<host>/<port>' إلى تثبيت أي package.