ایمن سازی ساختمان های کانتینر

۱. مقدمه

ead1609267034bf7.png

آسیب‌پذیری‌های نرم‌افزاری، نقاط ضعفی هستند که می‌توانند باعث خرابی تصادفی سیستم شوند یا ابزاری را در اختیار عوامل مخرب قرار دهند تا نرم‌افزار شما را به خطر بیندازند. تجزیه و تحلیل کانتینر، دو نوع اسکن سیستم عامل را برای یافتن آسیب‌پذیری‌ها در کانتینرها ارائه می‌دهد:

  • API اسکن بر اساس تقاضا به شما امکان می‌دهد تا تصاویر کانتینر را به صورت دستی برای آسیب‌پذیری‌های سیستم عامل اسکن کنید، چه به صورت محلی روی رایانه خود و چه از راه دور در رجیستری کانتینر یا رجیستری مصنوعات.
  • API اسکن کانتینر به شما امکان می‌دهد تا تشخیص آسیب‌پذیری سیستم عامل را خودکار کنید و هر بار که تصویری را به رجیستری کانتینر یا رجیستری مصنوعات ارسال می‌کنید، آن را اسکن کنید. فعال کردن این API همچنین امکان اسکن بسته‌های زبانی برای آسیب‌پذیری‌های Go و Java را فراهم می‌کند.

API اسکن On-Demand به شما امکان می‌دهد تصاویر ذخیره شده به صورت محلی در رایانه خود یا از راه دور در Container Registry یا Artifact Registry را اسکن کنید. این به شما امکان کنترل دقیق بر روی Containerهایی را می‌دهد که می‌خواهید برای آسیب‌پذیری‌ها اسکن کنید. می‌توانید قبل از تصمیم‌گیری در مورد ذخیره آنها در یک رجیستری، از اسکن On-Demand برای اسکن تصاویر در خط لوله CI/CD خود استفاده کنید.

آنچه یاد خواهید گرفت

در این آزمایشگاه شما:

  • ساخت تصاویر با Cloud Build
  • استفاده از رجیستری مصنوعات برای کانتینرها
  • استفاده از اسکن خودکار آسیب‌پذیری
  • پیکربندی اسکن بر اساس تقاضا
  • اسکن تصویر را در CICD در Cloud Build اضافه کنید

۲. تنظیمات و الزامات

تنظیم محیط خودتنظیم

  1. وارد کنسول گوگل کلود شوید و یک پروژه جدید ایجاد کنید یا از یک پروژه موجود دوباره استفاده کنید. اگر از قبل حساب جیمیل یا گوگل ورک اسپیس ندارید، باید یکی ایجاد کنید .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • نام پروژه ، نام نمایشی برای شرکت‌کنندگان این پروژه است. این یک رشته کاراکتری است که توسط APIهای گوگل استفاده نمی‌شود. می‌توانید آن را در هر زمانی به‌روزرسانی کنید.
  • شناسه پروژه در تمام پروژه‌های گوگل کلود منحصر به فرد است و تغییرناپذیر است (پس از تنظیم، قابل تغییر نیست). کنسول کلود به طور خودکار یک رشته منحصر به فرد تولید می‌کند؛ معمولاً برای شما مهم نیست که چه باشد. در اکثر آزمایشگاه‌های کد، باید به شناسه پروژه ارجاع دهید (که معمولاً با عنوان PROJECT_ID شناخته می‌شود). اگر شناسه تولید شده را دوست ندارید، می‌توانید یک شناسه تصادفی دیگر ایجاد کنید. به عنوان یک جایگزین، می‌توانید شناسه خودتان را امتحان کنید و ببینید که آیا در دسترس است یا خیر. پس از این مرحله قابل تغییر نیست و در طول پروژه باقی خواهد ماند.
  • برای اطلاع شما، یک مقدار سوم، شماره پروژه ، وجود دارد که برخی از APIها از آن استفاده می‌کنند. برای کسب اطلاعات بیشتر در مورد هر سه این مقادیر، به مستندات مراجعه کنید.
  1. در مرحله بعد، برای استفاده از منابع/API های ابری، باید پرداخت صورتحساب را در کنسول ابری فعال کنید . اجرای این آزمایشگاه کد، اگر اصلاً هزینه‌ای نداشته باشد، هزینه زیادی نخواهد داشت. برای خاموش کردن منابع به طوری که پس از این آموزش متحمل پرداخت صورتحساب نشوید، می‌توانید منابعی را که ایجاد کرده‌اید یا کل پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان ۳۰۰ دلاری هستند.

