Fail2ban מדריך מלא 2026: הגנה על שרתי לינוקס מפני התקפות brute force

מדריך Fail2ban 2026 מעשי לאדמינים: התקנה, קונפיגורציה ב-jail.local, שילוב עם nftables ו-firewalld, פילטרים מותאמים ל-Nginx, Postfix ו-WordPress, ופתרון תקלות.

Fail2ban 2026: מדריך הקשחת לינוקס

עודכן: 14 ביולי 2026

Fail2ban הוא כלי הגנה בקוד פתוח שסורק קבצי לוג של שירותי לינוקס ומוסיף חוקי חסימה זמניים בחומת האש כנגד כתובות IP שמייצרות ניסיונות התחברות כושלים חוזרים, מהתקפות brute force על SSH ועד סריקות זדוניות על Nginx, Postfix ו-WordPress. אני מתקין אותו כשירות שני על כל שרת חדש (מיד אחרי הידוק sshd), פשוט כי הרעש בלוגים בלעדיו הוא בלתי נסבל. במדריך המעשי הזה של 2026 תלמדו להתקין את Fail2ban 1.1.x, להגדיר jail.local נכון, לשלב אותו עם nftables ו-firewalld, לכתוב פילטרים מותאמים, ולפתור את הבעיות הנפוצות ביותר בגרסאות המודרניות של אובונטו 24.04, Debian 12 ו-Rocky Linux 9.

  • Fail2ban 1.1.0 (יולי 2024) מציג תמיכה מלאה ב-nftables, IPv6 משופר ו-backend של systemd journal כברירת מחדל בהפצות מודרניות.
  • הקובץ הקריטי היחיד שאתם צריכים לערוך הוא /etc/fail2ban/jail.local. לעולם לא jail.conf, שנדרס בעת עדכון החבילה.
  • עבור SSH מומלץ maxretry=3, findtime=10m ו-bantime=1h, עם bantime.increment=true כדי להעניש חוזרים אגרסיביים.
  • שילוב עם nftables באמצעות banaction=nftables-multiport הוא כיום ההמלצה הרשמית, ו-iptables נחשב legacy.
  • פילטרים מותאמים אישית ב-/etc/fail2ban/filter.d/ מאפשרים הגנה על Nginx, WordPress, Postfix, Docker registry וכל שירות שכותב ללוג טקסטואלי.
  • CrowdSec מהווה אלטרנטיבה מודרנית עם קהילת איומים גלובלית, אך Fail2ban עדיין דומיננטי בזכות קלות ההגדרה ותאימות אחורה.

מה זה Fail2ban וכיצד הוא עובד?

בקצרה: Fail2ban הוא daemon כתוב בפייתון שרץ ברקע ומעקב אחר קבצי לוג (או journal של systemd) בזמן אמת. עבור כל שורת לוג שמתאימה לביטוי רגולרי (regex) שהוגדר בפילטר, Fail2ban מעלה מונה עבור כתובת ה-IP המקורית. כאשר המונה עובר את maxretry בתוך חלון זמן של findtime, ה-daemon מפעיל action, בדרך כלל הוספת חוק DROP בחומת האש, למשך bantime.

