SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-09-04

تغيير منفذ SSH مع SELinux وfirewalld على Rocky Linux

غيّر منفذ SSH بأمان على Rocky Linux أو AlmaLinux: افتح firewalld، أضف تسمية SELinux باستخدام semanage، ثم عدّل sshd_config بالترتيب الصحيح.

لماذا يتطلب تغيير منفذ SSH ثلاث خطوات هنا

لتغيير منفذ SSH على Rocky Linux أو AlmaLinux أو CentOS Stream أو Fedora، لا يكفي تعديل واحد. تتحكم ثلاثة أنظمة منفصلة في إمكانية نجاح الاتصال عبر المنفذ الجديد. يحدد firewalld ما إذا كانت الحزمة ستصل إلى الجهاز. ويحدد SELinux ما إذا كان مسموحاً لـ sshd بالارتباط برقم المنفذ هذا أصلاً. ويحدد sshd_config المنفذ الذي يطلبه البرنامج الخدمي. إذا تخطيت خطوة SELinux، يرفض البرنامج الخدمي بدء التشغيل. وإذا تخطيت خطوة firewalld، فسيبدأ البرنامج الخدمي ويستمع إلى المنفذ، لكن لن يتمكن أي شخص من الوصول إليه.

في Ubuntu، تتطلب العملية نفسها تعديلاً واحداً وإعادة تشغيل، لأن Ubuntu يستخدم AppArmor بدلاً من SELinux، ولا يأتي معه ملف تعريف يقيّد المنافذ التي يمكن لـ sshd الارتباط بها. إذا كان ufw قيد التشغيل هناك، فأضف قاعدة واحدة. هذا هو الفرق بالكامل. تأتي عائلة RHEL مع firewalld قيد التشغيل وSELinux في وضع enforcing عند التثبيت الجديد، وكلاهما يتعامل مع أرقام المنافذ.

نفّذ الخطوات بالترتيب التالي، وستبقى جلستك الحالية متصلة طوال العملية:

  1. افتح المنفذ الجديد في firewalld، واترك المنفذ 22 مفتوحاً في الوقت الحالي.
  2. أضف تسمية SELinux للمنفذ الجديد باستخدام semanage.
  3. اضبط المنفذ في إعدادات sshd.
  4. أعد تشغيل sshd، ثم سجّل الدخول عبر المنفذ الجديد من طرفية ثانية قبل إغلاق الطرفية الأولى.
اعثر على وحدة التحكم على الويب التي يوفرها مزود الخدمة (VNC أو serial) قبل البدء، وتحقق من إمكانية تسجيل الدخول إليها. ستكون وحدة التحكم هذه وسيلتك للعودة إلى الخادم إذا حدث خطأ في التغيير. يُعد تغيير المنفذ أحد أكثر الأسباب شيوعاً لفقدان المستأجر إمكانية الوصول إلى خادم دفع تكلفته للتو.

أولاً، ثبّت semanage

semanage هي الأداة التي تعدّل إعدادات سياسة SELinux، ولا تتضمنها عملية التثبيت الدنيا لـ Rocky Linux أو AlmaLinux. توجد هذه الأداة في policycoreutils-python-utils.

sudo dnf install -y policycoreutils-python-utils

يؤدي تشغيل الأمر قبل تثبيت تلك الحزمة إلى ظهور sudo: semanage: command not found. عند هذه النقطة، يعتقد كثير من القراء أن SELinux غير مثبّت ويتجاوزون هذه الخطوة. SELinux مثبّت بالفعل. الأداة الإدارية فقط هي المفقودة. إذا كانت صيغة dnf جديدة عليك، فستعيد المكافئات بين أوامر dnf وapt ربطها بما تعرفه بالفعل.

اختر منفذاً وتحقق من عدم استخدام أي خدمة له

يكفي استخدام أي منفذ TCP متاح بين 1024 و65535. أجرِ فحصين قبل اعتماده:

sudo ss -tlnp | grep -w 2222
sudo semanage port -l | grep -w 2222

يوضح الفحص الأول ما إذا كانت هناك عملية تستمع على هذا الرقم. ويوضح الفحص الثاني ما إذا كانت سياسة SELinux قد خصصته مسبقاً لنوع خدمة آخر. لا يعرض المنفذ المتاح أي نتيجة في أي من الفحصين. إذا كانت السياسة قد خصصته مسبقاً، فسيفشل semanage port -a في الخطوة 2 مع ValueError: Port tcp/2222 already defined، والحل هو اختيار رقم مختلف.

يُستخدم 2222 مثالاً في هذا الدليل. وهو أيضاً أول منفذ يفحصه برنامج المسح بعد 22، لذلك اختر رقماً أقل وضوحاً على خادم فعلي.

الخطوة 1: فتح المنفذ في firewalld

sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports

يكتب --permanent القاعدة في ملف المنطقة على القرص، ولا يغيّر جدار الحماية قيد التشغيل. ويحمّل --reload الإعدادات الموجودة على القرص إلى جدار الحماية قيد التشغيل. إذا تخطيت إعادة التحميل، فستوجد القاعدة لكنها لن تؤثر في شيء حتى يُعاد تشغيل firewalld. وهذه من أكثر الطرق شيوعاً التي تجعل الإجراء بأكمله يبدو وكأنه فشل بلا سبب.

اترك إدخال الخدمة ssh كما هو الآن. فهذا الإدخال هو الذي يُبقي المنفذ 22 مفتوحاً، وهو وسيلة الرجوع الاحتياطية أثناء الاختبار.

تحقق أيضاً من لوحة تحكم موفّر الخدمة. يشغّل العديد من المضيفين جدار حماية للشبكة أمام VPS وخارج نظام التشغيل، لذلك قد يظل المنفذ الذي فتحته في firewalld محجوباً في طبقة الشبكة upstream. يشرح دليل أساسيات firewalld لـVPS المناطق والفصل بين الإعدادات المؤقتة والدائمة إذا كان هذا النموذج جديداً عليك.

الخطوة 2: ضع تسمية للمنفذ في SELinux

sudo semanage port -a -t ssh_port_t -p tcp 2222
sudo semanage port -l | grep ssh_port_t

يضيف -a تعييناً جديداً للمنفذ. ويمثل -t ssh_port_t النوع الذي تحمله منافذ SSH. يسرد الأمر الثاني كل ما يشمله ssh_port_t الآن، ولذلك يمكنك التأكد من إضافة رقم المنفذ قبل تعديل الخدمة.

لماذا يحظر SELinux المنفذ أصلاً

يمنح SELinux (Linux المحسّن أمنياً) كل كائن في النظام تسمية، وتُعد أرقام منافذ TCP كائنات مثل غيرها. يعمل برنامج SSH الخفي ضمن نطاق مقيّد يُسمى sshd_t. تسمح السياسة لـ sshd_t بربط منافذ TCP الموسومة بـ ssh_port_t، والمنفذ الوحيد الذي يحمل هذه التسمية افتراضياً هو 22. عندما تطلب من البرنامج الخفي الربط بالمنفذ 2222، تتحقق النواة من التسمية، وتجد النوع العام الذي عيّنته السياسة لذلك الرقم، ثم ترفض إذن name_bind على المقبس.

لهذا لا يبدو هذا الفشل كمشكلة في جدار الحماية. ترفض النواة الطلب قبل إنشاء أي مقبس للاستماع، لذلك يسجل sshd الخطأ ويخرج. أما مشكلة جدار الحماية فهي العكس: يكون البرنامج الخفي قيد التشغيل وسليماً، ثم تُسقط الحزم أثناء دخولها.

يخبرك getenforce بالوضع الذي يعمل به الخادم. في Permissive، يُسجَّل الرفض لكن لا يُطبَّق، لذلك يبدو تغيير المنفذ ناجحاً ثم يتعطل عندما يشغّل أحدهم setenforce 1 أو يعيد الخادم التشغيل في وضع الفرض. ضع تسمية للمنفذ في كلتا الحالتين. يشرح دليل أساسيات SELinux للخوادم الأوضاع والسياقات والقيم المنطقية بالتفصيل. المنافذ ليست الكائنات الوحيدة التي تتأثر بذلك؛ فالسياسة نفسها تمنع حاوية من قراءة دليل مضيف مركّب إلى أن يُعاد وضع تسمية للمسار، ولهذا تتضمن إرشادات تثبيت Docker على Rocky Linux أو AlmaLinux خطوة خاصة بـSELinux لا تذكرها إرشادات Ubuntu.

الخطوة 3: عيّن المنفذ في إعدادات sshd

في Rocky Linux 9 و10، وAlmaLinux 9 و10، وإصدارات Fedora الحالية، يبدأ /etc/ssh/sshd_config بسطر include، لذلك يكون ملف drop-in هو المكان المنظم لإجراء التغيير. لن تتعارض تحديثات الحزمة مع تعديلاتك بعد ذلك.

grep -n '^Include' /etc/ssh/sshd_config
echo 'Port 2222' | sudo tee /etc/ssh/sshd_config.d/10-port.conf
sudo sshd -t

