گیت‌وی‌های VPN با ظرفیت بالا در کنار تونل‌های اصلی UDP، همواره درگاه‌های مبتنی بر پروتکل TCP را نیز فعال نگه می‌دارند. در شبکه‌های سازمانی که ترافیک UDP با سخت‌گیری فیلتر می‌شود، پروتکل TCP به عنوان مسیر پشتیبان پایدار، کانال کنترل و بستر انتقال ترافیک رمزنگاری‌شده TLS به کار گرفته می‌شود. باز بودن پورت‌های عمومی مانند 443 سرورها را در معرض حملات توزیع‌شده سیل‌آسای TCP SYN Flood قرار می‌دهد.

اگرچه کارت‌های شبکه امروزی توانایی هدایت میلیون‌ها بسته در ثانیه را دارند، معماری سنتی ردیابی اتصالات در لینوکس (conntrack) در برابر چنین هجمه‌هایی آسیب‌پذیر است. اختصاص حافظه برای ثبت وضعیت اتصال قبل از تایید هویت کاربر، جدول وضعیت را به سرعت اشباع می‌کند. برای رفع قطعی این چالش، حذف وضعیت در فاز دست‌دهی اولیه به کمک قابلیت nftables SYNPROXY در لینوکس ضروری است.

درک عملکرد SYNPROXY مستلزم ارزیابی مسیر پردازش بسته‌ها در زیرسیستم Netfilter هسته لینوکس است.

خطر اشباع جدول ردیابی اتصال conntrack:
ترافیک SYN Flood ──> کارت شبکه (NIC) ──> بخش Netfilter PREROUTING ──> تخصیص حافظه (struct nf_conn)
                                                                                  │
                                                                   اشباع کامل جدول (nf_conntrack: table full)
                                                                                  │
                                                                       قطع کامل ارتباط (حذف همه اتصال‌ها)

─────────────────────────────────────────────────────────────────────────────────────────────────────────────

فیلترینگ بدون حالت با nftables SYNPROXY:
ترافیک SYN Flood ──> مسیر PREROUTING (notrack) ──> بخش INPUT (SYNPROXY) ──> پاسخ بی‌استیت SYN-ACK (Syncookie)
                                                                                  │
                                                                 (بدون مصرف رم / بدون ایجاد وضعیت)
                                                                                  │
ارسال ACK معتبر توسط کلاینت ──────────────────────────────────> تایید Syncookie ──> ثبت در conntrack ──> دیمن VPN

گلوگاه conntrack: محدودیت کوکی‌های سوکت سیستم‌عامل

بسیاری از متخصصان گمان می‌کنند فعال‌سازی net.ipv4.tcp_syncookies = 1 برای ایمن‌سازی کامل در برابر حملات کافی است. در عمل، مکانیزم کوکی در سطح سوکت فقط از صف انتظار سوکت برنامه (listen(backlog)) محافظت می‌کند و هیچ حفاظتی برای ماژول ردیابی اتصالات Netfilter یعنی nf_conntrack ارائه نمی‌دهد.

در پشته شبکه لینوکس، Netfilter در نقطه اتصال NF_INET_PRE_ROUTING بسته‌ها را پردازش می‌کند که بسیار جلوتر از پشته انتقال محلی (NF_INET_LOCAL_IN) قرار دارد. با دریافت هر بسته با پرچم SYN، ماژول nf_conntrack یک ساختار struct nf_conn ساخته و آن را در وضعیت SYN_RECV وارد جدول هش می‌کند:

ورود بسته ──> nf_conntrack_in() ──> init_conntrack() ──> kmem_cache_alloc(nf_conntrack_cachep)

هر ورودی حدود ۳۲۰ تا ۳۸۴ بایت از حافظه اسلب هسته را مصرف می‌کند. با سقف پیش‌فرض ۲۶۲,۱۴۴ ورودی، هجومی با شدت ۳۰۰,۰۰۰ بسته در ثانیه، کل جدول را در کمتر از ۹۰۰ میلی‌ثانیه پر می‌کند.

پیامدهای پر شدن جدول اتصالات:

  1. ثبت خطای مکرر net_ratelimit: nf_conntrack: table full, dropping packet در هسته.
  2. قطعی بلافاصله تمامی تونل‌های فعال و رد شدن تلاش‌های کاربران مجاز.
  3. افزایش بار پردازنده به علت جستجوی مداوم در سطل‌های پرشده هش.

از آنجا که اعتبارسنجی سوکت در تابع tcp_v4_rcv() پس از شکست تخصیص حافظه در conntrack واقع شده، هرگز فرصت اجرا پیدا نمی‌کند. بنابراین اعتبارسنجی باید پیش از ردیابی وضعیت صورت گیرد.

معماری درونی Netfilter SYNPROXY

ماژول synproxy که در مسیر net/netfilter/nf_synproxy_core.c پیاده‌سازی شده و از طریق nftables مدیریت می‌شود، به عنوان یک پروکسی معکوس بدون حالت در سطح هسته لینوکس عمل می‌کند. این ماژول اتصال را به دو مرحله تفکیک می‌کند: دست‌دهی خارجی بدون ثبت وضعیت با کلاینت، و سپس دست‌دهی داخلی با نرم‌افزار سرور.

کاربر خارجی                             nftables SYNPROXY                        سرویس محلی VPN
     │                                         │                                       │
     │─── ۱. بسته TCP SYN [MSS, WScale] ──────>│ (بدون حالت، بدون اشغال حافظه)         │
     │                                         │                                       │
     │<── ۲. پاسخ بی‌استیت SYN-ACK [Cookie] ───│ (هش رمزنگاری از مشخصات ۴گانه و ISN)   │
     │                                         │                                       │
     │─── ۳. پاسخ TCP ACK [Cookie + 1] ───────>│                                       │
     │                                         │─── ۴. ایجاد TCP SYN محلی ────────────>│
     │                                         │<── ۵. پاسخ SYN-ACK محلی [ISN سرور] ───│
     │                                         │─── ۶. پاسخ ACK محلی ─────────────────>│
     │                                         │                                       │
     │═════════════════════════════════════════╪═══════════════════════════════════════│
     │            فاز تبادل داده و اصلاح برخط آفست شماره‌های ترتیبی در سطح سخت‌افزاری    │
     │─── ۷. داده‌های کاربری TLS ─────────────>│─── ۸. بازنویسی SEQ/ACK (مقدار دلتا) ─>│
     │<── ۱۰. بازنویسی SEQ/ACK (مقدار دلتا) ───│<── ۹. پاسخ داده‌ها ──────────────────│

مراحل پردازش شامل چهار بخش زیر است:

گام اول: مستثنی‌سازی از ردیابی وضعیت

بسته‌های ورودی SYN به مقصد پورت VPN با دستور notrack در جدول prerouting علامت‌گذاری می‌شوند تا حافظه‌ای در conntrack برای آن‌ها رزرو نشود.

گام دوم: تولید کوکی بدون حالت

بسته به زنجیره INPUT و ماژول SYNPROXY هدایت می‌شود. ماژول بدون ارسال بسته به سوکت، شماره ترتیبی اولیه (ISN) را با تابع هش امن بر مبنای مقادیر زیر محاسبه می‌کند:

  • آدرس‌های آی‌پی مبدا و مقصد
  • پورت‌های مبدا و مقصد
  • شماره ترتیبی ارسالی کلاینت
  • کلید مخفی هسته که هر ۶۰ ثانیه نوسازی می‌شود
  • ویژگی‌های فشرده‌شده TCP نظیر MSS، مقیاس پنجره و قابلیت SACK

پاسخ SYN-ACK حاوی کوکی بلافاصله بازگردانده می‌شود، بدون آنکه حافظه یا تایمری در هسته تخصیص یابد. بسته‌های جعلی در همین نقطه خنثی می‌شوند.

گام سوم: تایید پاسخ ACK و ثبت وضعیت

کلاینت واقعی با بسته ACK حاوی شماره ترتیبی Cookie + 1 پاسخ می‌دهد. ماژول SYNPROXY درستی هش را ارزیابی می‌کند.

