ESC را فشار دهید تا بسته شود

رفع خطای nf_conntrack: table full در لینوکس؛ عیب‌یابی Connection Tracking و تنظیم امن sysctl

فهرست

خطای nf_conntrack: table full, dropping packet نشان می‌دهد جدول رهگیری اتصال‌های Netfilter به سقف ظرفیت رسیده است. در این وضعیت ممکن است اتصال‌های جدید NAT، Docker یا سرویس‌های پشت فایروال برقرار نشوند، در حالی که اتصال‌های قدیمی هنوز کار می‌کنند. راه درست، اندازه‌گیری مصرف جدول و نرخ شکست درج اتصال، پیدا کردن منبع ترافیک و سپس افزایش کنترل‌شده ظرفیت در صورت نیاز است؛ پاک‌کردن کل جدول راه‌حل امنی نیست.

پیش‌نیاز و ثبت وضعیت فعلی

دستورها را با دسترسی sudo روی Linux اجرا کنید. روی سرور Production قبل از تغییر sysctl، مقدار فعلی و وضعیت مصرف حافظه را ثبت کنید. اگر از Docker یا Kubernetes استفاده می‌کنید، بررسی را روی میزبان انجام دهید؛ فضای نام شبکه و سطح دسترسی کانتینر ممکن است دید کامل به جدول ندهد.

uname -r
sudo sysctl net.netfilter.nf_conntrack_max
sudo sysctl net.netfilter.nf_conntrack_count
free -h
sudo journalctl -k -b --no-pager | grep -i 'nf_conntrack'

اگر فایل sysctl مربوطه وجود ندارد، ابتدا بارگذاری ماژول و فعال‌بودن Connection Tracking را بررسی کنید. نبود مقدار الزاماً به معنی پرشدن جدول نیست.

چطور پرشدن جدول Connection Tracking را تشخیص دهیم؟

دو مقدار nf_conntrack_count و nf_conntrack_max را چند بار در زمان وقوع مشکل بخوانید. برای نمونه اگر count برابر 258000 و max برابر 262144 باشد، ظرفیت تقریباً اشباع است؛ اما نسبت بالا به‌تنهایی علت قطعی را ثابت نمی‌کند. آن را با پیام‌های کرنل و شکست اتصال‌های تازه تطبیق دهید.

watch -n 2 'sysctl -n net.netfilter.nf_conntrack_count; sysctl -n net.netfilter.nf_conntrack_max'
sudo conntrack -S
sudo conntrack -C

ابزار conntrack ممکن است نصب نباشد؛ در Debian/Ubuntu از بسته conntrack استفاده کنید. شمارنده‌های insert_failed و drop را در دو نوبت مقایسه کنید؛ افزایش آن‌ها در زمان قطعی، شاهد مهمی است. شمارنده‌ها ممکن است برای هر CPU جداگانه گزارش شوند؛ صرف مشاهده مقدار غیرصفر قدیمی به معنی خطای جاری نیست.

چه چیزی جدول را پر کرده است؟

پرشدن جدول معمولاً از نرخ بالای اتصال‌های جدید، NAT پرترافیک، Retry بدون محدودیت، حملات شبکه یا timeout نامتناسب ناشی می‌شود. قبل از افزایش سقف، الگوی ترافیک و سرویس مبدأ را بررسی کنید.

sudo conntrack -S
sudo ss -s
sudo ss -tan state established | head -n 30
sudo journalctl -k --since '30 minutes ago' | grep -i conntrack

ss فقط سوکت‌های قابل مشاهده در فضای نام فعلی را نشان می‌دهد و جایگزین مشاهده جدول Conntrack نیست. روی NAT Gateway ممکن است بخش عمده Flowها متعلق به کلاینت‌های پشت روتر باشند. از اجرای بی‌محابای conntrack -L روی جدول بسیار بزرگ خودداری کنید، چون خروجی و بار پردازشی زیادی ایجاد می‌کند.

بررسی timeoutها بدون قطع اتصال کاربران

زمان ماندگاری Flowهای TCP، UDP و وضعیت‌های مختلف یکسان نیست. مقادیر واقعی سیستم را بخوانید و فقط اگر شواهدی از نگهداری طولانی اتصال‌های بلااستفاده دارید، سراغ تنظیم اختصاصی بروید.

sysctl net.netfilter.nf_conntrack_tcp_timeout_established
sysctl net.netfilter.nf_conntrack_udp_timeout
sysctl net.netfilter.nf_conntrack_udp_timeout_stream

کاهش شدید timeout ممکن است اتصال‌های سالم، مخصوصاً نشست‌های کم‌ترافیک، را مختل کند. ابتدا Connection Pooling، Keep-Alive، Retry و نرخ ایجاد اتصال در برنامه را اصلاح کنید. اگر مشکل مربوط به تمام‌شدن پورت موقت است، راهنمای عیب‌یابی Ephemeral Port Exhaustion را ببینید؛ این دو مشکل یکسان نیستند.

افزایش امن nf_conntrack_max

اگر اشباع تأیید شده، علت ترافیک بررسی شده و RAM کافی دارید، سقف را به‌صورت موقت افزایش دهید. عدد زیر صرفاً نمونه است و نباید بدون بررسی روی همه سرورها اعمال شود.

