التوجيه السريع و NAT على Linux

مع استنفاد عناوين IPv4 ، يواجه العديد من مشغلي الاتصالات الحاجة إلى تنظيم وصول عملائهم إلى الشبكة باستخدام ترجمة العنوان. في هذه المقالة سأخبرك بكيفية الحصول على أداء مستوى NAT Carrier Grade على خوادم السلع.

القليل من التاريخ


لم يعد موضوع نفاد مساحة عنوان IPv4 جديدًا. في وقت ما ، ظهرت قوائم الانتظار في RIPE ، ثم كانت هناك تبادلات تم فيها تداول مجموعات من العناوين وإبرام معاملات لإيجارها. بدأ مشغلو الاتصالات تدريجياً في تقديم خدمات الوصول إلى الإنترنت من خلال ترجمة العناوين والمنافذ. لم ينجح شخص ما في الحصول على عناوين كافية لإعطاء عنوان "أبيض" لكل مشترك ، بينما بدأ شخص ما في توفير المال من خلال رفض شراء العناوين في السوق الثانوية. دعمت الشركات المصنعة لمعدات الشبكة هذه الفكرة كما تتطلب هذه الوظيفة عادةً وحدات أو تراخيص توسيع إضافية. على سبيل المثال ، مع وجود Juniper في تشكيلة موجه MX (باستثناء أحدث MX104 و MX204) ، يمكن تنفيذ NAPT على بطاقة خدمة MS-MIC منفصلة ، يتطلب Cisco ASR1k ترخيص GN ،على Cisco ASR9k ، وحدة A9K-ISM-100 منفصلة ورخصة A9K-CGN-LIC لها. بشكل عام ، المتعة تكلف الكثير من المال.

يبتلس


لا تتطلب مهمة تنفيذ NAT موارد حوسبة متخصصة ؛ يمكن للمعالجات ذات الأغراض العامة التي يتم تثبيتها ، على سبيل المثال ، في أي جهاز توجيه منزلي ، حلها. على مقياس شركة النقل ، يمكن حل هذه المشكلة باستخدام خوادم السلع التي تعمل بنظام FreeBSD (ipfw / pf) أو GNU / Linux (iptables). لن نفكر فري ، لأنه لقد رفضت استخدام نظام التشغيل هذا لفترة طويلة ، لذا دعنا نركز على جنو / لينكس.

ليس من الصعب على الإطلاق تشغيل ترجمة العنوان. تحتاج أولاً إلى كتابة القاعدة في iptables في جدول nat:

iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j SNAT --to <pool_start_addr>-<pool_end_addr> --persistent

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

net.ipv4.ip_forward = 1
net.ipv4.ip_local_port_range = 8192 65535

net.netfilter.nf_conntrack_generic_timeout = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 45
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.netfilter.nf_conntrack_icmpv6_timeout = 30
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.netfilter.nf_conntrack_checksum=0

وثانيًا ، نظرًا لأن الحجم الافتراضي لجدول الترجمة غير مصمم للعمل في ظروف مشغل الاتصالات ، يجب زيادته:

net.netfilter.nf_conntrack_max = 3145728

من الضروري أيضًا زيادة عدد المجموعات لجدول التجزئة الذي يخزن جميع الترجمات (هذا هو خيار وحدة nf_conntrack):

options nf_conntrack hashsize=1572864

بعد هذه التلاعبات البسيطة ، يتم الحصول على بناء يعمل بشكل كامل ، والذي يمكن أن يترجم عددًا كبيرًا من عناوين العملاء إلى تجمع خارجي. ومع ذلك ، فإن أداء هذا الحل ضعيف. في محاولاتي الأولى لاستخدام GNU / Linux لـ NAT (حوالي 2013) ، تمكنت من الحصول على أداء 7 جيجابت / ثانية بسرعة 0.8 ميجابت في الثانية لكل خادم (Xeon E5-1650v2). منذ ذلك الوقت ، تم إجراء العديد من التحسينات المختلفة في مكدس شبكة GNU / Linux kernel ، وزاد أداء خادم واحد على نفس الجهاز تقريبًا إلى 18-19 جيجابت / ثانية عند 1.8-1.9 ميجا بت في الثانية (كانت هذه هي القيم الحدية) ، ولكن الحاجة إلى حجم حركة المرور ، معالجتها بواسطة خادم واحد ، نمت بشكل أسرع. ونتيجة لذلك ، تم تطوير مخططات موازنة التحميل لخوادم مختلفة ، ولكن كل هذا زاد من تعقيد الإعداد ،خدمة والحفاظ على جودة الخدمات المقدمة.

نفتابلز


في الوقت الحاضر ، يعد استخدام DPDK و XDP اتجاهًا عصريًا في برنامج "نقل الحزم". تمت كتابة العديد من المقالات حول هذا الموضوع ، وتم عمل العديد من العروض التقديمية المختلفة ، وتظهر المنتجات التجارية (على سبيل المثال ، SKAT من VasExperts). ولكن في ظروف الموارد المحدودة للمبرمجين من مشغلي الاتصالات ، من الصعب جدًا قطع "حصة" من نوع ما على أساس هذه الأطر. لتشغيل مثل هذا الحل في المستقبل سيكون أكثر صعوبة ، على وجه الخصوص ، سيكون من الضروري تطوير أدوات التشخيص. على سبيل المثال ، لا يعمل tcpdump العادي مع DPDK ، ولن "يرى" الحزم المرسلة إلى الأسلاك باستخدام XDP. وفي خضم كل هذا الحديث عن تقنيات جديدة لإخراج توجيه الحزمة إلى المستخدم الفضاء، تقارير و مقالات ذهبت دون أن يلاحظها أحدبابلو نيرا أيوسو ، مشرف iptables ، على تطوير تفريغ التدفق في nftables. دعونا نلقي نظرة على هذه الآلية بمزيد من التفصيل.

