מבוא: למה nftables הוא חובה בכל שרת לינוקס ב-2026
אם אתם עדיין עובדים עם iptables לניהול חומת האש בשרתים שלכם — הגיע הזמן לשדרוג. ברצינות. iptables עשה עבודה מעולה במשך עשרים שנה, אבל ב-2026 הוא פשוט כבר לא הכלי הנכון. nftables, שהוא המחליף הרשמי, הפך לברירת המחדל בכל ההפצות הגדולות: Debian 10+, Ubuntu 20.04+, RHEL 8+, Fedora 32+ ו-Arch Linux.
והסיבות? ביצועים טובים יותר, תחביר נקי ואחיד, תמיכה מובנית ב-IPv4 וב-IPv6 באותה מסגרת, ויכולות כמו sets ו-maps שפשוט לא קיימות ב-iptables הישן.
אז בואו ניגש לעניין. במדריך הזה נבנה חומת אש מלאה מאפס — שלב אחרי שלב. נתחיל מהבסיס, נעבור לכללים מעשיים לשרתי ווב ו-SSH, נוסיף הגנות מפני Brute Force ו-DDoS, ונסיים עם מיגרציה מ-iptables ואינטגרציה עם Fail2Ban. כל דוגמה כאן היא קוד שעובד — אפשר ליישם ישירות בסביבת הייצור.
מה זה nftables ואיך הוא שונה מ-iptables
nftables הוא מסגרת סינון חבילות (packet filtering) בליבת לינוקס, זמין מגרסת קרנל 3.13 ומעלה. הוא מחליף את iptables, ip6tables, arptables ו-ebtables בכלי אחד מאוחד — nft. במקום לז׳ונגלר בין ארבעה כלים עם תחבירים שונים, יש לכם כלי אחד שעושה הכל.
היתרונות המרכזיים של nftables
- תחביר אחיד: משפחת
inetמאפשרת לכתוב כלל אחד שחל על IPv4 וגם IPv6. אין יותר שכפול כללים בשני קבצי תצורה נפרדים. - ביצועים מעולים: ב-iptables, כל חבילה עוברת ליניארית (O(n)) דרך כל הכללים. ב-nftables, שימוש ב-sets ו-maps מאפשר חיפוש בזמן קבוע (O(1)). בשרתים עם מאות כללים — זה הבדל דרמטי.
- עדכונים אטומיים: שינויים מיושמים כטרנזקציה אחת דרך Netlink. לא עוד race conditions בזמן טעינת כללים.
- מבני נתונים מתקדמים: sets, maps ו-concatenations — לוגיקה מורכבת בכלל אחד במקום עשרות כללים.
- מעקב מובנה (tracing): אפשר לראות בדיוק איזה כלל תפס חבילה. יכולת שפשוט לא קיימת ב-iptables (ומאמינו לי, חסכה לי שעות של דיבוג).
- אין טבלאות ושרשרות ברירת מחדל: ב-iptables, טבלאות ברירת מחדל נטענות תמיד ומשפיעות על ביצועים גם בלי כללים. ב-nftables, מגדירים רק את מה שצריך — לא יותר.
ארכיטקטורה בסיסית: טבלאות, שרשרות וכללים
לפני שקופצים לכתיבת כללים, כדאי להבין את המבנה ההיררכי. nftables בנוי משלוש שכבות, וההבנה שלהן חוסכת הרבה כאב ראש בהמשך.
טבלאות (Tables)
טבלה היא בעצם מרחב שמות (namespace) שמכיל שרשרות, כללים ו-sets. לכל טבלה מוגדרת משפחת כתובות:
ip— IPv4 בלבדip6— IPv6 בלבדinet— IPv4 ו-IPv6 יחד (מומלץ לרוב המקרים)arp— פרוטוקול ARPbridge— גשר רשתnetdev— סינון ברמת ממשק הרשת
שרשרות (Chains)
שרשרת מכילה כללים בסדר מסוים. יש שני סוגים עיקריים:
- שרשרת בסיס (Base Chain): נקודת כניסה לחבילות מהרשת. כאן מגדירים hook (כמו input, output, forward) וסדר עדיפות.
- שרשרת רגילה (Regular Chain): משמשת כיעד ל-jump — בעיקר לארגון כללים בצורה נקייה ומודולרית.
כללים (Rules)
כל כלל מגדיר תנאי התאמה ופעולה. וכאן יש יתרון מגניב: ב-nftables אפשר לשרשר כמה פעולות בכלל אחד. למשל, גם לרשום ביומן וגם לקבל חבילה — הכל באותו כלל.
התקנה והפעלה ראשונית
ברוב ההפצות המודרניות nftables כבר מותקן. אם בכל זאת צריך להתקין:
# Debian/Ubuntu
sudo apt update && sudo apt install nftables
# RHEL/CentOS/Fedora
sudo dnf install nftables
# Arch Linux
sudo pacman -S nftables
# הפעלה והגדרה לעלייה אוטומטית בעת אתחול
sudo systemctl enable nftables
sudo systemctl start nftables
קובץ התצורה הראשי יושב ב-/etc/nftables.conf. הנה כמה פקודות שתשתמשו בהן כל הזמן:
# הצגת כל הכללים הפעילים
sudo nft list ruleset
# טעינת תצורה מקובץ
sudo nft -f /etc/nftables.conf
# בדיקת תקינות תצורה בלי להחיל
sudo nft -c -f /etc/nftables.conf
# ניקוי כל הכללים
sudo nft flush ruleset
בניית חומת אש Stateful מאפס
חומת אש stateful עוקבת אחרי מצב החיבורים ומקבלת החלטות על בסיס הקשר — לא רק כתובות IP ופורטים. זה הבסיס לכל הגדרת אבטחה רצינית.
מדיניות Default-Deny — הכלל הראשון והחשוב ביותר
הגישה הנכונה פשוטה: חוסמים הכל כברירת מחדל, ופותחים רק מה שבאמת צריך. כל גישה אחרת? מתכון לצרות. הנה תצורה בסיסית להגנה על שרת SSH:
#!/usr/sbin/nft -f
flush ruleset
table inet firewall {
chain input {
type filter hook input priority 0; policy drop;
# Allow loopback traffic
iif lo accept
# Allow established and related connections
ct state established,related accept
# Drop invalid connections
ct state invalid drop
# Allow SSH
tcp dport 22 ct state new accept
# Allow ICMP (ping) with rate limiting
meta l4proto icmp icmp type echo-request limit rate 5/second burst 10 packets accept
meta l4proto ipv6-icmp accept
# Log and drop everything else
counter log prefix "[nft-drop-input] " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
כמה נקודות חשובות שכדאי לשים לב אליהן:
- policy drop — כל מה שלא הותר במפורש פשוט נחסם. ככה זה צריך לעבוד.
- ct state established,related accept — חיבורים קיימים ממשיכים לעבור (כולל תגובות HTTP וכו׳).
- ct state invalid drop — חבילות שלא שייכות לחיבור מוכר? נזרקות מיד.
- Rate limiting על ICMP — מונע ניצול ping flood, בלי לחסום ping לגמרי. איזון נכון.
- Log לפני drop — מאפשר לראות מה נחסם. חיוני לדיבוג ושיפור הכללים.
תצורה מעשית לשרת ווב
בשרת ווב טיפוסי צריך לפתוח HTTP/HTTPS, SSH לניהול, ואולי גם כמה שירותים נוספים. הנה תצורה מלאה ומאובטחת שאני משתמש בה כבסיס:
#!/usr/sbin/nft -f
flush ruleset
table inet webserver {
# Define sets for allowed management IPs
set admin_ips {
type ipv4_addr
flags interval
elements = { 10.0.0.0/24, 192.168.1.100 }
}
chain input {
type filter hook input priority 0; policy drop;
# Loopback
iif lo accept
# Connection tracking
ct state established,related accept
ct state invalid drop
# SSH - only from admin IPs
ip saddr @admin_ips tcp dport 22 ct state new accept
# HTTP and HTTPS - open to all
tcp dport { 80, 443 } ct state new accept
# ICMP rate limited
meta l4proto icmp icmp type { echo-request, destination-unreachable, time-exceeded } limit rate 10/second accept
meta l4proto ipv6-icmp accept
# Log dropped packets
counter log prefix "[nft-webserver-drop] " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
שימו לב ל-set בשם admin_ips — זה מה שהופך את הניהול לקל. במקום לערוך כללים בכל פעם שמתווסף אדמין, פשוט מעדכנים את ה-set:
# הוספת IP ל-set בזמן ריצה
sudo nft add element inet webserver admin_ips { 10.10.5.50 }
# הסרת IP מה-set
sudo nft delete element inet webserver admin_ips { 10.10.5.50 }
הגנה מפני התקפות Brute Force
התקפות Brute Force על SSH הן כנראה ההתקפה הנפוצה ביותר שתראו בלוגים של שרת לינוקס. כל שרת עם SSH פתוח לאינטרנט מקבל אלפי ניסיונות כניסה ביום (לפחות). החדשות הטובות: nftables מאפשר הגנה ברמת הקרנל באמצעות Rate Limiting דינמי — הרבה לפני שהחבילות מגיעות לתהליך sshd.
הגבלת קצב חיבורי SSH
table inet ssh_protection {
# Dynamic set to track connection rates per IP
set ssh_ratelimit {
type ipv4_addr
flags dynamic,timeout
timeout 60s
}
# Set for temporarily blocked IPs
set ssh_blocked {
type ipv4_addr
flags dynamic,timeout
timeout 10m
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
ct state invalid drop
# Drop blocked IPs immediately
ip saddr @ssh_blocked drop
# Rate limit new SSH connections: max 3 per minute per IP
tcp dport 22 ct state new \
add @ssh_ratelimit { ip saddr limit rate 3/minute burst 5 packets } \
accept
# IPs exceeding the rate get blocked
tcp dport 22 ct state new \
add @ssh_blocked { ip saddr } \
log prefix "[nft-ssh-blocked] " drop
# Allow other services...
tcp dport { 80, 443 } ct state new accept
meta l4proto icmp icmp type echo-request limit rate 5/second accept
counter drop
}
}
הלוגיקה כאן אלגנטית: כל IP שמנסה ליצור יותר מ-3 חיבורי SSH חדשים בדקה — עף אוטומטית ל-set בשם ssh_blocked ונחסם ל-10 דקות. ה-timeout דואג שהערכים נמחקים לבד. אפס תחזוקה ידנית.
הגנה מפני התקפות DDoS
nftables נותן כלים מובנים להתמודדות עם DDoS ברמת השרת. אני אגיד את זה ברור — זה לא מחליף שירותים ייעודיים כמו Cloudflare. אבל זו שכבת הגנה חשובה שעוצרת הרבה תעבורה זדונית לפני שהיא מגיעה לאפליקציה.
הגנה מפני SYN Flood
table inet ddos_protection {
set denylist {
type ipv4_addr
flags dynamic,timeout
timeout 5m
}
chain input {
type filter hook input priority filter; policy drop;
iif lo accept
ct state established,related accept
ct state invalid counter drop
# Drop denylisted IPs
ip saddr @denylist counter drop
# Detect SYN flood: more than 25 new connections/second from one IP
tcp flags syn tcp dport { 80, 443 } \
meter syn_flood { ip saddr limit rate over 25/second burst 50 packets } \
add @denylist { ip saddr } \
log prefix "[nft-synflood] " drop
# Limit total new connections per IP
ct state new meter conn_rate { ip saddr limit rate over 60/minute } \
add @denylist { ip saddr } drop
# Allow legitimate traffic
tcp dport 22 ct state new accept
tcp dport { 80, 443 } ct state new accept
meta l4proto icmp icmp type echo-request limit rate 5/second accept
counter drop
}
}
הגבלת חיבורים מקבילים
מעבר להגבלת קצב, כדאי מאוד להגביל גם את מספר החיבורים המקבילים מ-IP אחד. זה עוצר בוטים שפותחים מאות חיבורים במקביל:
# הגבלת חיבורי SSH מקבילים ל-2 לכל IP
nft add rule inet firewall input tcp dport 22 \
meter ssh_connlimit { ip saddr ct count over 2 } \
counter reject
# הגבלת חיבורי HTTP מקבילים ל-50 לכל IP
nft add rule inet firewall input tcp dport { 80, 443 } \
meter http_connlimit { ip saddr ct count over 50 } \
counter drop
מיגרציה מ-iptables ל-nftables
יש לכם שרתים ותיקים עם iptables? לא צריך לפחד מהמיגרציה. nftables מגיע עם כלי תרגום מובנים, והתהליך יכול להיות הדרגתי ובטוח לחלוטין.
שלב 1: תרגום כללים קיימים
# תרגום כלל iptables בודד
iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
# Output: nft add rule ip filter INPUT tcp dport 22 counter accept
# תרגום קובץ כללים שלם
iptables-save > iptables-backup.txt
iptables-restore-translate -f iptables-backup.txt > nftables-rules.nft
# בדיקת התוצאה
cat nftables-rules.nft
# טעינת הכללים המתורגמים
nft -f nftables-rules.nft
שלב 2: בדיקה בסביבת ביניים
חוק ברזל: לעולם אל תעשו מיגרציה ישירות על שרת ייצור. תמיד בדקו בסביבת staging קודם. וודאו שכל השירותים נגישים, ובדקו מכתובת IP חיצונית — כי בדיקה מ-localhost לא שווה הרבה (loopback תמיד עובר).
שלב 3: מעבר בשרת הייצור
# גיבוי כללי iptables
iptables-save > /root/iptables-backup-$(date +%Y%m%d).txt
# העתקת כללי nftables
cp nftables-rules.nft /etc/nftables.conf
# בדיקת תקינות
nft -c -f /etc/nftables.conf
# ניקוי iptables והפעלת nftables
systemctl stop iptables 2>/dev/null
systemctl disable iptables 2>/dev/null
systemctl enable nftables
systemctl start nftables
# וידוא
nft list ruleset
אזהרה חשובה: לא להריץ iptables-legacy ו-nftables במקביל. שניהם עובדים מול אותה תשתית בקרנל (Netfilter), וכללים מתנגשים יוצרים התנהגות מוזרה שקשה מאוד לדבג. אם יש לכם Docker או כלים אחרים שמגדירים כללי iptables אוטומטית — בדקו תאימות לפני שמתחילים.
אינטגרציה עם Fail2Ban
Fail2Ban ו-nftables הם צמד מנצח. Fail2Ban מנטר לוגים, מזהה דפוסי התקפה, וחוסם כתובות IP אוטומטית דרך nftables. ההגדרה פשוטה:
# /etc/fail2ban/jail.local
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables-allports
chain = input
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
Fail2Ban ייצור אוטומטית טבלה ו-set ב-nftables לניהול הכתובות החסומות. ככה בודקים מה קורה:
# הצגת הכללים של Fail2Ban
sudo nft list table inet f2b-table
# הצגת כתובות חסומות
sudo fail2ban-client status sshd
תכונות מתקדמות: Sets, Maps ו-Verdict Maps
וכאן nftables באמת מתחיל לזהור. sets ו-maps הם מה שהופך אותו ממסנן חבילות רגיל לכלי ניהול רשת רציני. בואו נראה כמה דוגמאות מעשיות.
Named Sets — ניהול מרכזי של כתובות
table inet firewall {
# Whitelisted IPs that bypass rate limiting
set whitelist {
type ipv4_addr
flags interval
elements = { 10.0.0.0/8, 172.16.0.0/12 }
}
# Known malicious IPs (updated externally)
set blacklist {
type ipv4_addr
flags interval
}
# Allowed TCP ports
set allowed_ports {
type inet_service
elements = { 22, 80, 443, 8080 }
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
# Blacklist takes priority
ip saddr @blacklist counter drop
# Whitelist bypasses rate limiting
ip saddr @whitelist tcp dport @allowed_ports accept
# Regular traffic with rate limiting
tcp dport @allowed_ports ct state new accept
counter drop
}
}
Verdict Maps — ניתוב תעבורה דינמי
Verdict maps זה אחד הפיצ׳רים שהכי אהבתי כשעברתי ל-nftables. הם מאפשרים לבצע פעולות שונות לפי ערך ההתאמה — בכלל אחד בלבד:
table inet firewall {
# Route traffic to different chains based on destination port
map port_policy {
type inet_service : verdict
elements = {
22 : jump ssh_rules,
80 : jump web_rules,
443 : jump web_rules,
25 : drop
}
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
tcp dport vmap @port_policy
counter drop
}
chain ssh_rules {
ip saddr 10.0.0.0/8 accept
limit rate 3/minute accept
drop
}
chain web_rules {
limit rate 100/second accept
drop
}
}
ניטור, דיבוג ויומן (Logging)
חומת אש בלי ניטור? זה כמו מנעול שאף אחד לא בודק אם ננעל. בכנות, ניטור הוא לא פחות חשוב מהכללים עצמם.
רישום ביומן (Logging)
# רישום חבילות חסומות עם prefix לזיהוי קל
nft add rule inet firewall input counter log prefix "[nft-blocked] " drop
# רישום חיבורים חדשים ל-SSH
nft add rule inet firewall input tcp dport 22 ct state new \
log prefix "[nft-ssh-new] " accept
היומנים נכתבים ל-/var/log/kern.log או ל-syslog, ואפשר לנתח אותם עם journalctl או לשלוח למערכת ניטור מרכזית כמו ELK.
מעקב בזמן אמת (Tracing)
# הפעלת tracing על חבילות SSH
nft add rule inet firewall input tcp dport 22 meta nftrace set 1
# צפייה בתוצאות
nft monitor trace
ה-tracing מראה בדיוק אילו כללים כל חבילה עוברת, כולל הפעולה שננקטה. כשיש בעיה בכללים — זה הכלי הראשון שפותחים.
סטטיסטיקות ומוני חבילות
# הצגת כללים עם מוני חבילות
nft list ruleset -a
# אפס מונים
nft reset counters
שיטות עבודה מומלצות (Best Practices)
אחרי שנים של עבודה עם nftables, הנה הדברים שלמדתי (חלקם בדרך הקשה):
- תמיד Default-Deny: מדיניות
policy dropבכל שרשרת input ו-forward. פתחו רק מה שחייבים. - SSH קודם לכל: תמיד הוסיפו כלל SSH לפני שמגדירים policy drop. אחרת תנעלו את עצמכם בחוץ. כן, זה קורה גם למנוסים.
- בדקו לפני שמחילים:
nft -c -fבודק תחביר בלי להחיל כללים. תמיד תריצו את זה קודם. - בדקו מבחוץ: לבדוק חומת אש מ-localhost זה כמו לא לבדוק. תמיד בדקו ממכונה חיצונית.
- גבו לפני כל שינוי:
nft list ruleset > backup.nft— שתי שניות שיכולות לחסוך שעות. - השתמשו ב-sets: כללים חוזרים לכתובות IP או פורטים? sets. תמיד sets. נקי יותר, קל יותר, מהיר יותר.
- הפעילו יומן: תרשמו ביומן חבילות חסומות. בלי זה, אתם עיוורים לדפוסי תקיפה.
- חשבו בשכבות: nftables הוא שכבה אחת. שלבו עם Fail2Ban, SELinux/AppArmor, ואבטחת SSH לתמונה מלאה.
שאלות נפוצות (FAQ)
האם nftables מחליף את iptables לחלוטין?
בקצרה — כן. nftables הוא המחליף הרשמי ומומלץ לכל התקנה חדשה. iptables עדיין נתמך דרך שכבת תאימות (iptables-nft), אבל iptables-legacy הולך ונעלם. כל ההפצות המובילות כבר עברו.
איך nftables עובד עם Docker ו-Kubernetes?
Docker ו-Kubernetes משתמשים ב-iptables באופן מסורתי. ברוב ההפצות החדשות, פקודות iptables ממופות אוטומטית ל-nftables דרך שכבת iptables-nft. הנקודה החשובה: לא להשתמש ב-iptables-legacy וב-nftables בו-זמנית. בדקו שה-Docker שלכם מוגדר עם backend של nftables.
האם nftables יכול להגן מפני DDoS?
כן, אבל עם סייג. nftables מספק הגנה יעילה מפני SYN flood, brute force ו-connection exhaustion ברמת השרת. אבל מול התקפות DDoS ברמת רוחב הפס (volumetric attacks) — צריך גם הגנה ברמת הרשת או שירות ייעודי. nftables הוא שכבה חשובה, לא פתרון מלא.
האם צריך Fail2Ban אם יש rate limiting ב-nftables?
ממליץ על שניהם. nftables נותן הגנה מהירה ברמת הקרנל, אבל עם לוגיקה בסיסית. Fail2Ban מנתח לוגים ומזהה דפוסים מתוחכמים — כמו ניסיונות כניסה כושלים עם שמות משתמש שונים. השילוב נותן כיסוי הרבה יותר רחב.
איך עושים מיגרציה בלי השבתה?
שלב ראשון — תרגמו כללים עם iptables-restore-translate. אחר כך בדקו בסביבת staging. כשמוכנים, השתמשו בשכבת iptables-nft כשלב ביניים (היא מריצה פקודות iptables מעל nftables). רק אחרי שהכל יציב — עברו לתחביר nftables מקורי. כל התהליך מתבצע בלי downtime.