SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor

iptables أم nftables على Ubuntu: أيهما يعمل فعلاً؟

في Ubuntu، يكتب أمر iptables قواعد nftables افتراضياً. تعلّم إثبات ذلك بأوامر عملية، وقراءة مجموعة القواعد الأصلية، وفهم تعارض ufw وDocker.

مقارنة iptables وnftables على Ubuntu: أيهما يعمل على خادمك؟

في Ubuntu 20.04 وما بعده، يُعد الأمر iptables واجهة أمامية تكتب قواعد nftables. يعمل مرشح حزم واحد داخل النواة، وهو nftables، بينما تبرمجْه أوامر اثنان في مساحة المستخدم. يظل سطر iptables -A INPUT يعمل بالطريقة نفسها تماماً، والقاعدة التي ينشئها هي قاعدة nftables يستطيع nft عرضها.

تحقق من ذلك على خادمك بنفسك قبل أن تعتمد عليه.

iptables -V
sudo update-alternatives --display iptables
sudo nft list ruleset

في Ubuntu 24.04 (الإصدار 1.8.10 من iptables، اعتباراً من أغسطس 2026)، يعرض iptables -V الناتج iptables v1.8.10 (nf_tables). الاسم بين القوسين هو الواجهة الخلفية. يشير (nf_tables) إلى أن الأمر يتصل بـnftables. ويشير (legacy) إلى الواجهة الخلفية القديمة x_tables، التي ما يزال Ubuntu يوفّرها باسم iptables-legacy، والتي تحتفظ بها النواة كمجموعة قواعد منفصلة تماماً. يعرض update-alternatives الرابط الرمزي المرتبط بهذا الاختيار: link currently points to /usr/sbin/iptables-nft.

على VPS جديد لم تُضبط عليه جدار ناري، لا يعرض sudo nft list ruleset أي شيء. هذا الناتج الفارغ هو خط الأساس لديك. أضف قاعدة بالطريقة القديمة ثم افحص الناتج مرة أخرى.

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo nft list ruleset
# Warning: table ip filter is managed by iptables-nft, do not touch!
table ip filter {
  chain INPUT {
    type filter hook input priority filter; policy accept;
    tcp dport 22 counter packets 0 bytes 0 accept
  }
  chain FORWARD {
    type filter hook forward priority filter; policy accept;
  }
  chain OUTPUT {
    type filter hook output priority filter; policy accept;
  }
}

قاعدة iptables التي أضفتها هي قاعدة nftables. يحدّد iptables-nft الجداول التي ينشئها، ويعرض nft ذلك التحذير عندما يرى هذا التحديد، لأن تعديل مثل هذا الجدول باستخدام nft يجعل أداتين تديران القواعد نفسها. لاحظ ما أنشأه أمر واحد: جدولاً لم تسمّه، وسلاسل لم تطلبها. هذا هو النموذج القديم، وهو أول ما يتغير عند كتابة قواعد nftables مباشرة.

ما الذي يخفيه عنك iptables -L

يعرض iptables -L جدول filter فقط. تحتاج قواعد NAT (ترجمة عناوين الشبكة) إلى iptables -t nat -L، بينما تحتاج قواعد mangle إلى -t mangle. ويستخدم IPv6 أمراً منفصلاً هو ip6tables، وله نسخته الخاصة من كل قاعدة. لذلك قد يبدو الخادم نظيفاً في إحدى القوائم، بينما يؤدي شيء ما إلى إسقاط حزمك أو إعادة كتابتها من جدول لم تتحقق منه مطلقاً.

يطبع sudo nft list ruleset كل عائلات البروتوكولات، وكل الجداول، وكل السلاسل، وكل القواعد في إخراج واحد. إذا كنت لا تعرف كيف أُنشئ الخادم، فإن هذا الأمر هو أسرع طريقة لمعرفة ما هو محمّل فعلياً. أضف -a لطباعة معرّفات القواعد، وهي مطلوبة لحذف قاعدة واحدة بدلاً من السلسلة بأكملها.