OLD_MAX=$(sysctl -n net.netfilter.nf_conntrack_max)
printf 'Previous max: %sn' "$OLD_MAX"
sudo sysctl -w net.netfilter.nf_conntrack_max=262144
sysctl -n net.netfilter.nf_conntrack_max

اگر سقف فعلی بالاتر از 262144 است، این دستور را اجرا نکنید چون باعث کاهش ظرفیت می‌شود. مقدار جدید را بر اساس مصرف واقعی، ظرفیت حافظه و بار شبکه تعیین کنید. افزایش تعداد ورودی‌ها مصرف حافظه کرنل را بیشتر می‌کند؛ مقدار RAM مصرفی هر Flow ثابت و مستقل از نسخه کرنل نیست.

پس از تأیید در Maintenance Window، می‌توانید تنظیم پایدار را در فایلی اختصاصی مانند /etc/sysctl.d/90-nf-conntrack.conf قرار دهید:

net.netfilter.nf_conntrack_max = 262144

برای اعمال فایل مشخص:

sudo sysctl -p /etc/sysctl.d/90-nf-conntrack.conf

پیش از نوشتن فایل، مقدار فعلی و هر تعریف دیگر همین کلید را در /etc/sysctl.conf و /etc/sysctl.d/ بررسی کنید تا تنظیم متناقض نداشته باشید. توضیح بیشتر در آموزش sysctl در لینوکس آمده است.

Verify: از کجا بفهمیم مشکل حل شده؟

در بار کاری مشابه قبل، نسبت count/max، تغییرات drop و insert_failed، زمان پاسخ برنامه و موفقیت اتصال‌های تازه را مقایسه کنید. صرف افزایش سقف و ناپدیدشدن موقت پیام خطا برای تأیید کافی نیست.

sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
sudo conntrack -S
sudo journalctl -k --since '10 minutes ago' | grep -i conntrack
free -h

اگر پس از افزایش سقف همچنان count سریع رشد می‌کند، احتمالاً ریشه مشکل نرخ اتصال یا تنظیم برنامه است. در محیط‌هایی با مسیریابی نامتقارن، بررسی rp_filter و مسیر برگشت نیز می‌تواند به تفکیک علت قطع ارتباط کمک کند.

Rollback و نکات امنیتی

برای برگشت، مقدار ثبت‌شده پیش از تغییر را با sysctl -w بازگردانید و اگر فایل پایدار ساخته‌اید آن را اصلاح یا حذف کنید. نمونه زیر را فقط پس از جایگزینی عدد واقعی قبلی اجرا کنید:

sudo sysctl -w net.netfilter.nf_conntrack_max=OLD_VALUE

OLD_VALUE یک جای‌نگهدار است، نه دستور آماده اجرا. اگر تعداد اتصال‌های موجود از سقف قبلی بیشتر است، کاهش سقف را با احتیاط و در پنجره نگهداری انجام دهید. دستورهایی مانند conntrack -F همه ورودی‌ها را حذف می‌کنند و ممکن است NAT و نشست‌های فعال کاربران را مختل کنند؛ برای رفع عادی مشکل از آن استفاده نکنید.

خطاهای رایج در عیب‌یابی

  • افزایش سقف بدون تحلیل: مشکل نرخ بالای اتصال را پنهان می‌کند و مصرف حافظه را بالا می‌برد.
  • تغییر timeout برای همه پروتکل‌ها: می‌تواند ارتباط سالم را قطع کند.
  • اعتماد به یک Snapshot: برای تشخیص Drop فعال، اختلاف شمارنده‌ها را در طول زمان بسنجید.
  • بررسی فقط با ss: در میزبان NAT یا Docker، همه Flowهای رهگیری‌شده را نشان نمی‌دهد.
  • Flush کردن جدول: احتمال قطع ارتباط کاربران و سرویس‌ها را دارد.

پرسش‌های متداول

آیا افزایش nf_conntrack_max همیشه مشکل را رفع می‌کند؟

خیر؛ اگر برنامه یا شبکه بیش از ظرفیت پایدار Flow جدید بسازد، حتی سقف بزرگ‌تر هم پر می‌شود. ابتدا علت افزایش را پیدا کنید.

آیا این خطا همان Too many open files است؟

خیر. nf_conntrack ظرفیت جدول رهگیری اتصال‌های کرنل را نشان می‌دهد، در حالی که Too many open files به محدودیت File Descriptor مربوط است.

آیا ری‌استارت سرویس یا سرور ضروری است؟

برای تغییر موقت nf_conntrack_max با sysctl معمولاً ری‌استارت لازم نیست؛ اما تنظیمات پایدار و رفتار سرویس‌ها را پس از تغییر جداگانه Verify کنید.

مستندات فنی: Linux Kernel nf_conntrack sysctl و conntrack manual. در سرورهای مجازی با بار NAT بالا، ظرفیت منابع سرور مجازی نیز باید متناسب با تعداد اتصال‌های هم‌زمان انتخاب شود.

5/5 - (1 امتیاز)
اشتراک گذاری نوشته در:

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *