لماذا تستضيف Fail2ban ذاتيًا على خادم افتراضي VPS
Fail2ban من أبسط أدوات الحماية وأوسعها انتشارًا لخادم معرَّض: يقرأ سجلاتك باستمرار، ويطبّق تعبيرات نمطية (المرشّحات) لرصد محاولات الاختراق، ويحظر عنوان IP المخالف بإضافته إلى nftables أو iptables لمدة قابلة للضبط. على خادم VPS، يمثّل خط دفاع أول يجب إعداده قبل بقية الأمور، لأنه لا يعتمد على أي خدمة خارجية، ويستهلك القليل، ويحمي SSH من القوة الغاشمة بمجرّد تفعيل الـ jail. وإلى جانب SSH، يمكنك توسيعه ليشمل Nginx (محاولات المصادقة، مسح عناوين URL) و Postfix و WordPress أو أي خدمة تكتب سجلات. يعمل كل شيء محليًا على جهازك: لا تخرج أي بيانات، ولا تتدخّل أي خدمة طرف ثالث. إنه حل مستقل وسهل التدقيق، شريطة أن تتحقّق منه من حين إلى آخر كما سنرى أدناه.
الفوائد الملموسة لهذا القالب
- حظر تلقائي — تُحظر عناوين IP التي تهاجم SSH بالقوة الغاشمة بمجرّد بلوغ العتبة
maxretryضمن نافذةfindtime. - مرشّحات لخدمات عديدة — SSH وNginx وApache وPostfix وWordPress، ومرشّحات مخصّصة تُكتب في
filter.d. - بصمة ضئيلة — يعمل دون مشاكل على أصغر خوادم VPS.
- حظر تصاعدي (التكرار) — كلما عاود عنوان IP المخالفة، طالت مدة الحظر.
- إشعارات بالبريد الإلكتروني — ممكنة عند كل حظر، عبر الإجراءين
action_mwأوaction_mwlمنjail.conf. - مستقل ومحلّي — بلا اعتماد على الشبكة في التشغيل اليومي، سهل التدقيق وإدارة الإصدارات.
المتطلبات المحدّدة بالأرقام لاستضافته
Fail2ban اقتصادي: يكفي لتشغيله خادم VPS بمعالج vCPU واحد و512 ميغابايت من الذاكرة، دون أثر ملحوظ (توصية تحريرية، تُقاس على حمل خادمك). من جهة البرمجيات، يطلب ملف README الأصلي للإصدار 1.1.1 لغة Python 3.5 أو أحدث. ويبقى مكوّنان اختياريان: pyinotify 0.8.3 أو أحدث لمراقبة الملفات (نواة Linux 2.6.13 أو أحدث)، و systemd 204 أو أحدث مع حزمة python-systemd لقراءة السجل (journal). يُثبَّت Fail2ban مباشرةً على النظام (دون حاجة إلى Docker) ويتطلّب صلاحية root، وواجهة خلفية لجدار ناري (nftables أو iptables)، والوصول إلى سجلات الخدمات المراد حمايتها: سجل systemd أو /var/log/auth.log لـ SSH بحسب التوزيعة، وسجلات access و error لـ Nginx. يحتفظ بحالته في قاعدة SQLite هي /var/lib/fail2ban/fail2ban.sqlite3 افتراضيًا. لا يلزم أي نطاق أو منفذ إضافي. القاعدة الذهبية: املأ ignoreip بعنوان IP الخاص بك قبل تفعيل الحظر، كي لا تحبس نفسك خارج خادمك.
تثبيت Fail2ban وإعداده على خادمك VPS
تثبيت Fail2ban
على Debian أو Ubuntu:
sudo apt update && sudo apt install fail2ban. تبدأ الخدمة تلقائيًا. تحقّق باستخدامsudo systemctl status fail2ban.إنشاء ملف jail.local
لا تعدّل
jail.confمباشرةً أبدًا. اكتب إعداداتك في/etc/fail2ban/jail.localالذي يتقدّم عليه: هناك تحدّدbantimeوfindtimeوmaxretryوقبل كل شيءignoreip = 127.0.0.1/8 ::1 VOTRE_IPلحماية نفسك من الحظر الذاتي. القيم الافتراضية فيjail.confهيbantime = 10mوfindtime = 10mوmaxretry = 5.تفعيل حماية SSH
جميع الـ jails معطّلة افتراضيًا في
jail.conf: فعّل[sshd]صراحةً فيjail.localمعenabled = true، وعلى سبيل المثالmaxretry = 3وbantime = 1h. بعد 3 حالات فشل ضمن نافذةfindtime، يُحظر عنوان IP لمدة ساعة على مستوى الجدار الناري.إضافة jail لـ Nginx
فعّل الـ jails المسمّاة
[nginx-http-auth]و[nginx-botsearch]التي يوفّرهاjail.conf، وتأكّد من أنlogpathيشير إلى سجلات Nginx لديك. يحظر ذلك محاولات المصادقة المتكرّرة وعمليات مسح عناوين URL الخبيثة.اختبار الإعداد ثم إعادة تحميله
تحقّق من الصياغة أولًا:
sudo fail2ban-client -t. ثم طبّقه:sudo fail2ban-client reload(أوsudo systemctl restart fail2ban). يسردsudo fail2ban-client statusالـ jails النشطة، ويُظهرsudo fail2ban-client status sshdعناوين IP المحظورة حاليًا.اختبار الحظر وإلغاؤه
تحقّق من المرشّح على سجلك أنت بالأمر
sudo fail2ban-regex systemd-journal sshd. ولمحاكاة حظر دون مهاجمة أحد:sudo fail2ban-client set sshd banip 203.0.113.10، ثم اقرأsudo fail2ban-client status sshd. لتحرير عنوان IP مشروع حُظر بالخطأ:sudo fail2ban-client set sshd unbanip X.X.X.X.أول تسجيل دخول
لا توجد واجهة ويب ولا حساب يجب إنشاؤه: fail2ban خدمة نظام تحظر، بإعداد القالب، عناوين IP بعد 4 محاولات SSH فاشلة خلال 10 دقائق. عبر SSH:
fail2ban-client status sshd(العناوين المحظورة)، وfail2ban-client set sshd unbanip <IP>(رفع الحظر). اضبط هذه العتبات فيjail.local.
ignoreip ومدة الحظر والمعاودة
يقبل ignoreip عناوين IP أو أقنعة CIDR أو أسماء مضيفين عبر DNS، تفصل بينها مسافات أو فواصل. افتراضيًا ignoreself = true: العناوين المحلية للخادم نفسه لا تُحظر أبدًا، لكن عنوان IP في مكتبك أو منزلك غير مشمول بذلك. وإن كان يتغيّر كثيرًا فاعتمد اسم مضيف ديناميكيًا أو استخدم ignorecommand، وهو أمر خارجي يتلقّى عنوان IP ويجيب هل يجب تجاهله. واحتفظ كذلك بمنفذ طوارئ لا يعتمد على SSH، مثل وحدة تحكّم مزوّد الخادم VPS، فيُعالَج الحظر الذاتي حينئذٍ دون مساعدة خارجية. تُضبط المدة بـ bantime، بالثواني أو باللواحق m و h و d و w و mo و y. وتعمل مدةً أولية حين يكون الحظر التصاعدي مفعّلًا. وللمعاودين، يضمّ jail.conf أيضًا jail اسمه recidive يقرأ سجل fail2ban نفسه.
الحظر التصاعدي: الصيغة والسقف والذاكرة
فعّل الحظر التصاعدي في jail.local بالقيمة bantime.increment = true. تضرب الصيغة الافتراضية bantime في 1 ثم 2 ثم 4 ثم 8 ثم 16 وهكذا عند كل معاودة؛ و bantime.factor (القيمة 1 افتراضيًا) معامل ضرب مشترك، و bantime.maxtime يضع سقفًا للمدة بالثواني، مثلًا bantime.maxtime = 604800 لسبعة أيام. وثمة نقطة كثيرًا ما تُغفل: يجد fail2ban عمليات الحظر السابقة في قاعدة بياناته، التي تُنظَّف وفق dbpurgeage (يوم واحد افتراضيًا في fail2ban.conf). ولكي تُرصد المعاودات المتباعدة، ارفعه؛ ويذكر تعليق الـ jail المسمّى recidive في jail.conf القيمة 648000 ثانية. اقرن ذلك كله بتعطيل المصادقة بكلمة المرور (مفاتيح SSH فقط): عندئذٍ يصبح Fail2ban شبكة أمان بدلًا من أن يكون حصنك الوحيد.
اختيار الـ backend: auto أو pyinotify أو polling أو systemd
الـ backend هو الطريقة التي يقرأ بها الـ jail سجلاته. القيمة الافتراضية في jail.conf هي backend = auto، ويمكن لكل jail تجاوزها. على Debian و Ubuntu، يضبط الملف paths-debian.conf في الأرشيف الأصلي 1.1.1 القيمة sshd_backend = systemd: فيُقرأ sshd عندئذٍ من سجل systemd لا من /var/log/auth.log. اقرأ sudo fail2ban-client status sshd لتعرف ما يُراقَب فعلًا: يدلّ السطر File list على ملفات، ويدلّ السطر Journal matches على سجل systemd. وقد تغيّر التوزيعة هذه القيم، فلا تفترض شيئًا: عايِن. يتم تغيير الـ backend لكل jail على حدة في jail.local، ثم sudo fail2ban-client reload.
الـ backends الأربعة في Fail2ban
مرّر الجدول أفقيًا
| الـ backend | ما يراقبه | ما يجب تذكّره |
|---|---|---|
| auto | ملفات (pyinotify ثم polling)؛ ينتقل إلى systemd إن لم يوجد أي ملف في `logpath` وكان المرشّح يعرّف `journalmatch` | القيمة الافتراضية في `jail.conf` |
| pyinotify | ملفات، عبر أحداث inotify في النواة | Linux فقط، ويتطلّب وحدة Python المسمّاة pyinotify؛ أنسب للملفات من polling بحسب الوثائق |
| polling | ملفات، بإعادة قراءتها على فترات منتظمة | بلا مكتبة خارجية، وهو الحل البديل الأبسط |
| systemd | سجل systemd، عبر python-systemd | `logpath` غير صالح؛ يمرّ المرشّح عبر `journalmatch`؛ إعدادات `journalflags` و `rotated` |
التحقّق من أن الـ jail ما زال يراقب
الـ jail المُشغَّل ليس بالضرورة jail يقرأ. بلاغ مرفوع لم يؤكّده القائمون على الصيانة: في البلاغ رقم 4250 في fail2ban، المفتوح في أكتوبر 2026، يصف مدير نظام على Debian مع fail2ban 1.1.1 حالة jail من نوع sshd بـ backend من نوع systemd يتوقّف عن الحظر بعد يوم إلى يومين من التشغيل، بينما يواصل jail كل من Nginx و Postfix عمله. ويبلغ مديران آخران، كلاهما على FreeBSD بحسب رسائلهما، عن عرَض مشابه مع الـ backend من نوع pyinotify؛ ويقول أحدهما إن الوضع استقرّ بعد الانتقال إلى polling. ونبّه أحد القائمين على الصيانة إلى أن البلاغ الأصلي كان عن الـ backend من نوع systemd، وأن العرَضين قد لا يكونان مرتبطين. ويصف مشارك أخير، على Arch مع الـ backend من نوع systemd، التوقّف نفسه بعد تدوير السجل ويطرح فرضية تخصّ الإعداد rotated: وتبقى غير مؤكّدة. السبب غير ثابت حتى الآن، ولا شيء يسمح بتعميم الأمر على خادمك. أما التحقّق نفسه فيستغرق دقيقة.
التحقّق في أربع خطوات من أن الـ jail ما زال يقرأ
قراءة حالة الـ jail
يعرض
sudo fail2ban-client status sshdالحقلينCurrently failedوTotal failedللمرشّح، وFile listأوJournal matchesللمصدر، ثمCurrently bannedوTotal bannedوBanned IP listللإجراء. دوّن قيمةTotal failed.المقارنة مع السجل
احسب حالات الفشل الفعلية في الفترة نفسها:
sudo journalctl _COMM=sshd --since "1 hour ago" | grep -c "Failed password"، أوsudo grep -c "Failed password" /var/log/auth.logإن كان الـ jail يقرأ هذا الملف. ثم أعد قراءةTotal failed: يُفترض أنه ازداد. قارن الاتجاه لا التساوي التام، لأن عناوين IP الواردة فيignoreipلا تُحتسب.قراءة سجل fail2ban نفسه
sudo tail -n 50 /var/log/fail2ban.log: يكتب الـ jail السليم أسطرFoundثمBan. وتدلّ عدة أيام من أسطرUnbanوحدها، بينما يُظهر سجل المصادقة محاولات، على jail أعمى.إعادة التشغيل وتغيير الـ backend عند الحاجة
يعيد
sudo systemctl restart fail2banتشغيل القراءة؛ ويصف البلاغ عملًا طبيعيًا لمدة يوم إلى يومين بعد كل تشغيل. وبالنسبة إلى jail يقرأ ملفات، فإنbackend = pollingهو الحل البديل الأبسط. جدوِل هذا التحقّق (cron أو أداة مراقبة) بدل الاعتماد على غياب التنبيهات.
استكشاف الأعطال: رسائل الأخطاء الحقيقية
تأتي هذه الرسائل من الشيفرة المصدرية لـ Fail2ban 1.1.1 (العملاء وقارئات الإعداد)؛ ومستوى التسجيل الافتراضي هو INFO. والأمر الذي يُبدأ به واحد في كل حالة: يختبر sudo fail2ban-client -t الإعداد، ويعطي sudo journalctl -u fail2ban بداية القصة.
رسائل الأخطاء الشائعة وعلاجها
Have not found any log file for 'sshd' jail.— لا يشيرlogpathالخاص بالـ jail إلى أي ملف موجود فيفشل التشغيل، إلا معskip_if_nologs = true. ومع الـ backend من نوعauto، ينتقل الـ jail الذي يعرّف مرشّحهjournalmatchإلى systemd بدلًا من ذلك. صحّح المسار أو اضبطbackend = systemd.No file(s) found for glob /var/log/nginx/error.log— نمط فيlogpathلا يطابق شيئًا. تحقّق من الموضع الحقيقي لسجلات Nginx بالأمرls /var/log/nginx.Unable to read the filter 'nginx-xyz'— الاسم المعطى لـfilter =غير موجود فيfilter.d. صحّح الخطأ الإملائي أو أضف ملف المرشّح الخاص بك.Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban running?— لا يجد العميل مقبس الخادم. الخدمة متوقّفة أو معطّلة:sudo systemctl status fail2banثم سجلّها.Permission denied to socket: ... (you must be root)— شُغّل الأمرfail2ban-clientدون الصلاحيات الكافية. أعد تشغيله بـsudo.Unable to contact server. Is it running?— المقبس موجود لكن الخادم لا يستجيب. أعد تشغيل الخدمة ثم اقرأ سجل إقلاعها.[sshd] Journal reader seems to be offline, reopen journal— رصد fail2ban أن قراءته لسجل systemd قد انقطعت (تدوير) فيعيد فتحه. هذه الرسالة من المستوىMSGأي دونINFO: وغيابها من سجل عادي لا يثبت شيئًا، ومن هنا جاء التحقّق في القسم السابق.Error reading line from systemd journal— خطأ قراءة في سجل systemd، يتبعه سبب النظام. تحقّق من صلاحيات الخدمة ومن حالة السجل بالأمرjournalctl --verify.
nftables أو iptables وجدار حماية الخادم VPS والنسخ الاحتياطي
يُختار إجراء الحظر بـ banaction. يقترح jail.conf القيمة iptables-multiport مثالًا معلّقًا؛ ويضبط الملف paths-debian.conf في الأرشيف 1.1.1 القيمتين banaction = nftables و banaction_allports = nftables[type=allports]. وينشئ إجراء nftables افتراضيًا الجدول f2b-table (من عائلة inet) والسلسلة f2b-chain المعلّقة على الدخول بأولوية -1؛ ويعرض sudo nft list table inet f2b-table عناوين IP المحظورة. اختر عائلة واحدة من الإجراءات، هي نفسها المستعملة في بقية جدار الحماية لديك، وإلا بحثت عن قواعدك في الجدول الخطأ. يعمل جدار حماية الخادم VPS في المنبع: يرشّح ما يصل إلى الجهاز، كأن يحصر SSH في عناوينك، بينما يتفاعل Fail2ban مع ما تقوله السجلات. وهما يتكاملان، لكن أبقِ ignoreip متّسقًا مع قواعدك. خلف وكيل (proxy) أو شبكة CDN، تُظهر السجلات عنوان IP الخاص بالوكيل: استعد العنوان الحقيقي قبل الحظر، وإلا حظرت الوكيل. أما النسخ الاحتياطي، فأرشِف الإعداد (sudo tar czf fail2ban-config.tar.gz /etc/fail2ban) ومخرجات sudo fail2ban-client --dp التي توثّق الإعداد الفعلي. وتحتفظ قاعدة /var/lib/fail2ban/fail2ban.sqlite3 بذاكرة عمليات الحظر.
الوثائق الرسمية
للإعداد المتقدّم والخيارات الخاصة بالأداة وتغييرات الإصدارات، ارجع إلى الوثائق الرسمية لـ Fail2Ban. يغطّي هذا الدليل النشر على خادم ServOrbit VPS؛ وتبقى وثائق الناشر المرجع للضبط الدقيق.