تنظیمات محیط

در Cloud Shell، شناسه پروژه و شماره پروژه خود را تنظیم کنید. آنها را به عنوان متغیرهای PROJECT_ID و PROJECT_ID ذخیره کنید.

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')

فعال کردن سرویس‌ها

فعال کردن تمام سرویس‌های لازم:

gcloud services enable \
  cloudkms.googleapis.com \
  cloudbuild.googleapis.com \
  container.googleapis.com \
  containerregistry.googleapis.com \
  artifactregistry.googleapis.com \
  containerscanning.googleapis.com \
  ondemandscanning.googleapis.com \
  binaryauthorization.googleapis.com 

۳. ساخت تصاویر با Cloud Build

در این بخش، شما یک خط لوله ساخت خودکار ایجاد خواهید کرد که تصویر کانتینر شما را می‌سازد، آن را اسکن می‌کند و سپس نتایج را ارزیابی می‌کند. اگر هیچ آسیب‌پذیری بحرانی پیدا نشود، تصویر را به مخزن ارسال می‌کند. اگر آسیب‌پذیری‌های بحرانی پیدا شود، ساخت با شکست مواجه شده و خاتمه می‌یابد.

دسترسی به حساب سرویس ساخت ابری (Cloud Build Service Account) را فراهم کنید

Cloud Build برای دسترسی به API اسکن درخواستی به مجوزهایی نیاز دارد. با دستورات زیر این دسترسی را فراهم کنید.

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser"
        
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/ondemandscanning.admin"

ایجاد و تغییر به یک دایرکتوری کاری

mkdir vuln-scan && cd vuln-scan

تعریف یک تصویر نمونه

یک فایل به نام Dockerfile با محتوای زیر ایجاد کنید.

cat > ./Dockerfile << EOF
FROM gcr.io/google-appengine/debian9@sha256:ebffcf0df9aa33f342c4e1d4c8428b784fc571cdf6fbab0b31330347ca8af97a

# System
RUN apt update && apt install python3-pip -y

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==1.1.4
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

EOF

یک فایل به نام main.py با محتوای زیر ایجاد کنید.

cat > ./main.py << EOF
import os
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    name = os.environ.get("NAME", "Worlds")
    return "Hello {}!".format(name)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF

ایجاد خط لوله Cloud Build

دستور زیر یک فایل cloudbuild.yaml در دایرکتوری شما ایجاد می‌کند که برای فرآیند خودکار استفاده خواهد شد. برای این مثال، مراحل به فرآیند ساخت کانتینر محدود می‌شوند. با این حال، در عمل، شما علاوه بر مراحل کانتینر، دستورالعمل‌ها و تست‌های خاص برنامه را نیز اضافه خواهید کرد.

با دستور زیر فایل را ایجاد کنید.

cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']


EOF

اجرای خط لوله CI

ساخت را برای پردازش ارسال کنید

gcloud builds submit

جزئیات ساخت را بررسی کنید

پس از شروع فرآیند ساخت، پیشرفت را در داشبورد Cloud Build بررسی کنید.

  1. Cloud Build را در کنسول Cloud باز کنید
  2. برای مشاهده محتوا روی ساخت کلیک کنید

۴. ثبت مصنوعات برای کانتینرها

ایجاد مخزن رجیستری مصنوعات

در این آزمایش شما از Artifact Registry برای ذخیره و اسکن تصاویر خود استفاده خواهید کرد. مخزن را با دستور زیر ایجاد کنید.

gcloud artifacts repositories create artifact-scanning-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository"

داکر را طوری پیکربندی کنید که هنگام دسترسی به رجیستری مصنوعات، از اعتبارنامه‌های gcloud شما استفاده کند.

gcloud auth configure-docker us-central1-docker.pkg.dev

به‌روزرسانی خط لوله ساخت ابری

خط لوله ساخت خود را تغییر دهید تا تصویر حاصل را به رجیستری مصنوعات ارسال کنید

cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

# push to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image']

images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF

اجرای خط لوله CI

ساخت را برای پردازش ارسال کنید

gcloud builds submit

۵. اسکن خودکار آسیب‌پذیری

اسکن مصنوعات هر بار که یک تصویر جدید را به رجیستری مصنوعات یا رجیستری کانتینر اضافه می‌کنید، به طور خودکار فعال می‌شود. اطلاعات آسیب‌پذیری به طور مداوم با کشف آسیب‌پذیری‌های جدید به‌روزرسانی می‌شود. در این بخش، تصویری را که اخیراً ساخته‌اید و به رجیستری مصنوعات اضافه کرده‌اید، بررسی کرده و نتایج آسیب‌پذیری را بررسی خواهید کرد.

جزئیات تصویر را بررسی کنید

پس از اتمام فرآیند ساخت قبلی، نتایج مربوط به تصویر و آسیب‌پذیری را در داشبورد Artifact Registry بررسی کنید.

  1. رجیستری مصنوعات را در کنسول ابری باز کنید
  2. برای مشاهده محتوا، روی مخزن اسکن مصنوعات کلیک کنید
  3. روی جزئیات تصویر کلیک کنید
  4. روی آخرین خلاصه تصویر خود کلیک کنید
  5. پس از اتمام اسکن، روی برگه آسیب‌پذیری‌ها برای تصویر کلیک کنید.

از تب آسیب‌پذیری‌ها، نتایج اسکن خودکار برای ایمیجی که تازه ساخته‌اید را مشاهده خواهید کرد.

361be7b3bf293fca.png

اسکن خودکار به طور پیش‌فرض فعال است. تنظیمات رجیستری مصنوعات را بررسی کنید تا ببینید چگونه می‌توانید اسکن خودکار را خاموش/روشن کنید.

۶. اسکن بر اساس تقاضا

سناریوهای مختلفی وجود دارد که ممکن است لازم باشد قبل از ارسال تصویر به مخزن، اسکن انجام دهید. به عنوان مثال، یک توسعه‌دهنده کانتینر ممکن است قبل از ارسال کد به کنترل منبع، یک تصویر را اسکن کرده و مشکلات را برطرف کند. در مثال زیر، قبل از اقدام بر اساس نتایج، تصویر را به صورت محلی ایجاد و تجزیه و تحلیل خواهید کرد.

ساخت یک تصویر

در این مرحله از داکر محلی برای ساخت ایمیج در حافظه پنهان محلی خود استفاده خواهید کرد.

docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .

تصویر را اسکن کنید

پس از ساخت تصویر، درخواست اسکن تصویر را بدهید. نتایج اسکن در یک سرور فراداده ذخیره می‌شوند. کار با قرار دادن نتایج در سرور فراداده به پایان می‌رسد.

gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --format="value(response.scan)" > scan_id.txt

فایل خروجی را بررسی کنید

لحظه‌ای به بررسی خروجی مرحله قبل که در فایل scan_id.txt ذخیره شده بود، بپردازید. به محل گزارش نتایج اسکن در سرور فراداده توجه کنید.

cat scan_id.txt

نتایج اسکن دقیق را بررسی کنید

برای مشاهده نتایج واقعی اسکن، از دستور list-vulnerabilities در محل گزارش ذکر شده در فایل خروجی استفاده کنید.

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) 

خروجی شامل مقدار قابل توجهی از داده‌ها در مورد تمام آسیب‌پذیری‌های موجود در تصویر است.

مسائل بحرانی را علامت‌گذاری کنید

انسان‌ها به ندرت مستقیماً از داده‌های ذخیره شده در گزارش استفاده می‌کنند. معمولاً نتایج توسط یک فرآیند خودکار استفاده می‌شوند. از دستورات زیر برای خواندن جزئیات گزارش و ثبت هرگونه آسیب‌پذیری بحرانی استفاده کنید.

export SEVERITY=CRITICAL

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq ${SEVERITY}; then echo "Failed vulnerability check for ${SEVERITY} level"; else echo "No ${SEVERITY} Vulnerabilities found"; fi

خروجی این دستور به صورت زیر خواهد بود:

Failed vulnerability check for CRITICAL level

