همانطور که آدرس های IPv4 کاهش می یابد، بسیاری از اپراتورهای مخابراتی با نیاز به ارائه دسترسی به شبکه با استفاده از ترجمه آدرس به مشتریان خود مواجه می شوند. در این مقاله به شما خواهم گفت که چگونه می توانید عملکرد NAT Grade Carrier را در سرورهای کالا بدست آورید.
کمی از تاریخ
موضوع فرسودگی فضای آدرس IPv4 دیگر جدید نیست. در برخی مواقع، لیستهای انتظار در RIPE ظاهر شدند، سپس مبادلاتی پدید آمدند که در آن بلوکهای آدرس معامله میشد و معاملاتی برای اجاره آنها منعقد میشد. به تدریج اپراتورهای مخابراتی شروع به ارائه خدمات دسترسی به اینترنت با استفاده از ترجمه آدرس و پورت کردند. برخی موفق به دریافت آدرس کافی برای صدور یک آدرس "سفید" برای هر مشترک نشدند، در حالی که برخی دیگر با امتناع از خرید آدرس در بازار ثانویه شروع به صرفه جویی در هزینه کردند. سازندگان تجهیزات شبکه از این ایده حمایت کردند، زیرا این عملکرد معمولاً به ماژولهای افزونه یا مجوزهای اضافی نیاز دارد. به عنوان مثال، در خط روترهای MX Juniper (به جز جدیدترین MX104 و MX204)، می توانید NAPT را روی یک کارت خدمات MS-MIC جداگانه انجام دهید، Cisco ASR1k به مجوز CGN نیاز دارد، Cisco ASR9k به یک ماژول جداگانه A9K-ISM-100 نیاز دارد. و مجوز A9K-CGN -LIC به او. به طور کلی، لذت هزینه زیادی دارد.
IPTables
وظیفه انجام NAT به منابع محاسباتی تخصصی نیاز ندارد، می توان آن را با پردازنده های همه منظوره که به عنوان مثال در هر روتر خانگی نصب می شوند، حل کرد. در مقیاس یک اپراتور مخابراتی، این مشکل را می توان با استفاده از سرورهای کالایی که FreeBSD (ipfw/pf) یا گنو/لینوکس (iptables) اجرا می کنند، حل کرد. ما FreeBSD را در نظر نخواهیم گرفت، زیرا... من مدت زیادی است که استفاده از این سیستم عامل را متوقف کرده ام، بنابراین به گنو/لینوکس می مانیم.
فعال کردن ترجمه آدرس اصلا سخت نیست. ابتدا باید یک قانون در 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
پس از این دستکاری های ساده، یک طرح کاملاً کارآمد به دست می آید که می تواند تعداد زیادی آدرس مشتری را به مجموعه ای از آدرس های خارجی تبدیل کند. با این حال، عملکرد این راه حل چیزهای زیادی برای دلخواه باقی می گذارد. در اولین تلاشم برای استفاده از گنو/لینوکس برای NAT (حدود سال 2013)، توانستم عملکردی در حدود 7 گیگابیت بر ثانیه با سرعت 0.8 مگاپیکسل در هر سرور داشته باشم (Xeon E5-1650v2). از آن زمان، بهینهسازیهای مختلفی در پشته شبکه هسته گنو/لینوکس انجام شده است، عملکرد یک سرور روی همان سختافزار به تقریباً 18-19 گیگابیت بر ثانیه با سرعت 1.8-1.9 Mpps افزایش یافته است (اینها حداکثر مقادیر بودند). ، اما تقاضا برای حجم ترافیک پردازش شده توسط یک سرور بسیار سریعتر رشد کرد. در نتیجه، طرح هایی برای متعادل کردن بار روی سرورهای مختلف ایجاد شد، اما همه اینها پیچیدگی راه اندازی، حفظ و حفظ کیفیت خدمات ارائه شده را افزایش داد.
جداول NF
امروزه، یک روند مد روز در نرم افزار "Shifting Bags" استفاده از DPDK و XDP است. مقالات زیادی در مورد این موضوع نوشته شده است، سخنرانی های مختلفی انجام شده است، و محصولات تجاری ظاهر می شوند (به عنوان مثال، SKAT از VasExperts). اما با توجه به محدودیت منابع برنامه نویسی اپراتورهای مخابراتی، ایجاد هر "محصولی" بر اساس این چارچوب ها به تنهایی کاملاً مشکل است. کار کردن با چنین راه حلی در آینده بسیار دشوارتر خواهد بود؛ به ویژه، ابزارهای تشخیصی باید ایجاد شوند. به عنوان مثال، tcpdump استاندارد با DPDK به همین شکل کار نخواهد کرد، و بستههای ارسال شده به سیمها را با استفاده از XDP «نمیبیند». در میان تمام صحبت ها در مورد فن آوری های جدید برای خروجی ارسال بسته به فضای کاربر، آنها مورد توجه قرار نگرفتند.
ایده اصلی این است که اگر روتر بستههایی را از یک جلسه در هر دو جهت جریان عبور دهد (جلسه TCP به حالت ESTABLISHED رفت)، دیگر نیازی به عبور بستههای بعدی این جلسه از طریق تمام قوانین فایروال نیست، زیرا همه این بررسی ها همچنان با انتقال بسته بیشتر به مسیریابی پایان می یابد. و ما در واقع نیازی به انتخاب مسیر نداریم - ما از قبل می دانیم که به کدام رابط و به کدام میزبان باید بسته ها را در این جلسه ارسال کنیم. تنها چیزی که باقی می ماند ذخیره این اطلاعات و استفاده از آن برای مسیریابی در مراحل اولیه پردازش بسته است. هنگام اجرای NAT، لازم است اطلاعات مربوط به تغییرات آدرس ها و پورت های ترجمه شده توسط ماژول nf_conntrack را نیز ذخیره کنید. بله، البته، در این مورد، پلیس های مختلف و سایر اطلاعات و قوانین آماری در iptable ها از کار می افتند، اما در چارچوب وظیفه یک NAT ایستاده جداگانه یا مثلاً مرز، این مهم نیست، زیرا خدمات در بین دستگاه ها توزیع می شوند.
پیکربندی
برای استفاده از این تابع نیاز داریم:
- از یک هسته تازه استفاده کنید. با وجود این واقعیت که خود عملکرد در هسته 4.16 ظاهر شد، برای مدت طولانی بسیار "خام" بود و مرتباً باعث وحشت هسته می شد. همه چیز در دسامبر 2019 تثبیت شد، زمانی که هسته های LTS 4.19.90 و 5.4.5 منتشر شدند.
- قوانین iptables را در قالب nftables با استفاده از نسخه نسبتاً جدید nftables بازنویسی کنید. دقیقا در نسخه 0.9.0 کار می کند
اگر در اصل همه چیز با نکته اول واضح است، نکته اصلی این است که فراموش نکنید که ماژول را در پیکربندی در هنگام مونتاژ قرار دهید (CONFIG_NFT_FLOW_OFFLOAD=m)، سپس نکته دوم نیاز به توضیح دارد. قوانین nftables کاملاً متفاوت از iptables توصیف می شوند.
پیکربندی 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)، با پیکربندی یکسان، با استفاده از هسته لینوکس یکسان، اما NAT در iptables انجام می دهم، پیوست می کنم. (NAT4) و در nftables (NAT5).
هیچ نموداری از بسته ها در ثانیه در اسکرین شات وجود ندارد، اما در پروفایل بارگذاری این سرورها، اندازه بسته به طور متوسط حدود 800 بایت است، بنابراین مقادیر به 1.5 مگابایت در ثانیه می رسد. همانطور که می بینید، سرور با nftable ها دارای ذخیره عملکرد بزرگی است. در حال حاضر، این سرور تا 30 گیگابیت بر ثانیه با سرعت 3 مگابیت بر ثانیه پردازش می کند و به وضوح می تواند محدودیت فیزیکی شبکه 40 گیگابیت بر ثانیه را برآورده کند، در حالی که منابع CPU رایگان دارد.
امیدوارم این مطالب برای مهندسان شبکه که سعی در بهبود عملکرد سرورهای خود دارند مفید باشد.
منبع: www.habr.com