«در سندباکس اجرایش کن» شبیه یک دستور واحد به نظر میرسد. در عمل منظور مردم یکی از چهار مرز رایج است، و این مرزها چیزهای بسیار متفاوتی را متوقف میکنند. انتخاب نادرست یا شما را بیدفاع میگذارد، یا هر اجرا را کندتر و گرانتر از لازم میکند.
این مقایسه فرض میکند کد واقعاً نامطمئن است: نوشتهٔ یک مدل زبانی، ارسالشده توسط یک کاربر، یا رسیده در pull request کسی که نمیشناسید. کدی که خودتان نوشتهاید نیازهای دیگری دارد.
چه چیزی ممکن است خراب شود
پیش از مقایسهٔ مرزها، خوب است بگوییم برای چه هستند. کد نامطمئن میتواند:
- چیزی را بخواند که نباید: متغیرهای محیطی، کلیدهای SSH، فایلهای پوشهٔ خانگی شما، endpointهای فرادادهٔ ابر.
- منابع را تمام کند: حلقهٔ بیپایان، fork تا وقتی ماشین از کار بیفتد، پر کردن دیسک.
- از شبکه سوءاستفاده کند: اسکن میزبانهای دیگر، ارسال اسپم، استخراج رمزارز، فراخوانی سرویسهای داخلی شما.
- ماندگار شود: نصب یک cron job یا سرویسی که پس از پایان کار هم باقی بماند.
- فرار کند: استفاده از باگی در لایهٔ زیرین برای اجرای کد روی خودِ میزبان.
هر سطح در ادامه بعضی از اینها را مهار میکند و بعضی را نه.
سطح ۱: فرایند
سادهترین سندباکس یک فرایند فرزند است: subprocess.run با مهلت زمانی، شاید با کاربری جداگانه، و اگر دقیق باشید با محدودیت منابع و فیلتر seccomp.
جلوی اینها را میگیرد: زمان افسارگسیخته (مهلت)، بخشی از تمام شدن منابع (محدودیتها)، برخی فراخوانیهای سیستمی خطرناک (seccomp). جلوی اینها را نمیگیرد: خواندن هر چیزی که آن کاربر میتواند بخواند، دسترسی به شبکه، ماندگاری از طریق هر جایی که کاربر میتواند در آن بنویسد، و هر باگی در هسته. شکست رایج: کد فایلی را میخواند که فراموش کرده بودید قابل خواندن است، یا معلوم میشود یک مفسر «محدودشده» راه دررو دارد. تاریخ پر از سندباکسهای درونزبانی است که دوام نیاوردند.
زمان راهاندازی عملاً صفر است. برای کدی که خودتان نوشتهاید خوب است؛ برای کدی که ننوشتهاید مرز به حساب نمیآید.
سطح ۲: کانتینر
در کانتینر، namespaces به کد نمای مخصوص خودش از فایلها، فرایندها و شبکه را میدهند؛ cgroups CPU و حافظه را محدود میکند؛ capabilityهای حذفشده و seccomp آنچه را میتواند از هسته بخواهد محدودتر میکنند.
جلوی اینها را میگیرد: خواندن فایلهای میزبان (مگر اینکه mount شده باشند)، دیدن فرایندهای دیگر، مصرف نامحدود منابع، و بخش بزرگی از مشکل ماندگاری اگر کانتینر پس از کار دور انداخته شود. جلوی این را نمیگیرد: باگی در هستهٔ مشترک میزبان. همهٔ کانتینرهای ماشین با یک هسته حرف میزنند، پس یک آسیبپذیری هستهٔ در دسترس، راه خروج است. شکست رایج: پیکربندی، نه اکسپلویتهای عجیب. کانتینر privileged، سوکت container runtime که داخل mount شده، شبکهٔ میزبان که «فقط برای دیباگ» روشن شده. هرکدام بیصدا مرز را برمیدارد.
زمان راهاندازی چند میلیثانیه است. گونههای مقاومشده هم وجود دارند، از جمله هستههای فضای کاربر که فراخوانیهای سیستمی را پیش از رسیدن به میزبان رهگیری میکنند، با کمی هزینه در سرعت و سازگاری. برای کد کسانی که به آنها اعتماد دارید، یک کانتینر خوب پیکربندیشده پیشفرض معقولی است.
سطح ۳: microVM
یک microVM مثل ماشین مجازی کامل، هستهٔ خودش را زیر یک هایپروایزر اجرا میکند، اما تقریباً همهٔ سختافزار شبیهسازیشده حذف شده است. Firecracker شناختهشدهترین نمونه است.
جلوی اینها را میگیرد: هر چیزی که کانتینر جلویش را میگیرد، بهعلاوهٔ مشکل هستهٔ مشترک. کد برای رسیدن به میزبان باید هایپروایزر یا یکی از چند دستگاه مجازی انگشتشمار را بشکند، که سطحی بسیار کوچکتر از رابط فراخوانیهای سیستمی هسته است. جلوی این را نمیگیرد: سوءاستفاده از آنچه به آن میدهید. خروجی باز همچنان قابل سوءاستفاده است؛ رازهایی که تزریق میکنید همچنان ممکن است نشت کنند. شکست رایج: سیاست، نه جداسازی. کسی توکن محیط تولید را «برای اینکه تستها کار کنند» میدهد، یا ترافیک خروجی را برای بار کاریای که به آن نیازی ندارد بیمحدودیت رها میکند.
زمان راهاندازی از کسری از ثانیه تا حدود یک ثانیه است، با چند مگابایت سربار. آنقدر سریع که برای هر کار یکی بسازید و بعد حذفش کنید، که مشکل ماندگاری را هم حل میکند: چیزی برای بازگشت باقی نمیماند.
سطح ۴: ماشین مجازی کامل
یک ماشین مجازی معمولی، یا VPS، همان نوع مرزی را دارد که microVM دارد: مجازیسازی سختافزاری و هایپروایزر. تفاوت در همهٔ چیزهای اطراف آن است: مدل دستگاه کامل، سیستمعامل کامل، IP عمومی اگر بخواهید، و چرخهٔ عمری که با روز یا ماه سنجیده میشود.
جلوی اینها را میگیرد: همان دسته از مشکلاتی که microVM مهار میکند، با سطح حملهٔ کمی بزرگتر چون سختافزار بیشتری شبیهسازی میشود. جلوی این را نمیگیرد: سوءاستفاده از هویت شبکهای خودش. ماشین مجازیای با IP عمومی که کد مخرب اجرا کند، IP خودش را وارد فهرست سیاه میکند، و اگر همان IP ایمیل شما را هم بفرستد این مهم است. (اگر این اتفاق افتاده، ببینید وقتی IP شما در فهرست سیاه است چه کنید.) شکست رایج: بیش از حد عمر میکند. ماشین مجازیای که برای یک آزمایش ساخته شده، اعتبارنامهها و وضعیت جمع میکند و کمکم به همان ماشین مورد اعتمادی تبدیل میشود که قرار بود از آن محافظت کند.
زمان راهاندازی از دهها ثانیه تا چند دقیقه است و صورتحساب معمولاً ماهانه. این شکل درستی برای سرویس طولانیمدتی است که به پورت ورودی نیاز دارد، و شکل نادرستی برای اجرای کدی ۲۰ ثانیهای.
مقایسه
| فرایند | کانتینر | microVM | ماشین مجازی کامل | |
|---|---|---|---|---|
| هستهٔ مستقل | خیر | خیر | بله | بله |
| مرز اصلی | مجوزهای کاربر | namespaces + هستهٔ مشترک | هایپروایزر، مدل دستگاه بسیار کوچک | هایپروایزر، مدل دستگاه کامل |
| زمان راهاندازی | ~0 | ms | ~0.1–1 ث | ۱۰ ث – چند دقیقه |
| سربار | هیچ | کم | چند MiB | دهها تا صدها MiB |
| دور انداختن پس از هر کار | آسان | آسان | آسان | کند و پرهزینه |
| پورت ورودی / IP عمومی | مال میزبان | مال میزبان | معمولاً ندارد | بله |
انتخاب
- کدی که خودتان یا تیمتان نوشتهاید: فرایند یا کانتینر کافی است.
- یکپارچهسازی مداوم (CI) برای شاخههای خودتان: کانتینر روی runner خودتان.
- کد تولیدشده توسط عامل، ارسالهای کاربران، pull requestهای بیرونی: یک microVM برای هر کار که بعد حذف میشود.
- سرویس نامطمئنی که باید اتصال بپذیرد یا هفتهها اجرا شود: یک ماشین مجازی جداگانه با IP خودش، دور از هر چیزی که اعتبارنامههای شما را نگه میدارد یا ایمیلتان را میفرستد.
هرکدام را که انتخاب کنید، دو قاعده بر آن افزوده میشود: چیزی داخلش نگذارید که حاضر نباشید به نویسندهٔ کد بدهید، و آگاهانه تصمیم بگیرید شبکه اجازهٔ چه کاری دارد.
محصولات ما کجا قرار میگیرند
برای سطح ۳، سندباکسهای کد را ارائه میدهیم: Firecracker microVMهایی که در حدود یک ثانیه راه میافتند، با اینترنت خروجی، بدون پورت ورودی و با صورتحساب ثانیهای. دقیقاً برای مورد سوم بالا ساخته شدهاند؛ صفحهٔ محافظهای MCP توضیح میدهد چطور کارهایی را که یک عامل میتواند با آنها انجام دهد محدود کنید. برای سطح ۴، یک VPS مانند تعرفهٔ AI agent یک ماشین کامل را بهصورت ماهانه در اختیارتان میگذارد. مثالهای عملی در سندباکس برای عاملهای هوش مصنوعی الگوی microVM را از ابتدا تا انتها نشان میدهند، و عاملهای هوش مصنوعی از زیرساخت چه میخواهند جداسازی را بهعنوان یکی از چند نیاز بررسی میکند.
نظرات
هنوز نظری نیست. اولین نفر باشید.