إذا لم يعثر grep على سطر Include، وهذا هو الحال في Rocky Linux 8 والصور الأقدم الأخرى، فأضف Port 2222 مباشرةً إلى /etc/ssh/sshd_config بدلاً من ذلك. يحلل sshd -t الإعداد بالكامل، بما في ذلك ملفات drop-in، ويُبلغ عن أخطاء الصياغة. أصلح كل ما يُبلغ عنه قبل إعادة التشغيل، لأن تعذر تحليل الإعداد يعني أن daemon لن يعود إلى العمل.

قد يظهر Port أكثر من مرة، ويستمع sshd إلى كل منفذ مُدرج. إن إبقاء Port 22 إلى جانب Port 2222 خلال اليوم الأول يوفر إجراءً احتياطياً بسيطاً، ما دمت تتذكر إزالته.

هل يبدأ sshd بواسطة وحدة socket؟

تبدأ بعض الصور تشغيل SSH من خلال تنشيط socket في systemd بدلاً من تشغيله كخدمة طويلة الأمد. عند إعداد التشغيل بهذه الطريقة، يتولى systemd مقبس الاستماع ويمرر الاتصالات إلى sshd، لذلك يُتجاهل السطر Port في sshd_config بالكامل. تحقّق من ذلك قبل إعادة تشغيل أي شيء:

systemctl is-enabled sshd.socket

تعني إجابة enabled أن المنفذ محدد في وحدة socket، وليس في sshd_config:

sudo systemctl edit sshd.socket
[Socket]
ListenStream=
ListenStream=2222

يجب استخدام ListenStream= من دون قيمة. تتراكم القيم عبر ملفات drop-in، ولذلك يستمر socket في الاستماع على 22 بالإضافة إلى 2222 ما لم تُعيّن قيمة فارغة لمسح القائمة أولاً. طبّق التغيير باستخدام sudo systemctl daemon-reload ثم sudo systemctl restart sshd.socket. إذا كانت الوحدة معطّلة أو غير موجودة على خادمك، فلا ينطبق هذا القسم عليك.

الخطوة 4: أعد التشغيل، ثم اختبر من طرفية ثانية

sudo systemctl restart sshd
systemctl status sshd
sudo ss -tlnp | grep sshd

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

ssh -p 2222 youruser@203.0.113.10

أغلِ الجلسة الأولى فقط بعد نجاح تسجيل الدخول الثاني. إذا لم ينجح، فستظل لديك جلسة shell يمكنك منها التراجع عن كل التغييرات. هذه العادة وحدها هي الفارق بين تغيير يستغرق خمس دقائق وقضاء فترة بعد الظهر أمام وحدة تحكم مزوّد الخدمة.

تمييز حظر الجدار الناري عن رفض SELinux

من حاسوبك المحمول، يبدو الفشلان متطابقين تقريباً. لكنهما يبدوان مختلفين تماماً على الخادم.

  • إذا أظهر systemctl status sshd أن الوحدة فشلت، فهذا يعني أن البرنامج الخدمي لم يحصل على socket. السبب خطأ في الإعداد أو رفض من SELinux.
  • إذا كانت الوحدة نشطة وأظهر ss -tlnp أن sshd يستمع على المنفذ الجديد، فالبرنامج الخدمي يعمل، والمشكلة في مسار الشبكة: firewalld، أو الجدار الناري المنفصل لدى المزوّد، أو العنوان والمنفذ اللذان اتصلت بهما.

في حالة SELinux، اقرأ سجل التدقيق بدلاً من التخمين:

sudo ausearch -m AVC -ts recent
sudo journalctl -u sshd -n 50 --no-pager

يسمّي رفض name_bind على الفئة tcp_socket العملية في comm="sshd"، ورقم المنفذ في src=، والتسمية التي يحملها المنفذ فعلياً في tcontext=. هذا الحقل الأخير هو الإجابة. وأي قيمة غير ssh_port_t تعني أن الخطوة 2 لم تُطبَّق على المنفذ الذي تستخدمه، ويكون السبب عادةً خطأً في الرقم أو استخدام البروتوكول الخطأ. ثبّت setroubleshoot-server إذا كنت تفضّل أن يحوّل sealert السجل إلى جملة مفهومة.

تظهر الرسالة التي يكتبها sshd نفسه عندما ترفض النواة عملية الربط بهذا الشكل:

error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.