هناك عادتان يجدر تصحيحهما أثناء ذلك. يحل iptables -L العناوين والمنافذ إلى أسماء، لذلك قد يبدو وكأنه توقف في خادم يعاني من خلل في محلّل الأسماء: استخدم iptables -nvL. وتحقق من أن الواجهة الخلفية القديمة فارغة باستخدام sudo iptables-legacy -nvL، لأن وجود قواعد في الواجهتين الخلفيتين يجعل النواة تقيّم القواعد في كلتيهما، ولا تعرض لك أي قائمة منهما الصورة كاملة.

جداول وسلاسل تنشئها، لا ترثها

يبدأ nftables من دون أي شيء. لا يوجد جدول filter قبل أن تنشئه، وكلمة filter ليست إلا اسماً اخترته. لا ترى السلسلة الحزم إلا بعد أن تمنحها type وhook وpriority، وعندها تصبح base chain. أما السلسلة التي لا تتضمن هذه العناصر فلا تصل إليها الحزم إلا عبر jump أو goto صريح، ولذلك لا تستهلك أي موارد إلى أن يقفز إليها شيء.

التغيير الكبير الآخر هو عائلة inet. يتولى جدول inet واحد معالجة IPv4 وIPv6 باستخدام القواعد نفسها، وهذا يزيل فئة كاملة من الأخطاء التي يكون فيها المنفذ مغلقاً في iptables ومفتوحاً بالكامل في ip6tables. هذا الاختلاف شائع بما يكفي ليكون له نمط فشل مستقل على خوادم ufw.

فيما يلي مجموعة قواعد كاملة للخادم. ضعها في /etc/nftables.conf.

#!/usr/sbin/nft -f
flush ruleset

table inet filter {
  set admin_ips {
    type ipv4_addr
    flags interval
    elements = { 203.0.113.5, 198.51.100.0/24 }
  }

  chain input {
    type filter hook input priority filter; policy drop;
    ct state established,related accept
    ct state invalid drop
    iif lo accept
    ip protocol icmp accept
    meta l4proto ipv6-icmp accept
    tcp dport 22 ip saddr @admin_ips counter accept
    tcp dport { 80, 443 } counter accept
  }

  chain forward {
    type filter hook forward priority filter; policy drop;
  }

  chain output {
    type filter hook output priority filter; policy accept;
  }
}

اقرأ السطر 2 مرتين. يحذف flush ruleset كل جدول على الخادم، بما في ذلك الجداول التي أنشأها ufw وDocker لنفسيهما. واصل القراءة قبل تشغيل هذا الأمر على خادم حي.

تنفذ القاعدة الأولى في سلسلة input معظم العمل. تسمح ct state established,related accept بعودة الردود على الاتصالات التي بدأتها، ولذلك لا تحتاج بقية السلسلة إلا إلى اتخاذ قرار بشأن الاتصالات الجديدة. وتتخلص ct state invalid drop من الحزم التي لا تطابق اتصالاً معروفاً ولا تمثل بداية صالحة. كل ما يأتي بعد ذلك هو فتحة صريحة، بينما تتولى policy drop معالجة الباقي.

تحقق من الملف قبل تحميله، وأبقِ جلسة SSH ثانية مفتوحة أثناء ذلك. يؤدي policy drop، مع وجود خطأ مطبعي واحد في قاعدة SSH، إلى منعك من الوصول إلى خادمك.

sudo nft -c -f /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo nft list ruleset

يحلل nft -c -f الملف ويبلغ عن الأخطاء من دون تحميل أي شيء. لا يطبع التحليل السليم أي مخرجات على الإطلاق.

تستبدل المجموعات قوائم القواعد الطويلة

tcp dport { 80, 443 } هي مجموعة مجهولة: قاعدة واحدة وعم
ليات بحث واحدة، بدلاً من قاعدة لكل منفذ. أما المجموعة المسماة مثل admin_ips فتوفّر إمكانات أكبر، لأنك تستطيع تغييرها أثناء تشغيل جدار الحماية.

sudo nft add element inet filter admin_ips { 203.0.113.9 }
sudo nft list set inet filter admin_ips
sudo nft delete element inet filter admin_ips { 203.0.113.9 }

