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

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

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

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

[إيبتبلس]

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

تمكين ترجمة العناوين ليس بالأمر الصعب على الإطلاق. تحتاج أولاً إلى تسجيل قاعدة في 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). منذ ذلك الوقت، تم إجراء العديد من التحسينات المختلفة في مكدس شبكة نواة جنو/لينكس، وزاد أداء خادم واحد على نفس الجهاز إلى ما يقرب من 18-19 جيجابت/ثانية بمعدل 1.8-1.9 ميجابت في الثانية (كانت هذه القيم القصوى). ، ولكن الطلب على حجم حركة المرور، التي تتم معالجتها بواسطة خادم واحد، نما بشكل أسرع بكثير. ونتيجة لذلك، تم تطوير المخططات لموازنة الحمل على خوادم مختلفة، ولكن كل هذا زاد من تعقيد إعداد وصيانة والحفاظ على جودة الخدمات المقدمة.

NTFables

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

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

ترتيب

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

  • استخدم نواة طازجة. على الرغم من حقيقة أن الوظيفة نفسها ظهرت في kernel 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 وتفريغ التدفق. أسطورة صغيرة على سبيل المثال: , - هذه هي واجهات الشبكة التي تمر عبرها حركة المرور، وفي الواقع يمكن أن يكون هناك أكثر من اثنتين منها. , - عنوان البداية والنهاية لنطاق العناوين "البيضاء".

تكوين 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).

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

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

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

المصدر: www.habr.com

إضافة تعليق