إن ظهور Permission denied على منفذ أعلى من 1024، حيث لا تحتاج عملية الربط إلى امتيازات root، هو علامة SELinux المميزة. أما Address already in use في السطر نفسه فيشير إلى عطل مختلف: هناك عملية أخرى تشغل المنفذ. من جهة العميل، يميّز الفرق بين رفض الاتصال وانتهاء مهلة الاتصال حالتي الشبكة، لأن الرفض يعني أن الحزمة وصلت إلى المضيف ولم تكن هناك خدمة تستمع، بينما يعني انتهاء المهلة أن شيئاً لم يستجب إطلاقاً.

أغلق المنفذ 22 وحدّث العملاء

بعد نجاح عدة عمليات تسجيل دخول عبر المنفذ الجديد، أزل المنفذ 22:

sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

اترك تسمية SELinux على المنفذ 22 كما هي. تأتي هذه التسمية من السياسة الأساسية، ولا تمنح أي وصول بعد أن يمنع الجدار الناري دخول الحزم.

ثم حدّث إعدادات العملاء، لأن كل أداة افترضت المنفذ الافتراضي تحتاج الآن إلى تحديد المنفذ الجديد لها. أضف الإعداد إلى ~/.ssh/config على جهازك مرة واحدة، بدلاً من كتابة -p في كل مرة:

Host myvps
  HostName 203.0.113.10
  Port 2222
  User youruser

تقرأ scp وsftp وrsync وAnsible هذا الملف. لكن مهام النسخ الاحتياطي وفحوصات المراقبة ونصوص cron التي تحدد المنفذ 22 مباشرة لا تقرأه، لذلك ابحث عنها الآن ما دمت تتذكر تفاصيل التغيير.

ما الذي يحققه تغيير المنفذ وما لا يحققه

يقلل ذلك ضوضاء السجلات. تهاجم أدوات الفحص الآلية المنفذ 22 باستمرار، ونقلك sshd بعيداً عنه يزيل معظم هذه الأسطر من journal، مما يسهل رؤية الأحداث الفعلية. لكنه ليس إجراءً أمنياً. فأي أداة فحص تمسح نطاق المنافذ بالكامل ستعثر على daemon الخاص بك وتقرأ banner الإصدار الخاص به على أي حال. تعامل مع تغيير المنفذ على أنه إجراء تنظيمي، وضع الحماية الفعلية في المصادقة باستخدام المفاتيح فقط مع تعطيل تسجيل الدخول بكلمات المرور، وهو ما يشرحه دليل تقوية SSH لخادم VPS خطوة بخطوة.

يعمل كل ما سبق بالطريقة نفسها على إصداري RHEL المعاد بناؤهما الرئيسيين، لأنهما مبنيان من المصادر نفسها. راجع مقارنة Rocky Linux وAlmaLinux إذا كنت لا تزال تختار بينهما. يوجد سببان لاختيار أحد الإصدارين المتطابقين تقريباً: توقف CentOS عن كونه أحدهما في 2020، وترد القصة كاملة في القصة من Red Hat إلى CentOS ثم إلى Rocky وAlmaLinux. تحقّق من الإصدار الذي حصلت عليه فعلياً قبل اتباع أي دليل أقدم، باستخدام cat /etc/os-release. لا تزال الأدلة المكتوبة لـRocky Linux 8 تحظى بترتيب جيد، وتبقى خطوات semanage وfirewall-cmd فيها صحيحة، لكن Rocky 8 لا يحتوي على سطر include sshd_config.d ولا على socket unit يجب مراعاتها، ولذلك لا يتطابق جزء sshd في تلك الأدلة مع خادم حالي.

يجب إبلاغ fail2ban بالمنفذ الجديد

لا يوجد fail2ban في المستودعات الأساسية. وهو يأتي من EPEL (حزم إضافية لنظام Enterprise Linux):

sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-firewalld

يجعل الحُزْمَة الفرعية fail2ban-firewalld fail2ban يطبّق حالات الحظر عبر firewalld. وهذا هو الخيار المطلوب على خادم يتولى فيه firewalld إدارة مجموعة القواعد.

تضبط jail الافتراضية sshd القيمة port = ssh، ويُحل هذا الاسم عبر /etc/services إلى المنفذ 22. بعد التغيير، تراقب jail منفذاً لا يستهدفه أحد، لذلك لا تحظر أي عنوان بينما تتراكم محاولات تسجيل الدخول الفاشلة على المنفذ 2222. اضبط المنفذ برقمِه في /etc/fail2ban/jail.local:

[sshd]
enabled = true
port = 2222
backend = systemd
maxretry = 5
bantime = 3600