لا تحتاج إلى إعادة التحميل أو إعادة ترقيم القواعد، وتبقى المطابقة عملية بحث واحدة سواء احتوت المجموعة على خمسة عناوين أو خمسين ألفاً. يتيح flags interval للمجموعة الاحتفاظ بالنطاقات وببادئات CIDR (التوجيه بين النطاقات غير الصنفي) مثل 198.51.100.0/24. من دون هذا الخيار، تقبل المجموعة عناوين مفردة فقط، ويفشل تحميل البادئة.

يمكن للمجموعات أيضاً أن تنتهي صلاحية عناصرها تلقائياً.

set banned {
  type ipv4_addr
  flags timeout
  timeout 1h
}

مع قاعدة تتضمن ip saddr @banned drop، يزيل كل عنصر نفسه بعد ساعة من إضافته. بهذه الطريقة يحظر إجراء nftables في fail2ban على Ubuntu 24.04 عنواناً: إذ يضيف عنصراً إلى مجموعة، ولا يضيف قاعدة. إذا كانت المنافذ جديدة عليك، فابدأ بقراءة ماهيّة المنفذ فعلياً في Linux.

يظهر فرق آخر أثناء الترحيل. لا يحسب nftables الحزم إلا إذا طلبت منه ذلك. يعرض iptables -nvL العدادات لكل قاعدة دائماً. أما في nftables، فلا تظهر الأرقام إلا للقواعد التي تتضمن الكلمة المفتاحية counter، لذلك أضف counter إلى أي قاعدة تتوقع تصحيحها لاحقاً.

كيف تحدد الـhooks والأولويات ترتيب التنفيذ

تسمّي السلسلة الأساسية hook، وهو الموضع في مسار الحزمة الذي تُنفَّذ فيه. يُنفَّذ prerouting قبل قرار التوجيه. ويُنفَّذ input للحزم الموجّهة إلى هذا الجهاز. ويُنفَّذ forward للحزم التي تمر عبره بعد توجيهها. ويُنفَّذ output للحزم الصادرة عن العمليات المحلية. ويُنفَّذ postrouting أخيراً، قبل مغادرة الحزمة مباشرة.

تحدد الأولوية ترتيب السلاسل داخل hook واحد، بدءاً من أقل رقم. تمنح nftables القيم التقليدية أسماءً: قيمة raw هي -300، وقيمة mangle هي -150، وقيمة dstnat هي -100، وقيمة filter هي 0، وقيمة srcnat هي 100. وكتابة priority filter; تعادل كتابة priority 0;.

أما الجزء الذي يحدد ما إذا كان خلط الأدوات يعمل، فهو الآتي. تُنفَّذ كل سلسلة أساسية مسجّلة على hook، وفق ترتيب الأولوية. لا تعني الموافقة على الحزمة في سلسلتك انتهاء معالجتها: إذ ينهي accept تلك السلسلة فقط، وتتابع الحزمة إلى السلسلة الأساسية التالية على hook نفسه. أما drop فنهائي في جميع المواضع ويوقف الحزمة فوراً. لذلك لا يمكن لقاعدة تسمح بالمرور في جدولك التراجع عن إسقاط في جدول ufw، بغض النظر عن السلسلة التي تُنفَّذ أولاً، كما أن accept لا يحميك من سلسلة تُنفَّذ لاحقاً.

تُنفَّذ سلسلتان أساسيتان على hook نفسه وبالأولوية نفسها وفق ترتيب التسجيل، ويتوقف ذلك على الخدمة التي بدأت أولاً. وقد يتغير هذا الترتيب بعد إعادة التشغيل. إذا كان يجب عليك تشغيل جدولك إلى جانب ufw، فامنحه أولوية مختلفة، حتى يكون الترتيب محدداً في الإعدادات بدلاً من أن يتقرر بالتسابق.

لماذا لا توجد قاعدة NAT عكسية لإضافتها؟

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

يبدو جدول nat الذي ينفّذ جزأي المهمة المعتادة لخادم VPS كما يلي.

table inet nat {
  chain prerouting {
    type nat hook prerouting priority dstnat; policy accept;
    iifname "enp1s0" tcp dport 8080 dnat ip to 10.0.0.5:80
  }

  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    ip saddr 10.0.0.0/24 oifname "enp1s0" masquerade
  }
}

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

