راهاندازی فایروال nftables روی سرور لینوکس: مهاجرت از iptables و ساخت قوانین امن روی VPS و سرور اختصاصی
فایروال اولین لایه دفاعی سروری است که مستقیماً به اینترنت وصل میشود. حتی اگر همه سرویسها بهروز باشند، باز گذاشتن پورتهای غیرضروری سطح حمله را افزایش میدهد. با یک ruleset کوچک میتوان فقط ترافیک موردنیاز را پذیرفت و بقیه اتصالهای ورودی را مسدود کرد.
nftables زیرساخت جدید فیلتر بسته در لینوکس است و در توزیعهای امروزی جای iptables را گرفته است. این ابزار قوانین IPv4 و IPv6 را در یک ساختار منسجم مدیریت میکند، مجموعه پورت و آدرس میسازد و امکان اعمال اتمیک کل ruleset را دارد.
در این راهنما، فایروال nftables در لینوکس را برای یک سرور وب معمولی تنظیم میکنیم: اتصال SSH از یک نشانی مدیریتی، دسترسی عمومی HTTP و HTTPS و مسدود شدن سایر اتصالهای ورودی. سپس قوانین را پایدار میکنیم و روش مهاجرت کنترلشده از iptables را بررسی میکنیم.
پیش از تغییر فایروال، کنسول تحت وب یا دسترسی نجات ارائهدهنده سرور را آماده نگه دارید. یک اشتباه در پورت یا نشانی SSH ممکن است اتصال شما را قطع کند. نشست فعلی SSH را نیز تا پایان آزمایش نبندید.
nftables چگونه قوانین را سازماندهی میکند؟
در nftables، قوانین داخل چند لایه قرار میگیرند:
- Table: ظرف اصلی تنظیمات است. هر جدول به یک family مانند ip، ip6 یا inet تعلق دارد.
- Chain: مسیر پردازش بستهها را مشخص میکند. chain پایه میتواند به hookهایی مانند input، forward و output متصل شود.
- Rule: شرط و عملی را تعریف میکند؛ برای مثال، پذیرش ترافیک TCP روی پورت 443.
- Set: مجموعهای از آدرسها، پورتها یا مقادیر دیگر است که مدیریت قوانین تکراری را ساده میکند.
برای بیشتر سرورهای دوپشته، family از نوع inet انتخاب مناسبی است؛ زیرا همان قوانین را روی IPv4 و IPv6 اعمال میکند. این ویژگی جلوی خطای رایجی را میگیرد که مدیر سرور IPv4 را محدود میکند اما پورتها از مسیر IPv6 همچنان باز میمانند.