يقرأ backend = systemd حالات الفشل من journal بدلاً من /var/log/secure. وهذا هو الخيار الأكثر أماناً في التثبيتات الدنيا التي قد لا يتوفر فيها rsyslog. شغّلها باستخدام sudo systemctl enable --now fail2ban وافحص jail باستخدام sudo fail2ban-client status sshd. تُستخدم صيغة jail نفسها في إعداد fail2ban لـSSH على Ubuntu 24.04. ويختلف فقط مصدر الحزمة وإجراء الحظر.

التحديثات الأمنية أهم من تغيير المنفذ

الخادم الذي نُقل منفذ SSH فيه، لكنه لم يتلقَّ تحديثات أمنية غير مطبَّقة منذ أربعة أشهر، يكون في حالة أسوأ من خادم يستخدم المنفذ 22 ويثبّت التحديثات تلقائياً كل ليلة. فعّل التحديثات التلقائية في الجلسة نفسها ما دمت تعمل بصلاحيات root: يشرح تفعيل تحديثات dnf التلقائية على Rocky Linux وAlmaLinux إعداد المؤقت والاختيار بين تنزيل التحديثات وتطبيقها. لا تؤدي التحديثات المثبّتة إلى إعادة تشغيل الخدمات التي ما زالت تشغّل الشيفرة القديمة، لذلك يستحق التحقق مما يحتاج إلى إعادة تشغيل أو إعادة إقلاع دقيقة من وقتك كلما تضمّنت دفعة التحديث openssh-server أو مكتبة يرتبط بها.

FAQ

لماذا يفشل sshd في البدء بعد تغيير المنفذ على Rocky Linux؟

غالباً ما يكون السبب هو فقدان تسمية منفذ SELinux. يعمل sshd مقيّداً ضمن النطاق sshd_t، ولا تسمح السياسة له بالربط إلا بالمنافذ التي تحمل تسمية ssh_port_t، وهي المنفذ 22 وحده افتراضياً. يرفض kernel عملية الربط، لذلك يخرج daemon بدلاً من الاستماع، ويحمل journalctl -u sshd سطراً بالصيغة error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.. شغّل sudo semanage port -a -t ssh_port_t -p tcp 2222 مع رقم المنفذ الذي اخترته، ثم أعد تشغيل الخدمة. إذا لم يُعثر على semanage، فثبّت policycoreutils-python-utils أولاً.

هل ما زلت أحتاج إلى semanage إذا كان SELinux في الوضع permissive؟

نعم. في الوضع permissive، يُسجَّل الرفض ويُسمح بعملية الربط على أي حال، لذلك يبدو أن التغيير نجح. لكن التسمية ما تزال مفقودة. وبمجرد تشغيل أي شخص للأمر setenforce 1، أو إقلاع الخادم مع ضبط SELINUX=enforcing في /etc/selinux/config، يتوقف sshd عن البدء على ذلك المنفذ. لا تتطلب إضافة التسمية سوى أمر واحد، وتزيل عطلاً قد يظهر بعد أسابيع من دون سبب واضح.

المنفذ يحمل التسمية وsshd يعمل، فلماذا تنتهي مهلة الاتصال؟

يعني عمل daemon أن SELinux يسمح بالاتصال، ولذلك تُسقط الحزمة أثناء دخولها. افحص sudo firewall-cmd --list-ports بحثاً عن منفذك، وتأكد من تشغيل firewall-cmd --reload بعد قاعدة --permanent، لأن القاعدة الدائمة وحدها لا تُطبَّق على جدار الحماية قيد التشغيل. ثم افحص لوحة التحكم الخاصة بالمضيف بحثاً عن جدار حماية شبكي منفصل أمام VPS. هذه هي النقطة الثانية التي يتعرض فيها المستخدمون للحظر، ولن يعرض أي شيء داخل نظام التشغيل ذلك.

ما المنفذ الذي ينبغي أن أستخدمه بدلاً من 22؟

استخدم أي منفذ TCP متاح من 1024 إلى 65535. تجنب 2222 و22222 على الخادم الفعلي، لأن أدوات الفحص تحاول استخدامهما فوراً بعد 22. تأكد من أن الرقم متاح باستخدام sudo ss -tlnp، وتأكد من أن سياسة SELinux لم تحجزه مسبقاً باستخدام sudo semanage port -l، وتجنب أي منفذ مخصص لخدمة قد تثبتها لاحقاً. لا بأس باختيار رقم مرتفع يصعب تذكره، لأنك ستكتبه مرة واحدة في ~/.ssh/config ولن تضطر إلى إدخاله مجدداً.