sudo apt install -y conntrack
sudo conntrack -L -p tcp
tcp 6 431999 ESTABLISHED src=198.51.100.20 dst=203.0.113.10 sport=54321 dport=8080 src=10.0.0.5 dst=198.51.100.20 sport=80 dport=54321 [ASSURED] mark=0 use=1

اقرأ الإدخال على أنه زوجان من القيم. الحقول الأربعة الأولى هي الاتصال كما أرسله العميل، موجهاً إلى 203.0.113.10:8080، أي عنوانك العام. والحقول الأربعة الثانية هي الرد الذي تتوقعه النواة، وقد عُكست ترجمته مسبقاً، والقادم من 10.0.0.5:80، أي الخادم الخلفي الفعلي. هذا الزوج الثاني هو القاعدة العكسية. كتبته النواة عندما طابقت الحزمة الأولى القاعدة.

لذلك لا تكتب قاعدة لاتجاه العودة. لن تتمكن من مطابقتها، لأن حزم العودة تنتمي إلى اتصال قائم ولا تصل مطلقاً إلى سلسلة nat. وحتى إذا طابقتها بطريقة ما، فستترجم حزمة سبق أن عالجتها النواة.

يُحدَّد موضع إعادة الكتابة المطلوبة وفق الآلية نفسها. يجب أن تعمل ترجمة الوجهة في prerouting، قبل قرار التوجيه، لأن التوجيه يجب أن يرى الوجهة الجديدة؛ وإلا ستذهب الحزمة إلى المكان الخطأ. وتُعالَج حركة المرور التي تنشئها النواة نفسها في hook output للسبب نفسه. أما ترجمة المصدر، بما في ذلك إعادة كتابة منفذ المصدر، فيجب أن تعمل في postrouting، بعد أن يختار التوجيه الواجهة الصادرة. يأخذ masquerade عنوانه من تلك الواجهة، ولا تُعرَف الواجهة قبل اكتمال التوجيه.

لهذا تنتمي قاعدة مثل هذه إلى نهاية المسار، ولا مكان لها غير ذلك.

ip saddr 10.0.0.0/24 oifname "enp1s0" snat ip to 203.0.113.10:20000-30000

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

تترتب على ذلك نتيجة عملية مهمة: لا يؤدي تغيير قاعدة NAT إلى نقل الاتصالات الموجودة مسبقاً، لأن ترجمتها مخزّنة بالفعل. وتستمر باستخدام السلوك القديم إلى أن تنتهي صلاحية إدخالاتها. يحذف sudo conntrack -D -p tcp --dport 8080 الإدخالات المطابقة، بينما يحذف sudo conntrack -F جميع الإدخالات. استخدم الأمر الثاني بحذر على خادم NAT، لأن الترجمات المخزّنة هي التي تُبقي الاتصالات الحالية حيّة، ومسحها يقطع كل اتصال يمر عبر الخادم دفعة واحدة.

ufw وDocker يكتبان قواعدهما الخاصة

ufw واجهة أمامية لـ iptables، وهو في Ubuntu واجهة أمامية لـ nftables. لذلك يحتوي خادم ufw على جدول ip filter يضم سلاسل بأسماء ufw-before-input وufw-user-input وما إلى ذلك، بالإضافة إلى نسخة ip6 filter من البنية نفسها. اعرضها باستخدام sudo nft list ruleset | grep ufw. تُنشأ هذه السلاسل من الملفات الموجودة في /etc/ufw، ويعيد ufw reload كتابتها من الصفر. لذلك تختفي قاعدة iptables التي تضيفها يدوياً عند إعادة التحميل التالية. يشرح أساسيات ufw لخادم VPS بنية هذه الملفات.

يبرمج Docker جدار الحماية بنفسه ولا يستشير ufw. يؤدي نشر منفذ باستخدام -p 80:80 إلى كتابة قاعدة DNAT في جدول nat، وقاعدة قبول في مسار إعادة التوجيه. وتُطبَّق القاعدتان قبل سلاسل المستخدم في ufw. وتظهر النتيجة مفاجئة للجميع مرة واحدة: يتم تحميل ufw deny 80، ويظل الوصول إلى الحاوية ممكناً من الإنترنت. يوجد الإصلاح في سلسلة DOCKER-USER التي يتركها Docker لقواعدك. يشرح سبب تجاهل حاويات Docker لـ ufw كيفية استخدامها. اعرض القواعد الموجودة على خادمك باستخدام sudo nft list ruleset | grep -i docker.