۷. اسکن در CICD با Cloud Build

دسترسی به حساب سرویس ساخت ابری (Cloud Build Service Account) را فراهم کنید

Cloud Build برای دسترسی به API اسکن درخواستی به مجوزهایی نیاز دارد. با دستورات زیر این دسترسی را فراهم کنید.

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser"
        
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/ondemandscanning.admin"

به‌روزرسانی خط لوله ساخت ابری

دستور زیر یک فایل cloudbuild.yaml در دایرکتوری شما ایجاد می‌کند که برای فرآیند خودکار استفاده خواهد شد. برای این مثال، مراحل به فرآیند ساخت کانتینر محدود می‌شوند. با این حال، در عمل، شما علاوه بر مراحل کانتینر، دستورالعمل‌ها و تست‌های خاص برنامه را نیز اضافه خواهید کرد.

با دستور زیر فایل را ایجاد کنید.

cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

#Run a vulnerability scan at _SECURITY level
- id: scan
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    (gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --location us \
    --format="value(response.scan)") > /workspace/scan_id.txt

#Analyze the result of the scan
- id: severity check
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
      gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
      --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
      then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi

#Retag
- id: "retag"
  name: 'gcr.io/cloud-builders/docker'
  args: ['tag',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#pushing to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']

images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF

اجرای خط لوله CI

در صورت یافتن آسیب‌پذیری با شدت بحرانی، نسخه را برای پردازش ارسال کنید تا نقص‌های نسخه تأیید شود.

gcloud builds submit

بررسی شکست ساخت

ساختاری که ارسال کردید با شکست مواجه خواهد شد زیرا تصویر حاوی آسیب‌پذیری‌های بحرانی است.

شکست ساخت را در صفحه تاریخچه ساخت ابری بررسی کنید

رفع آسیب‌پذیری

Dockerfile را به‌روزرسانی کنید تا از یک تصویر پایه که حاوی آسیب‌پذیری‌های بحرانی نیست، استفاده کند.

برای استفاده از ایمیج دبیان ۱۰، داکرفایل را با دستور زیر بازنویسی کنید

cat > ./Dockerfile << EOF
from python:3.8-slim  

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app

EOF

فرآیند CI را با تصویر خوب اجرا کنید

ساخت را برای پردازش ارسال کنید تا تأیید شود که ساخت در صورت عدم یافتن آسیب‌پذیری‌های با شدت بحرانی، با موفقیت انجام خواهد شد.

gcloud builds submit

بررسی ایجاد موفقیت

ساختاری که شما ارسال کردید با موفقیت انجام خواهد شد زیرا تصویر به‌روزرسانی‌شده حاوی هیچ آسیب‌پذیری بحرانی نیست.

موفقیت ساخت را در صفحه تاریخچه ساخت ابری بررسی کنید

نتایج اسکن را بررسی کنید

تصویر خوب را در رجیستری مصنوعات بررسی کنید

  1. رجیستری مصنوعات را در کنسول ابری باز کنید
  2. برای مشاهده محتوا، روی مخزن اسکن مصنوعات کلیک کنید
  3. روی جزئیات تصویر کلیک کنید
  4. روی آخرین خلاصه تصویر خود کلیک کنید
  5. برای مشاهده تصویر، روی تب آسیب‌پذیری‌ها کلیک کنید

۸. تبریک می‌گویم!

تبریک می‌گویم، شما codelab را تمام کردید!

آنچه ما پوشش داده‌ایم:

  • ساخت تصاویر با Cloud Build
  • ثبت آثار باستانی برای کانتینرها
  • اسکن خودکار آسیب‌پذیری
  • اسکن بر اساس تقاضا
  • اسکن در CICD با Cloud Build

قدم بعدی چیست؟

تمیز کردن

برای جلوگیری از تحمیل هزینه به حساب گوگل کلود خود برای منابع استفاده شده در این آموزش، یا پروژه‌ای که شامل منابع است را حذف کنید، یا پروژه را نگه دارید و منابع تکی را حذف کنید.

حذف پروژه

ساده‌ترین راه برای حذف هزینه‌ها، حذف پروژه‌ای است که برای آموزش ایجاد کرده‌اید.

آخرین به‌روزرسانی: 21/3/23