الفكرة الرئيسية هي أنه إذا مرر جهاز التوجيه حزم جلسة واحدة على جانبي الدفق (تحولت جلسة TCP إلى الحالة ESTABLISHED) ، فلن تكون هناك حاجة لتمرير الحزم اللاحقة لهذه الجلسة من خلال جميع قواعد جدار الحماية ، لأن كل هذه الفحوصات ستنتهي جميعها عن طريق نقل الحزمة إلى التوجيه. نعم ، والواقع أن اختيار المسار لا يحتاج إلى إجراء - فنحن نعرف بالفعل الواجهة وواجهة المضيف التي يجب إعادة توجيه الحزم خلال هذه الجلسة. يبقى فقط لحفظ هذه المعلومات واستخدامها للتوجيه في مرحلة مبكرة من معالجة الحزم. عند إجراء NAT ، من الضروري أيضًا حفظ المعلومات حول التغييرات في العناوين والمنافذ المحولة بواسطة وحدة nf_conntrack. نعم ، بالطبع ، في هذه الحالة ، توقف العديد من المحاضرين وقواعد إحصائية المعلومات الأخرى في iptables عن العمل ،ولكن كجزء من مهمة NAT الدائمة المنفصلة أو ، على سبيل المثال ، الحدود ، فهذا ليس مهمًا جدًا ، لأن الخدمات موزعة عبر الأجهزة.

ترتيب


لاستخدام هذه الوظيفة نحتاج إلى:

  • استخدم نواة جديدة. على الرغم من حقيقة أن الوظيفة نفسها ظهرت في نواة 4.16 ، إلا أنها كانت "خامًا" لفترة طويلة وكانت تسمى بشكل دوري ذعر النواة. استقر كل شيء في ديسمبر 2019 تقريبًا ، عندما تم إصدار نواة LTS 4.19.90 و 5.4.5.
  • إعادة كتابة قواعد iptables بتنسيق nftables باستخدام إصدار حديث إلى حد ما من nftables. يعمل بشكل جيد في الإصدار 0.9.0

إذا كان كل شيء واضحًا من حيث المبدأ مع الفقرة الأولى ، فإن الشيء الرئيسي هو عدم نسيان تضمين الوحدة النمطية في التكوين أثناء التجميع (CONFIG_NFT_FLOW_OFFLOAD = m) ، فإن الفقرة الثانية تتطلب شرحًا. يتم وصف قواعد nftables بشكل مختلف تمامًا عن قواعد iptables. تكشف الوثائق عن جميع النقاط تقريبًا ، وهناك أيضًا محولات قواعد خاصة من iptables إلى nftables. لذلك ، سأعطي فقط مثالًا على إعداد NAT وإلغاء تحميل التدفق. وسيلة إيضاح صغيرة لمثال: <i_if> ، <o_if> هي واجهات الشبكة التي تمر من خلالها حركة المرور ، في الواقع يمكن أن يكون هناك أكثر من اثنين. <pool_addr_start> ، <pool_addr_end> - عنوان البداية والنهاية لنطاق العناوين "البيضاء".

تكوين NAT بسيط للغاية:

#! /usr/sbin/nft -f

table nat {
        chain postrouting {
                type nat hook postrouting priority 100;
                oif <o_if> snat to <pool_addr_start>-<pool_addr_end> persistent
        }
}

يعد تفريغ التدفق أكثر تعقيدًا بعض الشيء ، ولكنه مفهوم:
#! /usr/sbin/nft -f

table inet filter {
        flowtable fastnat {
                hook ingress priority 0
                devices = { <i_if>, <o_if> }
        }

        chain forward {
                type filter hook forward priority 0; policy accept;
                ip protocol { tcp , udp } flow offload @fastnat;
        }
}

هذا ، في الواقع ، هو الإعداد بأكمله. الآن ستذهب كل حركة مرور TCP / UDP إلى جدول fastnat وستتم معالجتها بشكل أسرع.

النتائج


لتوضيح مدى سرعة "هذا بكثير" ، سأرفق لقطة شاشة للحمل على خادمين حقيقيين بنفس الجهاز (Xeon E5-1650v2) ، تمت تهيئتهما بنفس القدر ، باستخدام نفس نواة Linux ، ولكن تشغيل NAT في iptables (NAT4) وفي nftables (NAT5).



لا يوجد رسم بياني للحزم في الثانية في لقطة الشاشة ، ولكن في ملف تعريف التحميل لهذه الخوادم ، يبلغ متوسط ​​حجم الحزمة حوالي 800 بايت ، لذلك ترتفع القيم إلى 1.5 ميجا بت في الثانية. كما ترى ، فإن هامش أداء الخادم مع nftables ضخم. في الوقت الحالي ، يعالج هذا الخادم ما يصل إلى 30 جيجابت / ثانية بسرعة 3 ميجابت في الثانية ، ومن الواضح أنه قادر على تشغيل القيود المادية لشبكة 40 جيجابت في الثانية ، مع وجود موارد وحدة المعالجة المركزية المجانية.

آمل أن تكون هذه المادة مفيدة لمهندسي الشبكات الذين يحاولون تحسين أداء خوادمهم.

All Articles