سه hook پرکاربرد چنین کاربردی دارند:
- input: بستههایی که مقصدشان خود سرور است.
- output: بستههایی که از خود سرور خارج میشوند.
- forward: بستههایی که سرور فقط مسیریابی میکند؛ مانند میزبان کانتینر یا روتر.
در یک VPS عادی که نقش روتر ندارد، تمرکز اصلی روی chain ورودی است.
تفاوت nftables و iptables
nftables همان هدف کلی iptables را دنبال میکند، اما مدل پیکربندی و امکانات آن متفاوت است.
| موضوع | iptables | nftables |
|---|---|---|
| مدیریت IPv4 و IPv6 | معمولاً با iptables و ip6tables جداگانه | با family نوع inet در یک ruleset |
| گروهبندی مقادیر | وابسته به ابزارهایی مانند ipset | دارای set و map داخلی |
| اعمال چند تغییر | اجرای فرمانهای جداگانه یا استفاده از restore | بارگذاری اتمیک ruleset |
| نمایش قوانین | چند ابزار و قالب متفاوت | خروجی یکپارچه با nft list ruleset |
| ساختار قوانین | مبتنی بر table و chainهای ازپیششناختهشده | table و chainهای قابلتعریف با hook و priority |
| شمارنده ترافیک | با گزینههای جداگانه | عبارت counter در خود قانون |
برخی توزیعها فرمان ظاهری iptables را با backend مبتنی بر nftables اجرا میکنند. خروجی iptables --version ممکن است عبارت nf_tables را نشان دهد. بااینحال، نباید یک ruleset را همزمان و بدون شناخت backend از طریق هر دو رابط مدیریت کرد؛ چون عیبیابی ترتیب و مالکیت قوانین دشوار میشود.
بررسی وضعیت فعلی سرور
ابتدا سرویسهای در حال گوش دادن را با فرمان ss پیدا کنید:
sudo ss -lntup
پورت SSH لزوماً 22 نیست. تنظیم واقعی آن را در فایلهای پیکربندی OpenSSH و خروجی ss بررسی کنید. همچنین مشخص کنید وبسرور، پایگاه داده، پنل مدیریت یا عامل مانیتورینگ روی چه نشانی و پورتی گوش میدهند.
سپس وضعیت ابزارهای فایروال را ببینید:
sudo nft list ruleset
sudo iptables-save
sudo ip6tables-save
اگر ufw، firewalld، Docker، Kubernetes یا نرمافزار دیگری قوانین شبکه را مدیریت میکند، پیش از جایگزینی ruleset باید رفتار آن را بررسی کنید. پاک کردن همه جدولها روی میزبان کانتینر میتواند شبکه یا انتشار پورت کانتینرها را مختل کند.
برای نصب nftables در Debian و Ubuntu اجرا کنید:
sudo apt update
sudo apt install nftables
در توزیعهای خانواده RHEL، بسته معمولاً با این فرمان نصب میشود:
sudo dnf install nftables
طراحی یک ruleset پایه و امن
سیاست پیشنهادی برای ورودی این است که اتصالهای غیرمجاز بهصورت پیشفرض رد شوند. در مقابل، خروجی را فعلاً باز میگذاریم تا بهروزرسانی سیستم، DNS و ارتباط سرویسها مختل نشود.
پیش از ساخت فایل، این مقادیر را مشخص کنید:
- پورت واقعی SSH؛ در مثال ما 22 است.
- نشانی ثابت دفتر، VPN یا سیستم مدیریتی؛ در مثال 203.0.113.10 است.
- نیاز واقعی به IPv6.
- پورتهای عمومی برنامه؛ در مثال 80 و 443 هستند.
نشانی 203.0.113.10 صرفاً مستنداتی است و باید با IP عمومی واقعی خودتان جایگزین شود.
فایل /etc/nftables.conf را با محتوای زیر تنظیم کنید:
#!/usr/sbin/nft -f
flush ruleset
table inet firewall {
set web_ports {
type inet_service
elements = { 80, 443 }
}
chain input {
type filter hook input priority filter; policy drop;
iifname "lo" accept
ct state invalid drop
ct state established,related accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
ip saddr 203.0.113.10 tcp dport 22 ct state new counter accept
tcp dport @web_ports ct state new counter accept
counter log prefix "nft-input-drop: " limit rate 5/second drop
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
این ruleset چند تصمیم مشخص دارد. ترافیک loopback پذیرفته میشود تا ارتباط داخلی برنامهها با localhost قطع نشود. اتصالهای established و related اجازه بازگشت میگیرند و بستههای نامعتبر حذف میشوند.
ICMP نیز عمداً پذیرفته شده است. مسدود کردن کامل ICMP میتواند عیبیابی و برخی سازوکارهای شبکه را خراب کند. ICMPv6 برای کشف همسایه، تشخیص اندازه مسیر و کارکرد درست IPv6 اهمیت بیشتری دارد.
SSH فقط از IP مدیریتی مجاز است، اما وب برای همه نشانیها باز میماند. قانون آخر بستههای ردشده را با نرخ محدود ثبت میکند تا یک اسکن پورت باعث پر شدن سریع لاگ نشود.
اگر IP مدیریتی شما ثابت نیست، محدود کردن SSH به یک IP میتواند دردسرساز شود. راه بهتر، اتصال از طریق VPN یا شبکه مدیریتی است. در غیر این صورت میتوان موقتاً قانون SSH را بدون شرط ip saddr نوشت و حفاظت را با کلید عمومی، غیرفعال کردن ورود رمزعبوری و ابزارهای مقابله با تلاش مکرر مانند Fail2ban تکمیل کرد:
tcp dport 22 ct state new counter accept
تغییر پورت SSH بهتنهایی امنیت قابلاتکایی ایجاد نمیکند؛ فقط بخشی از اسکنهای خودکار و نویز لاگ را کم میکند.
بررسی و اعمال قوانین بدون قطع SSH
پیش از بارگذاری فایل، syntax آن را بررسی کنید:
sudo nft --check --file /etc/nftables.conf
این فرمان خطاهای نحوی را پیدا میکند، اما درست بودن IP مدیریتی یا پورت SSH را تضمین نمیکند. برای کاهش خطر، یک نشست SSH دوم باز کنید و کنسول ارائهدهنده را در دسترس نگه دارید. سپس ruleset را بارگذاری کنید:
sudo nft --file /etc/nftables.conf
sudo nft list ruleset
نشست فعلی معمولاً بهدلیل قانون ct state established,related accept برقرار میماند. بااینحال، آزمون اصلی ایجاد یک اتصال جدید است. از ترمینال دیگری SSH را امتحان کنید و دسترسی وب را نیز بررسی کنید:
ssh user@example-server
curl -I http://example.com
curl -I https://example.com
پورتها را از بیرون سرور آزمایش کنید، نه فقط از localhost. برای دیدن شمارندهها و تشخیص اینکه کدام قانون تطبیق یافته است، دوباره این فرمان را اجرا کنید:
sudo nft -a list ruleset
گزینه -a شناسه هر rule را هم نمایش میدهد. این شناسه برای حذف یک قانون مشخص بدون بازنویسی فوری کل فایل مفید است.
لاگ قانون نهایی معمولاً از طریق journal قابل مشاهده است:
sudo journalctl -k -g nft-input-drop
ثبت همه بستههای ردشده در یک سرور پرترافیک ضروری نیست. پس از عیبیابی میتوانید قانون log را حذف کنید و فقط counter drop نگه دارید.
پایدارسازی قوانین پس از راهاندازی مجدد
اعمال دستی قوانین کافی نیست؛ پس از reboot باید همان فایل دوباره بارگذاری شود. در Debian و Ubuntu، سرویس nftables را فعال کنید:
sudo systemctl enable --now nftables
sudo systemctl status nftables
در توزیعهای خانواده RHEL نیز سرویس nftables در دسترس است، اما اگر firewalld فعال باشد ابتدا باید مشخص کنید کدام ابزار مالک پیکربندی است. غیرفعال کردن firewalld بدون بررسی ممکن است قوانین موجود سرویسها یا zoneها را حذف کند.
پس از فعالسازی، یک بار سرور را در زمان نگهداری راهاندازی مجدد کنید و از طریق کنسول و SSH صحت قوانین را بسنجید:
sudo systemctl reboot
پس از بالا آمدن سیستم، nft list ruleset و سرویسهای در حال گوش دادن را دوباره بررسی کنید. اتکا به موفق بودن فرمان systemctl enable جای آزمون واقعی reboot را نمیگیرد.
مهاجرت کنترلشده از iptables
مهاجرت بهتر است در یک بازه نگهداری انجام شود. ابتدا از قوانین موجود نسخه پشتیبان بگیرید:
sudo iptables-save > /root/iptables-v4-backup.rules
sudo ip6tables-save > /root/iptables-v6-backup.rules
sudo nft list ruleset > /root/nftables-before-migration.nft
ابزارهای iptables-translate و iptables-restore-translate میتوانند قواعد قدیمی را به syntax نزدیک به nftables تبدیل کنند:
sudo iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables-restore-translate -f /root/iptables-v4-backup.rules
خروجی ترجمه را مستقیم روی سرور عملیاتی اعمال نکنید. extensionها، targetهای خاص، NAT، mark، ماژولهای تطبیق و قوانینی که نرمافزارهای دیگر ساختهاند ممکن است ترجمه کامل یا مناسبی نداشته باشند. خروجی را بهعنوان نقطه شروع بخوانید و ruleset نهایی را بر اساس سرویسهای واقعی بازنویسی کنید.
روال مهاجرت پیشنهادی چنین است:
1. پورتها، NAT، مسیر forwarding و وابستگی نرمافزارها را فهرست کنید.
2. از قوانین IPv4 و IPv6 نسخه پشتیبان بگیرید.
3. معادل nftables را در یک فایل جدا بسازید.
4. فایل را با nft --check بررسی کنید.
5. در محیط آزمایشی یا از طریق کنسول، قوانین را اعمال کنید.
6. SSH، وب، DNS، مانیتورینگ و سرویسهای کانتینری را از بیرون آزمایش کنید.
7. تنها پس از اطمینان، سرویس قدیمی را از چرخه راهاندازی خارج کنید.
فرمان flush ruleset همه قوانین nftables را پاک میکند. روی سیستمی که Docker، Kubernetes، firewalld یا ابزار دیگری جدولهای nftables را ساخته است، استفاده از آن بدون بررسی خطرناک است. در چنین محیطی بهتر است فقط table متعلق به خودتان را مدیریت کنید یا فایروال را از طریق ابزار اصلی همان پلتفرم تنظیم کنید.
چند قانون کاربردی برای محیط واقعی
باز کردن پورت برنامه فقط برای یک شبکه خصوصی
اگر پنل یا پایگاه داده باید فقط از شبکه خصوصی 10.20.0.0/16 قابل دسترسی باشد، میتوان نوشت:
ip saddr 10.20.0.0/16 tcp dport 8443 ct state new accept
محدودسازی در فایروال جای bind کردن سرویس به IP خصوصی را نمیگیرد. بهتر است هر دو کنترل اعمال شوند.
محدود کردن نرخ اتصال جدید به SSH
برای کاهش اتصالهای پرتکرار میتوان نرخ اتصال جدید را محدود کرد:
tcp dport 22 ct state new limit rate 10/minute burst 15 packets accept
این عدد باید با الگوی استفاده تیم هماهنگ شود. نرخ بسیار پایین ممکن است هنگام قطعی شبکه یا فعالیت چند مدیر، اتصال معتبر را هم رد کند. احراز هویت با کلید و غیرفعال کردن password authentication همچنان کنترل اصلی SSH است.
حذف یا افزودن یک قانون موقت
برای تغییرات پایدار، فایل اصلی را ویرایش و کل ruleset را پس از بررسی بارگذاری کنید. تغییر مستقیم با فرمان nft add rule برای عیبیابی مناسب است، اما پس از reboot از بین میرود مگر اینکه در فایل ذخیره شود.
خطاهای رایج در تنظیم فایروال nftables در لینوکس
رایجترین خطا، فعال کردن policy drop پیش از افزودن قانون SSH است. اشتباه در IP مبدأ، پورت یا نام رابط هم نتیجه مشابهی دارد.
خطای دیگر، تنظیم فقط IPv4 و فراموش کردن IPv6 است. استفاده از table نوع inet بخش زیادی از این ناسازگاری را رفع میکند، اما شرطهای آدرس همچنان باید با نسخه IP هماهنگ باشند. برای محدود کردن SSH از طریق IPv6 باید قانون ip6 saddr جداگانه تعریف شود.
باز گذاشتن مستقیم پورت پایگاه داده روی اینترنت نیز معمولاً لازم نیست. PostgreSQL، MySQL، Redis و پنلهای داخلی را به شبکه خصوصی، VPN یا یک IP مدیریتی محدود کنید.
در نهایت، فایروال نباید جای بهروزرسانی سیستم، تنظیم امن SSH، حداقلسازی سرویسها و مدیریت دسترسی را بگیرد؛ این موارد در راهنمای افزایش امنیت سرور لینوکس با جزئیات بررسی شده است. nftables ترافیک را کنترل میکند، اما آسیبپذیری برنامهای را که عمداً روی پورت عمومی در دسترس است برطرف نمیکند.
انتخاب زیرساخت مناسب برای اجرای سرویس
اگر برای راهاندازی یک سرویس لینوکسی به سروری با دسترسی مدیریتی نیاز دارید، میتوانید مشخصات سرور ابری آریاسرویس را بررسی کنید. پس از تحویل سرور، پیش از استقرار برنامهها پورتهای لازم را فهرست کنید و ruleset را متناسب با معماری واقعی سرویس بسازید.
جمعبندی
یک پیکربندی پایه nftables لازم نیست طولانی باشد. پذیرش loopback، اجازه دادن به اتصالهای برقرارشده، حفظ ICMP، محدود کردن SSH و باز کردن پورتهای واقعی برنامه برای بیشتر VPSهای وب نقطه شروع مناسبی است. بخش حساس کار، نوشتن چند قانون نیست؛ باید مسیر بازگشت داشته باشید، اتصال جدید SSH را قبل از بستن نشست فعلی آزمایش کنید، قوانین را پس از reboot بسنجید و مالکیت فایروال را میان nftables، firewalld و ابزارهای کانتینری روشن نگه دارید. برای مهاجرت از iptables نیز ترجمه خودکار را فقط پیشنویس در نظر بگیرید. ruleset نهایی باید بر اساس ترافیک، سرویسها، IPv6، NAT و نیازهای واقعی همان سرور بازبینی و آزمایش شود.




