استفاده از تصاویر پایه امن – انجمن DEV

من این مقاله را نوشتم تا برخی از چیزهایی را که قبلاً در مورد PICK از LinuxTips یاد گرفتهام به اشتراک بگذارم. بنابراین، نوشیدنی خود را بردارید و به من بپیوندید.
همه چیز از آنجا شروع شد که، گاهی، ابزارهای امنیتی آسیبپذیریهای کم/متوسط را گزارش میکردند و زمانی که به ارزیابی این آسیبپذیری میرفتیم، همیشه به توافق ذهنی بزرگی میرسیدیم: «این کاری نیست که ما انجام دادیم، بنابراین راهی برای حل آن وجود ندارد. “
در طول کلاس های PICK، Chainguard را کشف کردم. و سپس ایده گردآوری این مقاله مطرح شد تا نشان دهد چگونه از یک تصویر پایه امن برای ساخت کانتینر برنامه من استفاده کنم.
برای نشان دادن این موضوع، ما در طول این مقاله یک برنامه کنسول بسیار ابتدایی “Hello world” را در DotNet در دسترس قرار می دهیم، زیرا تمرکز در اینجا این است که چگونه یک Dockerfile را برای برنامه به روشی امن تر جمع آوری کنیم و نه خود برنامه.
ایجاد اپلیکیشن
با فرض اینکه قبلاً DotNet SDK را در محیط خود نصب و پیکربندی کرده اید، بیایید ترمینال خود را باز کنیم و شروع به ایجاد پروژه کنیم.
بیایید برنامه خود را با استفاده از الگو ایجاد کنیم console
از DotNet CLI. با استفاده از دستور زیر این کار را انجام خواهیم داد:
dotnet new console -o HelloWorldApp
پس از انجام این کار، به ویرایشگر متن مورد علاقه خود می رویم تا شروع به دستکاری فایل های موجود در فهرست پروژه کنیم.
با باز بودن ویرایشگر متن، اجازه دهید فایل را تغییر دهیم Program.cs
تا او «سلام جهان» ما را داشته باشد. فایل خود را به شکل زیر ویرایش کنید:
namespace HelloWorldApp
{
static class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
ایجاد Dockerfile
عالی است، اکنون که برنامه ما را ایجاد کرده اید (که پتانسیل هک ناسا را دارد)، زمان آن رسیده است که Dockerfile خود را برای کانتینر کردن برنامه خود ایجاد کنیم.
شایان ذکر است که Dockerfile باید در همان سطح فایل csproj باشد، در مورد ما، در دایرکتوری HelloWorldApp
.
برای ساخت داکرفایل خود، علاوه بر استفاده از تصاویر پایه ایمن، از مفهوم سازمانی و عملکردی به نام ساخت های چند مرحله ای استفاده خواهیم کرد.
گام اول
بدون مقدمه، بیایید به خط اول Dockerfile خود برویم:
FROM cgr.dev/chainguard/dotnet-sdk:latest AS build
تصویر پایه ای که ما استفاده می کنیم دارای محدوده کمتری است به طوری که فقط وابستگی هایی وجود دارد که استفاده از DotNet SDK را برآورده می کند.
بنابراین، در مقایسه با دامنه تصویر پایه آلپاین، برای مثال، احتمال اینکه کانتینر ما دارای آسیبپذیریهایی باشد که فقط به وابستگیهای DotNet SDK مربوط نمیشود، بسیار کمتر است. و این تفاوت بزرگ در استفاده از تصاویر پایه Chainguard است.
هنوز در خط اول، توجه کنید که ما از یک نام مستعار برای شناسایی مرحله ای که اجرا می شود استفاده می کنیم. در این حالت مرحله جاری را فراخوانی می کنیم build
.
در حال حرکت، بنابراین می توانیم دستور خود را اجرا کنیم که برنامه ما را کامپایل می کند و dll ما را تولید می کند (dotnet publish
)، ابتدا باید اعلام کنیم که فایل های ما متعلق به یک کاربر غیر ریشه هستند تا کامپایل شوند. این کار را به صورت زیر انجام خواهیم داد:
COPY --chown=nonroot:nonroot . /source
در اینجا ما از دستور استفاده می کنیم COPY
برای کپی کردن تمام فایل ها از دایرکتوری فعلی که Dockerfile در آن قرار دارد، تحت مجوزهای یک کاربر غیر ریشه، به دایرکتوری داخل کانتینر به نام source
که بعدا مورد استفاده قرار خواهد گرفت.
از آنجایی که این یک تصویر پایه امن است، برخی از عملیات (مانند انتشار در مورد ما) نیاز به توجه بیشتر به سطوح مجوز دارند، زیرا اجازه دادن به چیزهایی که در سطح بالایی کامپایل شوند، امنیت کل تصویر را تضعیف می کند.
در پایان این مرحله، دایرکتوری کاری پیش فرض خود را تعریف می کنیم و فرآیند ایجاد dll خود را انجام می دهیم که به دایرکتوری به نام هدایت می شود. Release
. این کار در خطوط زیر انجام خواهد شد:
WORKDIR /source
RUN dotnet publish --use-current-runtime --self-contained false -o Release
مرحله نهایی
اکنون، در این مرحله، دیگر نیازی به وابستگیهای مربوط به SDK نداریم. اکنون برای اجرای dll خود باید منابع مرتبط با زمان اجرا DotNet داشته باشیم. برای این کار از تصویر پایه زیر استفاده می کنیم:
FROM cgr.dev/chainguard/dotnet-runtime:latest AS final
پس از آن، اکنون به تعریف دایرکتوری کاری پیش فرض خود می پردازیم و اکنون از مزیت بزرگ استفاده از چند مرحله ای استفاده خواهیم کرد. همانطور که در مرحله از build
ما قبلا dll خود را تولید کرده ایم، سپس می توانیم dll خود را در مرحله فعلی کپی کنیم تا بتوانیم از آن استفاده کنیم. بیایید این کار را به صورت زیر انجام دهیم:
WORKDIR /
COPY --from=build /source .
توجه داشته باشید که در دستور COPY
ما می گوییم که می خواهیم آن را در زمینه اصلی کپی کنیم .
آنچه در دایرکتوری ایجاد شده است /source
صحنه است build
. و اینجاست که ما سازماندهی و عملکرد را در Dockerfile خود به دست می آوریم و ایجاد و استفاده مجدد از مصنوعات را تقسیم بندی می کنیم.
در نهایت دستور اصلی خود را تعریف می کنیم که با راه اندازی کانتینر ما اجرا می شود، یعنی نشان می دهیم که از DotNet برای اجرای dll خود استفاده می کنیم. ما این کار را به صورت زیر انجام می دهیم:
ENTRYPOINT ["dotnet", "Release/HelloWorldApp.dll"]
Dockerfile را کامل کنید
با انجام تمام این کارها، Dockerfile نهایی ما باید به شکل زیر باشد:
FROM cgr.dev/chainguard/dotnet-sdk:latest AS build
COPY --chown=nonroot:nonroot . /source
WORKDIR /source
RUN dotnet publish --use-current-runtime --self-contained false -o Release
FROM cgr.dev/chainguard/dotnet-runtime:latest AS final
WORKDIR /
COPY --from=build /source .
ENTRYPOINT ["dotnet", "Release/HelloWorldApp.dll"]
ساخت و اجرای تصویر
با ایجاد Dockerfile، زمان آن فرا رسیده است که تصویر خود را بسازیم و ببینیم که آیا همه چیز همانطور که انتظار میرود کار میکند (اینجا معمولاً همه چیز آتش میگیرد). برای انجام این کار، با قرار گرفتن در همان دایرکتوری که Dockerfile ما است، دستور زیر را اجرا می کنیم:
docker build -t helloworldapp .
پس از تکمیل ساخت، به لحظه مورد انتظار می رویم: اجرای یک ظرف که dll ما اجرا می شود. برای این کار از دستور استفاده کنید:
docker run --rm helloworldapp
این همه، مردمی
این سفر ما را با استفاده از تصاویر پایه ایمن و چند مرحله ای در Dockerfiles به پایان می رساند. واضح است که میتوانید جلوتر بروید، برای مثال، گردشهای کاری در GitHub ایجاد کنید که کد یا ظرف را با هر درخواست فشار/کشیدن با استفاده از ابزارهایی مانند Snyk یا Trivy اسکن میکند.
اکنون به شما بستگی دارد: از آنچه در اینجا گذرانده ایم سوء استفاده کنید و استفاده کنید! سایر تصاویر پایه را کاوش کنید، سعی کنید در مورد نحوه کار آنها بیشتر بدانید، سعی کنید Dockerfiles را برای استفاده از چند مرحله ای بازسازی کنید. فراتر از!
به یاد داشته باشید: باشد که نیرو با شما باشد، زندگی طولانی و مرفه داشته باشید و نترسید! Allons-y!