הארכיטקטורה מבוססת על ארבע ישויות:

  • Jail: הגדרה משולבת של פילטר, אקשן, מקור לוג ופרמטרים כמו maxretry ו-bantime. לכל שירות מוגן יש jail נפרד (sshd, nginx-http-auth, postfix-sasl וכו').
  • Filter: קובץ ב-/etc/fail2ban/filter.d/ המכיל failregex, כלומר ביטויים רגולריים המזהים כשל התחברות בשורת לוג.
  • Action: קובץ ב-/etc/fail2ban/action.d/ המגדיר איך לחסום ולשחרר IP: iptables, nftables, firewalld, route null, hosts.deny, או קריאה ל-API חיצוני.
  • Backend: מנגנון קריאת הלוג — pyinotify, polling, systemd journal או auto. ב-2026 systemd הוא ברירת המחדל ברוב ההפצות.

גרסת Fail2ban 1.1.0 שיצאה ב-2024 מוסיפה תמיכה נטיבית ב-nftables, שיפורים משמעותיים ב-IPv6 (כולל טווחי /64), ותיקוני ביצועים ב-backend של systemd. ה-wiki הרשמי בגיטהאב הוא מקור התיעוד המעודכן ביותר, ואני ממליץ לעקוב אחריו לפני שאתם מסתמכים על פוסטים ישנים בבלוג. Fail2ban אינו IDS, הוא אמצעי תגובה אוטומטי (reactive) שמשלים IDS כמו OSSEC/Wazuh או פתרונות הקשחה כלליים שסקרנו במדריך הקשחת ליבת לינוקס עם sysctl.

התקנת Fail2ban על אובונטו, Debian ו-Rocky Linux

ההתקנה טריוויאלית כמעט בכל הפצה מודרנית. בדקו שההפצה שלכם מספקת גרסה 1.0.2 ומעלה. אם לא, שקלו התקנה מהמאגר הרשמי ב-GitHub. הנה הפקודות לשלוש ההפצות הנפוצות ביותר:

# Ubuntu 24.04 LTS / Debian 12
sudo apt update
sudo apt install -y fail2ban
fail2ban-server --version   # אמור להחזיר Fail2Ban v1.0.2 או חדש יותר

# Rocky Linux 9 / AlmaLinux 9 / RHEL 9
sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-firewalld
sudo systemctl enable --now fail2ban

# Arch Linux
sudo pacman -S fail2ban

# התקנה מהמקור עבור גרסה 1.1.0
git clone https://github.com/fail2ban/fail2ban.git
cd fail2ban
sudo python3 setup.py install
sudo cp build/fail2ban.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now fail2ban

לאחר ההתקנה בדקו שהשירות חי:

sudo systemctl status fail2ban
sudo fail2ban-client ping    # אמור להחזיר: Server replied: pong
sudo fail2ban-client status  # מציג את כל ה-jails הפעילים

ברוב ההפצות ה-jail היחיד שמופעל מיד לאחר ההתקנה הוא sshd, אם SSH מותקן. זו התנהגות ברירת מחדל הגיונית: היא לוקחת בחשבון את השירות המסוכן ביותר בשרת ציבורי טיפוסי.

הבנת jail.conf, jail.local ומבנה הקבצים

Fail2ban מקבל את הקונפיגורציה שלו מתוך היררכיה של קבצים ב-/etc/fail2ban/. הכלל הזהב: לעולם אל תערכו את jail.conf. עדכון החבילה ידרוס אותו והשינויים שלכם ילכו לאיבוד (למדתי את זה בדרך הקשה אחרי apt upgrade שמחק לי jail שלם). במקום, צרו jail.local שדורס אך ורק את הפרמטרים שאתם רוצים לשנות.

קבצי הליבה

  • /etc/fail2ban/fail2ban.conf: הגדרות ה-daemon עצמו (רמת לוג, socket, pidfile). ב-95% מהמקרים לא נוגעים בו.
  • /etc/fail2ban/jail.conf: הגדרות ברירת מחדל של jails. לקריאה בלבד.
  • /etc/fail2ban/jail.d/*.conf: קבצים ספציפיים ל-jails יחידים (למשל jail.d/sshd.conf).
  • /etc/fail2ban/jail.local: הקובץ שאתם עורכים.
  • /etc/fail2ban/filter.d/: פילטרים (regex) מוכנים ומותאמים.
  • /etc/fail2ban/action.d/: אקשנים (iptables, nftables, firewalld, mail).

שלד jail.local מומלץ ל-2026

# /etc/fail2ban/jail.local
[DEFAULT]
# רשת מקומית וכתובת השרת - אל תחסמו את עצמכם
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16

# חלון זיהוי וזמן חסימה
findtime  = 10m
maxretry  = 5
bantime   = 1h

# חסימה אגרסיבית יותר לחוזרים
bantime.increment = true
bantime.factor    = 2
bantime.maxtime   = 1w

# מקור הלוג - systemd journal בהפצות מודרניות
backend = systemd

# אקשן ברירת מחדל - nftables במקום iptables legacy
banaction        = nftables-multiport
banaction_allports = nftables-allports

# פרוטוקולים לתמיכה ב-IPv4 ו-IPv6
usedns = warn

[sshd]
enabled  = true
port     = ssh
maxretry = 3
findtime = 10m
bantime  = 2h

הפרמטר bantime.increment הוא אחת התוספות הכי חזקות: הוא מכפיל את זמן החסימה בכל פעם שאותו IP חוזר להתחבר לרעה. תוקף שמנסה 100 פעם יימצא חסום לימים או שבועות. שילוב עם bantime.maxtime מבטיח שהחסימה לא תגדל לנצח.

הקשחת SSH עם Fail2ban, קונפיגורציה מומלצת ל-2026

SSH הוא הווקטור מספר אחת להתקפות על שרתים ציבוריים. גם אחרי שהעברתם את השרת לפורט לא סטנדרטי או השבתם password authentication, בוטים ימשיכו להציף את הלוג בניסיונות. Fail2ban מוריד את הרעש הזה ומעניק שכבת הגנה תגובתית.

הנה הקונפיגורציה שאני נוהג לפרוס על שרתי VPS חדשים, כמעט בלי שינויים:

# /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled   = true
port      = 22,2222
filter    = sshd
backend   = systemd
logpath   = %(sshd_log)s
maxretry  = 3
findtime  = 10m
bantime   = 24h
mode      = aggressive

# חסימה בכל הפורטים אחרי maxretry - לא רק SSH
banaction = nftables-allports

# התראה + חסימה
action    = %(action_mwl)s

המצב aggressive מפעיל failregex נוסף שמזהה גם ניסיונות כמו Connection reset by peer, Did not receive identification string וסריקות פורטים אקטיביות. השורה action_mwl שולחת אימייל עם whois ולוג של ה-IP החסום.

שילוב עם sshd_config

Fail2ban הוא רק שכבה אחת. שלבו אותו עם ההקשחות הבאות ב-/etc/ssh/sshd_config:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 20
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers admin deploy
Protocol 2

הקומבינציה של אימות מפתחות בלבד, Fail2ban במצב aggressive וחומת אש nftables מוקשחת חוסמת כמעט לחלוטין את משטח ההתקפה של SSH ברמת השרת.

שילוב Fail2ban עם nftables ו-firewalld

מאז 2020 iptables מוכרז כ-legacy והרוב הגדול של ההפצות עברו ל-nftables. Fail2ban 1.0+ מספק אקשנים נטיביים ל-nftables שאמורים להיות ברירת המחדל שלכם. תיעוד הפקודות עצמן מרוכז ב-wiki הרשמי של nftables.

שימוש ב-nftables כברירת מחדל

# /etc/fail2ban/jail.local
[DEFAULT]
banaction         = nftables-multiport
banaction_allports = nftables-allports
chain             = input

Fail2ban יוצר טבלת nftables בשם f2b-table ואת ה-set addr-set-sshd (או שם ה-jail הרלוונטי) שמכיל את הכתובות החסומות. בדקו אותו:

sudo nft list table inet f2b-table
sudo nft list set inet f2b-table addr-set-sshd

שימוש ב-firewalld

ב-Rocky/AlmaLinux/RHEL ההמלצה היא firewalld עם rich rules. התקינו את חבילת האינטגרציה ואז:

sudo dnf install -y fail2ban-firewalld
# ב-jail.local
banaction = firewallcmd-ipset

האקשן משתמש ב-ipset מאחורי הקלעים, מה שנותן ביצועים מעולים גם עם עשרות אלפי כתובות חסומות.

יצירת פילטרים מותאמים ל-Nginx, Postfix ו-WordPress

העוצמה האמיתית של Fail2ban היא כשמפעילים אותו על שירותים מעבר ל-SSH. הנה שלושה פילטרים מוכנים לשימוש שמכסים את התוקפים הכי נפוצים.

הגנה על Nginx מפני סריקות

# /etc/fail2ban/filter.d/nginx-badbots.local
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*(wp-login|xmlrpc|admin|\.env|\.git|phpMyAdmin|shell\.php).*" (4\d\d|5\d\d)
ignoreregex =

# /etc/fail2ban/jail.d/nginx.local
[nginx-badbots]
enabled  = true
port     = http,https
filter   = nginx-badbots
logpath  = /var/log/nginx/access.log
maxretry = 2
findtime = 5m
bantime  = 12h

הגנה על Postfix מפני auth brute force

# /etc/fail2ban/jail.d/postfix.local
[postfix-sasl]
enabled  = true
port     = smtp,465,submission,imap,imaps,pop3,pop3s
filter   = postfix-sasl
logpath  = /var/log/mail.log
maxretry = 3
findtime = 10m
bantime  = 6h

הגנה על WordPress

# /etc/fail2ban/filter.d/wordpress.local
[Definition]
failregex = ^<HOST> .* "POST /wp-login\.php
            ^<HOST> .* "POST /xmlrpc\.php
ignoreregex =

# /etc/fail2ban/jail.d/wordpress.local
[wordpress]
enabled  = true
port     = http,https
filter   = wordpress
logpath  = /var/log/nginx/access.log
maxretry = 5
findtime = 5m
bantime  = 24h

לפני שאתם מפעילים jail עם פילטר חדש, בדקו אותו על הלוג האמיתי:

sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-badbots.local

הפקודה תדפיס כמה שורות תואמות ה-regex תפס. בלי הבדיקה הזאת יש סיכון גבוה ליצור פילטר שגורם ל-false positives ולחסימת משתמשים לגיטימיים (קרה לי פעם באמצע יום שישי, לא נעים).

ניהול Fail2ban מהשורה עם fail2ban-client

ה-CLI fail2ban-client הוא הדרך היחידה המתועדת לתקשר עם ה-daemon בזמן ריצה. הפקודות שכל מפעיל צריך לדעת:

# מצב כללי - רשימת jails פעילים
sudo fail2ban-client status

# מצב של jail ספציפי - כמה IPs חסומים, כמה כשלים, איפה הלוג
sudo fail2ban-client status sshd

# חסימה ידנית של IP
sudo fail2ban-client set sshd banip 203.0.113.42

# שחרור ידני של IP חסום
sudo fail2ban-client set sshd unbanip 203.0.113.42

# ניקוי כל החסימות של jail מסוים
sudo fail2ban-client unban --all

# רשימת כל ה-IPs שחסומים כרגע ב-jail
sudo fail2ban-client get sshd banip

# בדיקת הזמן שנותר עבור IP ספציפי
sudo fail2ban-client get sshd banip --with-time

# טעינה מחדש של קונפיגורציה בלי איבוד חסימות
sudo fail2ban-client reload

# טעינה מחדש של jail בודד
sudo fail2ban-client reload sshd

# שינוי דינמי של פרמטר
sudo fail2ban-client set sshd bantime 604800

עבור סקריפטים אוטומטיים, השתמשו בפורמט --csv או --yaml כדי לפרסר את הפלט בצורה בטוחה.

הגדרת ignoreip, whitelist ותמיכת IPv6

הפרמטר ignoreip הוא הדבר הראשון שתגדירו. הוא מונע מכם לחסום את עצמכם, ומקבל רשימה של כתובות בודדות, טווחי CIDR, שמות דומיין (זהירות, הופך את Fail2ban לתלוי DNS) וקבצים חיצוניים.

# /etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
           10.0.0.0/8
           192.168.0.0/16
           2001:db8::/32
           office.example.com

אם רשימת ה-whitelist שלכם מתארכת, העבירו אותה לקובץ חיצוני:

ignoreip = 127.0.0.1/8 ::1
ignorecommand = /usr/local/bin/check-whitelist.sh <ip>

הסקריפט check-whitelist.sh מחזיר 0 אם הכתובת צריכה להיות מדולגת ו-1 אם צריך להעריך אותה כרגיל.

תמיכה מלאה ב-IPv6

Fail2ban 1.1.0 מוסיף תמיכה טבעית ב-nftables לחסימת טווחי IPv6 שלמים. כדי לחסום את כל ה-/64 של תוקף (מכיוון שהוא יכול לרוטט בין כתובות בתוך הטווח):

# /etc/fail2ban/jail.local
[DEFAULT]
banaction = nftables-multiport
block_subnet = 64  # חוסם /64 עבור IPv6

ודאו שהלוג של השירות שלכם מכיל כתובות IPv6 מלאות (לא v4-mapped). ב-sshd_config הפרמטר הרלוונטי הוא AddressFamily any.

התראות אימייל, אינטגרציה עם SIEM ו-Slack

התראות בזמן אמת חשובות כדי לזהות ניסיונות מתמשכים. Fail2ban מספק שלושה סוגי אקשן משולבים:

  • action_: חסימה בלבד.
  • action_mw: חסימה + אימייל עם whois.
  • action_mwl: חסימה + אימייל עם whois + שורות הלוג הרלוונטיות.
# /etc/fail2ban/jail.local
[DEFAULT]
destemail = [email protected]
sender    = [email protected]
mta       = sendmail

[sshd]
action = %(action_mwl)s

שליחה ל-Slack דרך webhook

צרו אקשן מותאם:

# /etc/fail2ban/action.d/slack.conf
[Definition]
actionstart =
actionstop  =
actioncheck =
actionban   = curl -X POST -H 'Content-type: application/json' \
                --data '{"text":"[Fail2ban] נחסמה <ip> ב-<name> במכונה <fq-hostname>"}' \
                https://hooks.slack.com/services/T00/B00/XXXX
actionunban =

[Init]
name = default

הוסיפו ב-jail:

action = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s"]
         slack

שילוב עם SIEM

הלוג של Fail2ban עצמו נכתב ל-/var/log/fail2ban.log וב-systemd גם ל-journal. עבור SIEM כמו Wazuh, Elastic Security או Splunk השתמשו בפורמט structured logging. השלימו את התמונה עם ניטור מערכת מקיף כפי שסקרנו במדריך auditd המלא.

Fail2ban מול CrowdSec ב-2026

CrowdSec, שיצא ב-2020, מוצג לרוב כ"Fail2ban מודרני". שני הכלים פועלים לפי אותו עיקרון (זיהוי כשלים בלוג + חסימה בחומת אש), אבל יש הבדלים משמעותיים ב-2026.

יכולתFail2ban 1.1.xCrowdSec 1.6.x
שפת פיתוחPythonGo
ביצועים על 100k+ שורות/דקהמוגבלמצוין
חסימות משותפות בקהילהאין (עצמאי)יש (Community Blocklist)
ארכיטקטורה מבוזרתלאכן (API מרכזית)
עקומת למידהמתונה, קבצי confתלולה יותר, YAML + סצנריו
עדכוני חוקים אוטומטייםלאכן (Hub)
תמיכה בפילטרים מותאמיםregex פשוטיםparsers ו-scenarios מלאים
גיל וטביעה בקהילהמ-2004, כלים לאין ספורמ-2020, קהילה צומחת
ההמלצה שלנושרתים בודדים, סטאק פשוטfleet של שרתים + intel קהילתי

אין פתרון "טוב יותר" חד-משמעית. עבור שרת VPS יחיד או סטארטאפ קטן Fail2ban עדיין המנצח בזכות פשטות. עבור ארגונים עם עשרות שרתים, שני הכלים יכולים לרוץ בו-זמנית (על שירותים שונים), וזה בהחלט שילוב שגור.

פתרון בעיות נפוצות

Fail2ban לא חוסם אף אחד למרות ניסיונות בלוג

הבעיה הכי שכיחה. בדקו לפי הסדר:

# 1. האם ה-jail בכלל פעיל?
sudo fail2ban-client status | grep sshd

# 2. האם ה-regex תופס את שורות הלוג?
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 3. האם ה-backend מזהה את הלוג?
sudo journalctl -u fail2ban -n 100 | grep -i sshd

# 4. האם ה-action מיישם חוקים בפועל?
sudo nft list ruleset | grep f2b

סיבה נפוצה מאוד: ב-Ubuntu 22.04+ SSH כותב ל-/var/log/auth.log רק אם rsyslog מותקן. אם עברתם ל-systemd journal only, ודאו ש-jail.local קובע backend = systemd.

שגיאה: "Failed to access socket path"

Fail2ban הופעל לפני שהוא הצליח לכתוב ל-/var/run/fail2ban/fail2ban.sock. בדקו הרשאות ותיקייה:

sudo mkdir -p /var/run/fail2ban
sudo chown root:root /var/run/fail2ban
sudo systemctl restart fail2ban

חסימה של IP לגיטימי (false positive)

שחררו מיד את הכתובת, הוסיפו אותה ל-ignoreip והצמצמו את ה-failregex. אל תעלו את maxretry כפתרון כללי, זה מחליש את כל ההגנה.

sudo fail2ban-client set sshd unbanip 203.0.113.10
sudo sed -i '/^ignoreip/ s/$/ 203.0.113.10/' /etc/fail2ban/jail.local
sudo fail2ban-client reload

שימוש CPU גבוה

בשרתי log גדולים polling backend צורך משאבים. עברו ל-systemd או pyinotify, וצמצמו את החלון findtime ל-5m במקום 10m.

שאלות נפוצות

האם Fail2ban עדיין רלוונטי ב-2026?

כן. למרות שקיימות אלטרנטיבות מודרניות כמו CrowdSec, Fail2ban ממשיך להיות פתרון מוכר, יציב וקל לפריסה על שרתים בודדים או קטנים. גרסה 1.1.0 מ-2024 הוסיפה תמיכה נטיבית ב-nftables ושיפורים ב-IPv6 שהופכים אותו לרלוונטי מאוד לסביבות מודרניות.

איך משחררים IP חסום ב-Fail2ban?

הפקודה sudo fail2ban-client set <jail> unbanip <ip> משחררת מיד כתובת ספציפית. לדוגמה, sudo fail2ban-client set sshd unbanip 203.0.113.42. לשחרור כל הכתובות ב-jail, השתמשו ב-fail2ban-client unban --all.

מה ההבדל בין jail.conf ל-jail.local?

הקובץ jail.conf מגיע עם החבילה ונדרס בעת עדכון. הקובץ jail.local נוצר על ידכם ודורס פרמטרים מ-jail.conf. תמיד עורכים אך ורק את jail.local כדי לשמור על עמידות מול עדכוני חבילה.

האם Fail2ban מגן מפני התקפות DDoS?

לא באופן יעיל. Fail2ban מתאים להגנה מפני התקפות brute force ממקורות בודדים או מעטים. עבור DDoS מבוזר מרבבות מקורות תזדקקו ל-rate limiting ברמת חומת האש (nftables meters), שירות CDN כמו Cloudflare או פתרון scrubbing ייעודי.

איך בודקים אם ה-regex של Fail2ban עובד?

השתמשו ב-fail2ban-regex עם קובץ הלוג והפילטר: sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf. הפקודה מדפיסה כמה שורות תואמות, איזה קטע ה-regex תפס וסטטיסטיקה מלאה. תמיד הריצו אותה לפני שאתם מפעילים פילטר מותאם על שרת production.

מה ההבדל בין reload ל-restart ב-Fail2ban?

הפקודה reload טוענת מחדש את הקונפיגורציה בלי לאבד את החסימות הפעילות ואת מונה הכשלים. הפקודה restart עוצרת ומפעילה מחדש את ה-daemon, מנקה את כל המצב ומאתחלת מונים, שימושית בעיקר לפיתוח או אחרי שדרוג גרסה.

אודות הכותב Editorial Team

Our team of expert writers and editors.