اصل ماجرا
تیم امنیتی Cloudflare با تغییر معماری پردازش پیامها، بهینهسازی کوئریهای پایگاهداده و اصلاح توزیع بار API، توانست ظرفیت اسکن را از ۱۰ به بیش از ۱۲۰ درخواست در ثانیه برساند. این بهروزرسانی باعث شد اسکنهای خودکار برای همه حسابها فعال شود و فرکانس اسکن برای همه کاربران دو برابر شود.
متن کامل ترجمهشده
Security Insights توصیه های امنیتی را برای هر حساب Cloudflare ارائه می دهد. برای پیدا کردن این اطلاعات، ما به طور منظم برای تمام حساب های، منطقه ها و رکورد های DNS اسکن می کنیم، به دنبال خطرات امنیتی و اختلالات احتمالی. با این حال، دو مشکل کلیدی ظاهر شد. اول، اسکن های ما بسیار نادر بودند. اسکن ها تنها هر هفته یا دو بار انجام می شد، و بنابراین خطرات امنیتی تازه وارد شده ممکن است تا دو هفته بدون تشخیص باقی بماند. دوم، اسکن اتوماتیک برای بسیاری از حساب های برنامه رایگان انتخاب شده است - به این معنی که بسیاری از حساب ها به طور کلی اسکن نمی شوند. خطرات اسکن های نادر یا وجود ندارد افزایش می یابد: به عنوان حملات خودکار سرعت می دهند، پنجره برای تشخیص اختلالات امنیتی کاهش می یابد. اطمینان حاصل کنید که ما این مسائل را برای همه مشتریان ما پیدا می کنیمما محاسبه کردیم که برای افزایش فرکانس اسکن و فعال کردن اسکن اتوماتیک برای تمام حساب ها، ما نیاز به افزایش سرعت اسکن خود را در حدود 10x در متوسط از 10 اسکن در ثانیه به 100 در ثانیه داشتیم. اما سیستم ما در حال حاضر با وزن آن مبارزه می کرد: میلیون ها رویداد ما را پر می کنند که منتظر پردازش هستند؛ API ما اغلب زمان می رفت؛ فرآیند های ما سقوط می کردند. ما نیاز به اصلاح سیستم ما داشتیم، و ما نیاز به گسترش آن داشتیم. این داستان از چگونگی افزایش سرعت اسکن برای Security Insights با بیش از 10x، دسترسی به اطلاعات امنیتی برای میلیون ها مشتری و دو برابر سرعت اسکن ما برای همه مشتریان است. در ادامه بخوانید تا بدانید که چگونه ما این بهبود ها را به دست آورده ایم. چگونه برای اطلاعات امنیتی اسکن می کنیم.هنگامی که یک حساب یا منطقه برای اسکن انجام می شود، برنامه نویسی یک پیام (یا پیام) را به Apache Kafka، یک پلتفرم پخش رویداد با منبع باز منتشر می کند، منتشر می کند. این پیام ها به تعدادی از چک ها فرود می آیند: مایکروسافت های تخصصی Go که منابع یا تنظیمات خاصی را اسکن می کنند. برای هر پیام، هر چک نتایج خود را (به اطلاعات امنیتی که پیدا کرده) به API داخلی ما می فرستد، که سپس این ها را در یک پایگاه داده Postgres باقی می گذارد. Apache Kafka به طور کامل یک رقیب نیست: این یک جریان رویداد جداگانه است (مگر به تازگی در رقیب به دست آورده شده است). در یک پارتیشن، پیام ها باید به طور منظم مصرف و پردازش شود. این از رقیب های معمول متفاوت است که دراین دو نتیجه برای ما دارد: - پیام هایی که به آرامی پردازش می کنند ، مصرف کننده را از پیشرفت به پیام بعدی جلوگیری می کند - برای هر چکر ، ما فقط می توانیم مقدار زیادی از مصرف کنندگان را داشته باشیم که قسمت ها وجود دارد (هر چکر گروه مصرف کننده خود را دارد ) ما می توانستیم با اضافه کردن بیشتر قسمت ها به اندازه گیری برسیم. با این حال ، این باعث افزایش استفاده از منابع برای خود بروکر Kafka می شود ، که توسط بسیاری از خدمات دیگر به اشتراک گذاشته می شود. ما این را به عنوان یک راه حل نهایی ، با هدف بهبود کد و معماری ما در ابتدا. معرفی پردازش paralel اگرچه ما فقط می توانیم پیام ها را در ترتیب مصرف کنیم ، هیچ چیز ما را از مصرف چند پیام در یک زمان متوقف نمی کند. ما چکرهای خود را برای مصرف پیام ها در گروه ها تغییر دادیم ، هر پیام را در یک Goroutineدر مورد ما، این دو مورد پذیرفته می شدند. اجتناب از بلاک کردن سر خط برخی از پیام های پردازش شده توسط برخی از چک های ما طولانی تر از دیگران است. به عنوان مثال، یک حساب یا منطقه ممکن است دارایی های بسیار بیشتر از یک دیگر داشته باشد. در بدترین صورت، این پیام ها ممکن است چند دقیقه یا ساعت طول بکشد تا پردازش شود در مقایسه با یک مورد متوسط ثانیه یا میلی ثانیه. ما یک رویکرد بسیار ساده را انتخاب کردیم: تقسیم گروه های مصرف کننده و چک های ما را به دو دسته تقسیم می کنیم - آهسته و آهسته. ما می توانیم به سرعت تعیین کنیم که آیا یک پیام به آهسته یا سریع پردازش می شود. اگر آهسته چک یک پیام را ملاقات می کند، آن را از بین می برد. این مشکل را حل کرد: پیام های آهسته دارای منابع اختصاصی و برای پردازش با تاخیر کمهر آگاهی که ما پیدا می کنیم به پایگاه داده Postgres ما نوشته می شود. این توسط یک نقطه پایانی API است که چککاران ما با یک لیست آگاهی دعوت می کنند. اجرای به این شکل بود: برای _, موضوع := مسائل سطح { _, err = tx.Exec(ctx, INSERT INTO table ... VALUES ($1, $2, ...) ON CONFLICT DO UPDATE ..., …) اگر err != nil { return err } } خواننده هوشمندانه متوجه خواهد شد که برای مجموعه های بزرگ آگاهی، این کد یک سفر دور به پایگاه داده برای هر آگاهی انجام می دهد. با حداکثر اندازه مشاهده شده 500،000، این نیم میلیون سفر دور، سوال و معاملات در یک تماس API بود. ما ابتدا استاندارد طلا برای آگهی های بزرگ در Postgres: COPY به یک جدول موقت امتحان کردیم. با این حال، ما متوجه شدیمما در یک رویکرد هیبریدی قرار گرفتیم: این بهترین از هر دو جهان را ارائه داد: واردات به اندازه کافی سریع برای مجموعه های گسترده ای از اطلاعات ( ثانیه ها) و حتی واردات سریع تر (ملیس ثانیه ها) برای مجموعه های کوچک از اطلاعات. بررسی زمان های API ما ما برخی از رفتار های عجیب در API داخلی ما را در حالی که ما سعی می کردیم به اندازه گیری: - تعداد زیادی از درخواست ها باعث زمان های دور از مشتری - بسیاری از چک ها 20-90٪ از زمان پردازش خود را در یک تماس API واحد صرف می کردند - هنگامی که یک حجم بزرگ از اسکن ها را تحریک می کنیم، انتقال ما شروع می شود و بدتر می شود.به عنوان یک نتیجه از این تاثیرات، درخواست های پایگاه داده از آستردام API زمان زیادی طول کشید، به طوری که اتصالات از کمربند اتصال مشتری ما باز می شد. با حجم زیادی از درخواست هایی که ما به API انجام می دادیم، کمربند اتصال به سرعت پر شده بود، که منجر به زمان انتظار برای اتصال رایگان شد. اتصال API متوسط ما در 10 ms در Portland، اما تقریبا 3 ثانیه در Amsterdam! اما چرا کاهش انتقال پیام؟ هر فرایند چک یک مجموعه از پارتیشن ها از جریان Kafka برای مصرف اختصاص داده می شود. API ما توازن بار است. از آنجایی که ما اتصال را در طول زندگی فرایند باز نگه داریم، برخی از فرایندها اتصال به آستردام API داشتند و دیگران اتصال به Portland API داشتند.پارتیشن های مرتبط با پورتلند به سرعت پردازش شدند، اما آنهایی که توسط فرآیندهای مربوط به آمستردام مصرف می شدند، پشت می شدند: Kafka lag (مجموع پیام های منتظر پردازش در یک گروه مصرف کننده واحد) توسط پارتیشن برای یکی از چک های ما. توجه داشته باشید که ما در این مورد 30 پارتیشن داریم. دقیقا 15 پارتیشن می توان مشاهده کرد که پشت می شوند (جایز هایی که بعد از ساعت 03/10 03:00 تا 0 برسند). این به این دلیل است که توازنگر بارگیری ترافیک را به طور مساوی بین نقاط پایانی API ما تقسیم می کند. این یک اصلاح ساده بود: ما API خود را به فعال-پاسیزو تبدیل کردیم، اطمینان حاصل کنید که API فعال از پایگاه داده اصلی ما پیروی می کرد. مشکلات تنگی ما در طول شب ناپدید شدند. Weâdاین امکان پذیر نبود که همه اسکن های ما را همزمان به دنبال داشته باشیم، زیرا موضوع Kafka ما از یک سیاست نگهداری مبتنی بر زمان استفاده می کرد: اسکن ها در Kafka جمع می شدند و در نهایت حذف می شدند قبل از اینکه بتوانند پردازش شوند. برنامه ریزی ما در توزیع یکسان اسکن های ما خوب نبود. تعداد اسکن هایی که در یک زمان داده می شد، ناخوشایند و غیر قابل پیش بینی بود. در برخی نقاط در طول هفته، صدها هزار اسکن در چند دقیقه از یکدیگر فعال می شد. چه اتفاقی می افتاد؟ برنامه ریزی کننده اسکن ها را در دوره های تکراری ثابت تاسیس می کند.در pseudocode، برنامه نویسی به این شکل بود: Loop Forever: Find accounts where last_scheduled_at + scanning frequency <= now For each account: Trigger scan for account Trigger scan for all zones in account Update last_scheduled_at = now We quickly noticed that last_scheduled_at was similar for a large number of accounts in our database, which was responsible for some of this inequality. However, even with perfectly even distribution, increasing our scanning frequency would have compounded this problem. For example, changing the scanning frequency from every 15 days to every seven days would mean 53% of accounts would suddenly be due to a scan. There was a further problem with this logic.برای حل این مشکلات، ما سه تغییرات کلیدی انجام دادیم: - منطقه های برنامه ریزی مستقل از حساب ها: هر منطقه دارای زمینه last_scheduled_at خود را دریافت می کند. - زمان last_scheduled_at را برای حساب ها و منطقه های موجود تصادفی کنید. - محدودیت نرخ تنظیماتی برای برنامه ریزی اسکن را معرفی کنید. منطقه های برنامه ریزی مستقل یک راه آشکار برای حل مشکل حساب های بزرگ است. تصادفی last_scheduled_at در زمان (و اطمینان حاصل کنید که هیچ اسکن در طول این فرایند تاخیر نشده است) به ما اجازه داد تا عدم تعادل موجود در پایگاه داده ما را اصلاح کنیم. محدودیت نرخ تنظیماتی کمی جالب تر است. محدودیت نرخ را به ما اجازه می دهد تا مشکل افزایش در اسکن ها را در هنگام تغییر فرکانس های اسکن حل کنیم. به عنوان مثال، اگر ما می خواستیمپس از آن، این محدودیت نرخ به ما مجبور می شود 8 روز برای اسکن تمام این حساب ها. این جایی است که بخش متمرکز می آید: محدودیت نرخ هر نیم ساعت متمرکز بر اساس کل تعداد حساب ها و مناطق ما، و فرکانس اسکن ما است. این اطمینان می دهد که ما به دنبال اسکن در زمان حتی اگر ما در هزاران یا میلیون ها حساب و مناطق بیشتر است. func computeRate(free, pro, biz, ent int64) rate.Limit { r := float64(free)/freeScanInterval.Seconds() + float64()/proScanInterval.Seconds() + float64(biz)/bizScanInterval.Seconds() + float64(ent)/ScanInterval.Seconds() // Guard در مقابل عدد های صفر. ما همیشه می خواهیم حداقل یک اسکن در هر ثانیه برنامه ریزی. اگرLimit(r) } با این اصلاحات، متوسط حرکت 7 روزانه ما در طول زمان بیش از 10x افزایش یافته است. قبل از این بهبود، ما حدود 10 اسکن در هر ثانیه انجام می دادیم. تفاوت بین این و هدف ما از 100 اسکن در هر ثانیه به نظر می رسید بزرگ است. ما در مورد استفاده از منابع بیشتری در مورد مشکل صحبت کردیم، فرستادن بخش های بیشتری در موضوع Kafka ما - حتی فرستادن تمام معماری ما. اما اصلاحات ما همه تفاوت را ایجاد کرده است. امروز، Security Insights بیش از 120 اسکن در هر ثانیه در طول برنامه ریزی بالا را حفظ می کند، بیش از هدف بهبود 10x ما. API داخلی ما دیگر زمان نمی گذارد، و متریکات کافا ما به نظر می رسد بسیار سالم تر. این بهبود های گسترش را به ما اجازه داده است که اسکن اتوماتیک برای تمام حساب های رایگان و مناطق و افزایش سرعت اسما توانایی انجام اسکن های عمیق بر اساس درخواست را اضافه کرده ایم. اکنون شما می توانید حساب Cloudflare، منطقه، بصری، یا نوع بصری را به صورت دستی دوباره اسکن کنید. شروع یک اسکن عمیق بر اساس درخواست از صفحه بررسی امنیت در صفحه کنترل Cloudflare درس ما این است که مهم است که سیستم موجود را به طور عمیق درک کنید قبل از اینکه چیزی را از بین ببرید. با نگاه کردن به کد، اسکن های SQL، ژوگرافی ها و متریال های ما (به ویژه متریال ها) (به ویژه متریال ها)، می توانیم ظرفیت خود را افزایش دهیم بدون اینکه فقط پود ها یا پارتیشن ها را اضافه کنیم. با تردید کردن فرضیه های ما، غوطه کردن در متریال های عجیب و عجیب و غریب و انکار استفاده از Shortcuts ساده (مانند افزایش زمان از سوی مشتری API)امروز برای بررسی و مدیریت اطلاعات امنیتی خود، به دیسک Cloudflare وارد شوید.
چرا مهمه؟
اسکنهای قبلی هر دو هفته یکبار انجام میشد و برای حسابهای رایگان فعال نبودند؛ این باعث میشد خطرات جدید تا دو هفته کشف نشوند. حالا تمام کاربران، حتی رایگانها، اسکنهای مکرر و خودکار دریافت میکنند و خطرات سریعتر شناسایی میشوند. خواننده باید به این خبر اهمیت بده چون امنیت سرویسهای وبسایتش بهسرعت بهتر میشود و احتمال نفوذ کاهش مییابد.
به درد کی میخوره؟
• مدیران امنیت وب • مهندسان زیرساخت • تیمهای DevOps • توسعهدهندگان وب • کاربران Cloudflare
تو عمل چی کار کنیم؟
با اطلاع از این بهبود، میتوانید بهسرعت اسکنهای امنیتی را در داشبورد Cloudflare فعال کنید و از گزارشهای جدید برای رفع پیکربندیهای خطرناک استفاده کنید. همچنین میتوانید برنامهریزی دقیقتری برای بهروزرسانیهای امنیتی داشته باشید و از زمانبندی اسکنهای خودکار بهرهمند شوید.
نظر Blue IT News
این پیشرفت نشان میدهد که بهجای افزودن سرورهای بیشتر، بهینهسازی عمیق معماری میتواند بازدهی چشمگیری بدهد؛ پس همیشه قبل از سرمایهگذاری سختافزاری، کد و متریکها را بررسی کنید.
<div class=“disclosure”> این صفحه ترجمه و تفسیر کاملی از گزارش اصلی Blog است که توسط تیم تحریریه بلو آی تی نیوز به فارسی ترجمه و تحلیل شده. برای مشاهده نسخه اصلی، به منبع مراجعه کنید. </div>