با تایید اصالت اتصال:

  • ساختار struct nf_conn در conntrack تشکیل می‌شود.
  • اتصال مستقیما به وضعیت ESTABLISHED ارتقا می‌یابد.
  • ویژگی‌های اتصال از کوکی بازیابی می‌شوند.

گام چهارم: دست‌دهی محلی و انطباق آفست

به دلیل نیاز نرم‌افزار سرور به دست‌دهی متعارف TCP، ماژول SYNPROXY یک بسته SYN محلی به سمت سوکت ارسال می‌کند.

با دریافت SYN-ACK از نرم‌افزار با شماره ترتیبی اختصاصی سرور (ISN_server)، اختلاف محاسبه می‌شود:

$$\Delta = ext{ISN}_{ ext{server}} - ext{Cookie}$$

از این پس در تمامی بسته‌های تبادلی، هدرها به صورت بلادرنگ اصلاح می‌شوند:

  • در ترافیک ورودی: افزودن مقدار $\Delta$ به شماره ترتیبی (SEQ).
  • در ترافیک خروجی: کاستن مقدار $\Delta$ از شماره تایید (ACK).

این روند بدون تاخیر در لایه هسته و شفاف برای نرم‌افزار اجرا می‌شود.

پیاده‌سازی عملیاتی: تنظیمات فایروال nftables SYNPROXY

پیکربندی کامل برای پورت 443 به صورت زیر تدوین می‌شود:

#!/usr/sbin/nft -f

flush ruleset

table inet vpn_filter {
    synproxy synproxy_vpn {
        mss 1460
        wscale 7
        timestamp sack-perm
    }

    chain raw_prerouting {
        type filter hook prerouting priority raw; policy accept;
        tcp dport 443 tcp flags syn notrack
    }

    chain filter_input {
        type filter hook input priority filter; policy drop;

        iif "lo" accept
        ct state established,related accept
        ct state invalid drop

        tcp dport 443 synproxy config synproxy_vpn
        tcp dport 443 ct state new accept
    }

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

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

اعمال پیکربندی در لینوکس:

sudo nft -f /etc/nftables.conf

بررسی قوانین جاری:

sudo nft list table inet vpn_filter

بهینه‌سازی هسته و نظارت بر شاخص‌ها

تنظیم پارامترهای سیستمی در فایل /etc/sysctl.d/99-synproxy.conf:

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_timestamps = 1
net.netfilter.nf_conntrack_tcp_loose = 0
net.netfilter.nf_conntrack_max = 2097152
net.netfilter.nf_conntrack_buckets = 524288
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 10
net.netfilter.nf_conntrack_tcp_timeout_established = 3600

بارگذاری پارامترها:

sudo sysctl --system

پایش بلادرنگ آمار عملکرد

بررسی شمارنده‌ها از طریق مسیر /proc:

cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/net/stat/synproxy

شاخص‌های اصلی:

  • entries: شمار اتصالات فعال تحت مدیریت SYNPROXY.
  • syn_received: کل بسته‌های SYN مدیریت‌شده به صورت بی‌استیت.
  • cookie_invalid: بسته‌های ACK نامعتبر ردشده.
  • cookie_valid: اتصالات تاییدشده و انتقال‌یافته به conntrack.

نقش راهکار در معماری شبکه RiceGuard

امنیت پایدار بر تاب‌آوری تمامی پروتکل‌ها استوار است. با وجود اتکای پروتکل RiceGuard بر بستر UDP و اعتبارسنجی کوکی‌های رمزنگاری‌شده، درگاه‌های سرور پورت‌های TCP را برای تعامل در شبکه‌های محدود و پرس‌وجوهای امن DNS روی HTTPS در دسترس نگه می‌دارند.

استقرار nftables SYNPROXY در لبه شبکه، ظرفیت مقاومت زیرساخت RiceGuard را در برابر سیل داده‌های مخرب حفظ کرده و تداوم تبادل پایدار ترافیک کاربران را تضمین می‌کند.

دریافت VPNRice