أعد الآن قراءة سطر flush ruleset من الإعداد السابق. فهو يحذف كل جدول، بما في ذلك الجداول التي يديرها هذان البرنامجان. على خادم يستضيف Docker، تتوقف المنافذ المنشورة عن العمل إلى أن يعيد sudo systemctl restart docker إنشاء السلاسل. هذا السطر هو الطريقة الأكثر شيوعاً لتعطيل الأشخاص خدماتهم الخاصة أثناء تنظيف إعدادات جدار الحماية.

قواعد تبقى بعد إعادة التشغيل

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

بالنسبة إلى nftables، يقرأ /etc/nftables.conf الملف nftables.service. تشحن Ubuntu هذه الخدمة معطّلة، لذلك تحقّق من حالتها قبل الاعتماد عليها.

systemctl is-enabled nftables
sudo nft -c -f /etc/nftables.conf
sudo systemctl enable --now nftables

بالنسبة إلى iptables، الحزمة هي iptables-persistent، وهي تثبّت netfilter-persistent وتحفظ القواعد في /etc/iptables/rules.v4 و/etc/iptables/rules.v6.

sudo apt install -y iptables-persistent
sudo netfilter-persistent save

لا تشغّل النظامين معاً. ستختلف محتويات الملفين اللذين يدّعي كل منهما احتواء جدار الحماية، وستُطبَّق القواعد التي تُحمَّل أخيراً بطريقة لا يمكن التنبؤ بها من خلال قراءة أي من الملفين.

يوجد خطأ شائع مرتبط بتصدير مجموعة قواعد محمّلة حالياً. يلتقط sudo nft -s list ruleset > /etc/nftables.conf كل ما هو محمّل في تلك اللحظة، بما في ذلك جداول ufw وجداول Docker. إذا استعدت هذا التصدير عند الإقلاع، فستحصل على نسخة ثابتة من القواعد التي تتوقع تلك الأدوات إنشاءها بنفسها، ثم تُنشئ نسخة ثانية عند بدء تشغيلها. صدّر جدولك أنت فقط باستخدام sudo nft -s list table inet filter. يستبعد الخيار -s العدادات، لأنها لا تنتمي إلى ملف إعدادات.

هل ينبغي تفعيل جدار الحماية على VPS لديك؟

اترك ufw كما هو ما لم تحتج إلى وظيفة لا يستطيع التعبير عنها. يغطي ufw الاستخدام المعتاد لـVPS: الرفض الافتراضي مع فتح عدد قليل من المنافذ. واستبدال ذلك بمجموعة قواعد مكتوبة يدوياً لمجرد الاستبدال يمنحك جدار الحماية نفسه، مع عنصر إضافي عليك صيانته.

استخدم الأدوات الأصلية عندما تتجاوز حاجتك نموذج ufw، مثل NAT وإعادة توجيه المنافذ، أو المجموعات التي تحدّثها أثناء التشغيل، أو قاعدة واحدة تغطي عائلتي العناوين، أو أولويات السلاسل التي تختارها بنفسك. هذه أسباب حقيقية، ولا يوفّر ufw طريقة للتعبير عن أي منها.

إذا استخدمت الأدوات الأصلية، فاستخدمها بالكامل. شغّل sudo ufw disable وsudo systemctl disable --now ufw، وتحقق باستخدام sudo nft list ruleset من زوال جداولها، ثم حمّل ملفك الخاص. سيواصل خادم يشغّل ufw وجدولاً مكتوباً يدوياً معاً تمرير حركة الشبكة، لكن السياسة الفعلية أصبحت الآن اتحاد مجموعتي قواعد تُقيَّمان بترتيب تحدده عملية بدء الخدمات، ولا يستطيع أي شخص يقرأ أحد الملفين معرفة ما يفعله الخادم فعلياً.

ترحيل مجموعة قواعد iptables موجودة

iptables-translate يحوّل قاعدة واحدة ويطبع صيغة nftables. لا يغيّر أي شيء على الخادم.

iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
nft add rule ip filter INPUT tcp dport 22 counter accept

iptables-restore-translate -f /etc/iptables/rules.v4 يفعل الشيء نفسه مع مجموعة قواعد محفوظة بالكامل. تعامل مع ناتجه باعتباره مسودة أولى. التحويل آلي ويتم قاعدةً مقابل قاعدة، لذلك ستحصل على أسماء الجداول والسلاسل القديمة، ومجموعتي قواعد منفصلتين لـ IPv4 وIPv6، ولن تحصل على أي من المجموعات التي تجعل الترحيل مفيداً. أعد كتابته يدوياً في جدول inet واحد، ثم تحقّق منه باستخدام nft -c -f قبل أن تقترب به من خادم حي.

العناوين في هذه الأمثلة مأخوذة من نطاقَي التوثيق 203.0.113.0/24 و198.51.100.0/24، وenp1s0 هو اسم واجهة. استخدم القيم الخاصة بك من ip route show default وip -br addr بدلاً من نسخ القيم هنا، لأن صور Ubuntu الحالية نادراً ما تسمّي أي واجهة eth0.

FAQ

هل أصبح iptables مهجوراً في Ubuntu؟

لم يُلغَ الأمر، وما زال يعمل على Ubuntu 24.04. التغيير هو ما يحدث في الخلفية: iptables واجهة أمامية تكتب قواعد nftables عبر الواجهة الخلفية iptables-nft. تحقّق من إعدادك باستخدام iptables -V، إذ يطبع iptables v1.8.10 (nf_tables) في الإصدار 24.04. وما زالت الواجهة الخلفية القديمة x_tables تُوفَّر باسم iptables-legacy، وهي تحتفظ بمجموعة قواعد منفصلة تماماً؛ لذلك ضع القواعد في واجهة خلفية واحدة فقط، وليس في كلتيهما.

هل أحتاج إلى قاعدة ثانية لإلغاء NAT عند عودة الحزم؟

لا. يخزّن تتبّع الاتصالات الترجمة عندما تطابق أول حزمة في الاتصال قاعدة nat، ثم يعيد كتابة كل حزمة لاحقة في الاتجاهين استناداً إلى ذلك الإدخال المخزّن. يعرض sudo conntrack -L ذلك على شكل مجموعتي tuples لكل اتصال: اتجاه الاتصال الأصلي، ثم الرد الذي عُكست ترجمته مسبقاً. لا يمكن لقاعدة مكتوبة لاتجاه العودة أن تساعد، لأن حزم العودة لا تصل إلى سلسلة nat.

هل يمكنني تشغيل ufw وقواعد nftables الخاصة بي في الوقت نفسه؟

هذا ممكن، لكنه يسبب مشكلة. تُنفَّذ كل base chain مرتبطة بـhook، لذلك تتكوّن السياسة الفعلية من مجموعتي القواعد، وفقاً للأولوية، وعند تساوي الأولوية وفقاً للخدمة التي بدأت أولاً. يكون drop في أي منهما نهائياً، كما أن accept في قواعدك لا يمنع المجموعة الأخرى من إسقاط الحزمة نفسها. اختر أداة واحدة. إذا اخترت nftables، فعطّل ufw أولاً وتحقق من زوال جداوله من sudo nft list ruleset.

كيف أجعل قواعد nftables تستمر بعد إعادة التشغيل في Ubuntu؟

ضع مجموعة القواعد في /etc/nftables.conf، وتحقق منها باستخدام sudo nft -c -f /etc/nftables.conf، ثم شغّل sudo systemctl enable --now nftables. لا تكون الخدمة مفعّلة افتراضياً، لذلك يُستحسن تشغيل systemctl is-enabled nftables مرة واحدة. عند إنشاء ذلك الملف، صدّر جدولك فقط باستخدام sudo nft -s list table inet filter، لأن تفريغ list ruleset الكامل يلتقط أيضاً الجداول التي يديرها ufw وDocker بأنفسهما.