1. مقدمه
Container Analysis اسکن آسیب پذیری و ذخیره ابرداده را برای کانتینرها فراهم می کند. سرویس اسکن اسکن آسیبپذیریها را بر روی تصاویر در Artifact Registry و Container Registry انجام میدهد، سپس ابردادههای حاصل را ذخیره میکند و از طریق یک API برای مصرف در دسترس قرار میدهد. ذخیره سازی ابرداده به شما امکان می دهد اطلاعات را از منابع مختلف، از جمله اسکن آسیب پذیری، سرویس های Google Cloud، و ارائه دهندگان شخص ثالث ذخیره کنید.
اسکن آسیبپذیری میتواند به صورت خودکار یا بر حسب تقاضا انجام شود:
- هنگامی که اسکن خودکار فعال است، هر بار که تصویر جدیدی را به رجیستری مصنوع یا رجیستری کانتینر فشار می دهید، اسکن به طور خودکار فعال می شود. هنگامی که آسیب پذیری های جدید کشف می شود، اطلاعات آسیب پذیری به طور مداوم به روز می شود.
- وقتی اسکن درخواستی فعال است، باید دستوری را برای اسکن یک تصویر محلی یا یک تصویر در رجیستری مصنوع یا رجیستری کانتینر اجرا کنید. اسکن درخواستی به شما انعطاف پذیری را در هنگام اسکن ظروف می دهد. به عنوان مثال، میتوانید یک تصویر محلی را اسکن کرده و آسیبپذیریها را قبل از ذخیره آن در رجیستری برطرف کنید. نتایج اسکن تا 48 ساعت پس از تکمیل اسکن در دسترس است و اطلاعات آسیبپذیری پس از اسکن بهروزرسانی نمیشود.
با تجزیه و تحلیل کانتینر که در خط لوله CI/CD شما یکپارچه شده است، می توانید بر اساس آن ابرداده تصمیم گیری کنید. برای مثال، میتوانید از Binary Authorization برای ایجاد خطمشیهای استقرار استفاده کنید که فقط اجازه استقرار تصاویر سازگار از رجیستریهای مورد اعتماد را میدهد.
چیزی که یاد خواهید گرفت
- نحوه فعال کردن اسکن خودکار
- نحوه انجام اسکن درخواستی
- نحوه ادغام اسکن در خط لوله ساخت
- نحوه امضای تصاویر تایید شده
- نحوه استفاده از کنترلرهای GKE Admission برای مسدود کردن تصاویر
- چگونه GKE را پیکربندی کنیم تا فقط تصاویر تایید شده امضا شده را مجاز کند
2. راه اندازی و الزامات
تنظیم محیط خود به خود
- به Google Cloud Console وارد شوید و یک پروژه جدید ایجاد کنید یا از یک موجود استفاده مجدد کنید. اگر قبلاً یک حساب Gmail یا Google Workspace ندارید، باید یک حساب ایجاد کنید .
- نام پروژه نام نمایشی برای شرکت کنندگان این پروژه است. این یک رشته کاراکتری است که توسط API های Google استفاده نمی شود. شما می توانید آن را در هر زمان به روز کنید.
- شناسه پروژه در تمام پروژههای Google Cloud منحصربهفرد است و تغییرناپذیر است (پس از تنظیم نمیتوان آن را تغییر داد). Cloud Console به طور خودکار یک رشته منحصر به فرد تولید می کند. معمولاً برای شما مهم نیست که چیست. در اکثر کدها، باید به شناسه پروژه ارجاع دهید (معمولاً به عنوان
PROJECT_ID
شناخته می شود). اگر شناسه تولید شده را دوست ندارید، ممکن است یک شناسه تصادفی دیگر ایجاد کنید. از طرف دیگر، میتوانید خودتان را امتحان کنید و ببینید آیا در دسترس است یا خیر. پس از این مرحله نمی توان آن را تغییر داد و در طول مدت پروژه باقی می ماند. - برای اطلاع شما، یک مقدار سوم وجود دارد، یک شماره پروژه که برخی از API ها از آن استفاده می کنند. در مورد هر سه این مقادیر در مستندات بیشتر بیاموزید.
- در مرحله بعد، برای استفاده از منابع Cloud/APIها باید صورتحساب را در کنسول Cloud فعال کنید . اجرا کردن از طریق این کد لبه نباید هزینه زیادی داشته باشد، اگر اصلاً باشد. برای اینکه منابع را خاموش کنید تا بیش از این آموزش متحمل صورتحساب نشوید، می توانید منابعی را که ایجاد کرده اید حذف کنید یا کل پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.
ویرایشگر Cloudshell را شروع کنید
این آزمایشگاه برای استفاده با Google Cloud Shell Editor طراحی و آزمایش شده است. برای دسترسی به ویرایشگر،
- به پروژه Google خود در https://console.cloud.google.com دسترسی پیدا کنید.
- در گوشه بالا سمت راست روی نماد ویرایشگر پوسته ابری کلیک کنید
- یک صفحه جدید در پایین پنجره شما باز می شود
راه اندازی محیط
در 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
مخزن رجیستری مصنوع را ایجاد کنید
در این آزمایشگاه شما از 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
3. اسکن خودکار
اسکن مصنوع به طور خودکار هر بار که تصویر جدیدی را به رجیستری مصنوع یا رجیستری کانتینر فشار می دهید، فعال می شود. هنگامی که آسیب پذیری های جدید کشف می شود، اطلاعات آسیب پذیری به طور مداوم به روز می شود. در این بخش شما یک تصویر را به رجیستری Artifact فشار می دهید و نتایج را بررسی می کنید.
ایجاد و تبدیل به فهرست کاری
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
تصویر را بسازید و به AR فشار دهید
از Cloud Build برای ساختن و به طور خودکار کانتینر خود را به Artifact Registry فشار دهید. به تگ bad
روی تصویر توجه کنید. این به شما کمک می کند آن را برای مراحل بعدی شناسایی کنید.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
بررسی جزئیات تصویر
پس از تکمیل فرآیند ساخت، تصویر و آسیبپذیری را در داشبورد Artifact Registry بررسی کنید.
- رجیستری Artifact را در Cloud Console باز کنید
- برای مشاهده مطالب روی artifact-scanning-repo کلیک کنید
- روی جزئیات تصویر کلیک کنید
- روی آخرین خلاصه تصویر خود کلیک کنید
- پس از پایان اسکن، روی تب آسیب پذیری تصویر کلیک کنید
از برگه آسیب پذیری ها، نتایج اسکن خودکار تصویری را که به تازگی ساخته اید، مشاهده خواهید کرد.
اسکن خودکار به طور پیش فرض فعال است. تنظیمات رجیستری مصنوع را کاوش کنید تا ببینید چگونه می توانید اسکن خودکار را خاموش/روشن کنید.
4. اسکن درخواستی
سناریوهای مختلفی وجود دارد که ممکن است لازم باشد قبل از فشار دادن تصویر به یک مخزن، یک اسکن انجام دهید. به عنوان مثال، یک توسعه دهنده کانتینر ممکن است قبل از فشار دادن کد به کنترل منبع، یک تصویر را اسکن کرده و مشکلات را برطرف کند. در مثال زیر قبل از اقدام بر روی نتایج، تصویر را به صورت محلی ساخته و آنالیز خواهید کرد.
یک تصویر بسازید
در این مرحله از docker محلی برای ساختن تصویر در حافظه پنهان محلی خود استفاده خواهید کرد.
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
5. ساخت خط لوله اسکن
در این بخش شما یک خط لوله ساخت خودکار ایجاد میکنید که تصویر ظرف شما را میسازد، آن را اسکن کرده و نتایج را ارزیابی میکند. اگر هیچ آسیبپذیری مهمی پیدا نشود، تصویر را به مخزن میبرد. اگر آسیبپذیریهای بحرانی پیدا شوند، ساختوساز شکست میخورد و خارج میشود.
دسترسی برای حساب خدمات ساخت ابری فراهم کنید
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"
خط لوله ساخت Cloud را ایجاد کنید
دستور زیر یک فایل 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
بررسی خرابی ساخت
ساختنی که ارسال کردید با شکست مواجه می شود زیرا تصویر حاوی آسیب پذیری های مهمی است.
شکست ساخت را در صفحه Cloud Build History مرور کنید
آسیب پذیری را برطرف کنید
Dockerfile را بهروزرسانی کنید تا از یک تصویر پایه استفاده کنید که حاوی آسیبپذیریهای بحرانی نباشد.
برای استفاده از تصویر Debian 10 با دستور زیر، 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
بررسی موفقیت ساخت
ساختنی که به تازگی ارسال کردید موفق خواهد شد زیرا تصویر به روز شده حاوی هیچ آسیب پذیری مهمی نیست.
موفقیت ساخت را در صفحه Cloud Build History مرور کنید
نتایج اسکن را مرور کنید
تصویر خوب را در رجیستری Artifact مرور کنید
- رجیستری Artifact را در Cloud Console باز کنید
- برای مشاهده مطالب روی artifact-scanning-repo کلیک کنید
- روی جزئیات تصویر کلیک کنید
- روی آخرین خلاصه تصویر خود کلیک کنید
- برای تصویر روی تب آسیب پذیری ها کلیک کنید
6. امضای تصاویر
یک یادداشت تأیید کننده ایجاد کنید
یادداشت تأیید کننده به سادگی یک بیت کوچک از داده است که به عنوان یک برچسب برای نوع امضای اعمال شده عمل می کند. به عنوان مثال، یک یادداشت ممکن است نشان دهنده اسکن آسیب پذیری باشد، در حالی که یکی دیگر ممکن است برای علامت QA استفاده شود. در حین امضاء به یادداشت ارجاع داده خواهد شد.
یک یادداشت ایجاد کنید
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
یادداشت را ذخیره کنید
NOTE_ID=vulnz_note
curl -vvv -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./vulnz_note.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
یادداشت را تأیید کنید
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
ایجاد یک گواهی دهنده
گواهیدهندهها برای انجام فرآیند امضای تصویر واقعی استفاده میشوند و یک رخداد یادداشت را برای تأیید بعدی به تصویر پیوست میکنند. گواهی را برای استفاده بعدی ایجاد کنید.
تایید کننده ایجاد کنید
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
تأیید کننده را تأیید کنید
gcloud container binauthz attestors list
توجه داشته باشید که خط آخر NUM_PUBLIC_KEYS: 0
کلیدها را در مرحله بعد ارائه خواهید کرد
همچنین توجه داشته باشید که وقتی ساختی را اجرا می کنید که تصاویر تولید می کند، Cloud Build به طور خودکار گواهی built-by-cloud-build
در پروژه شما ایجاد می کند. بنابراین دستور بالا دو گواهیدهنده، vulnz-attestor
و built-by-cloud-build
برمیگرداند. پس از اینکه تصاویر با موفقیت ساخته شدند، Cloud Build به طور خودکار امضا می کند و برای آنها گواهی ایجاد می کند.
اضافه کردن نقش IAM
حساب سرویس مجوز باینری برای مشاهده یادداشتهای گواهی نیاز به حقوق دارد. دسترسی را با فراخوانی API زیر فراهم کنید
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
cat > ./iam_request.json << EOM
{
'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
'policy': {
'bindings': [
{
'role': 'roles/containeranalysis.notes.occurrences.viewer',
'members': [
'serviceAccount:${BINAUTHZ_SA_EMAIL}'
]
}
]
}
}
EOM
از فایل برای ایجاد سیاست IAM استفاده کنید
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./iam_request.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
افزودن کلید KMS
Attestor برای پیوست کردن یادداشت و ارائه امضاهای قابل تأیید به کلیدهای رمزنگاری نیاز دارد. در این مرحله کلیدهایی را در KMS برای Cloud Build ایجاد و ذخیره میکنید تا بعداً به آن دسترسی داشته باشید.
ابتدا چند متغیر محیطی برای توصیف کلید جدید اضافه کنید
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
یک جا کلیدی برای نگه داشتن مجموعه ای از کلیدها ایجاد کنید
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
یک جفت کلید امضای نامتقارن جدید برای گواهیدهنده ایجاد کنید
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
باید ببینید که کلید شما در صفحه KMS کنسول ابری Google ظاهر می شود.
اکنون، کلید را از طریق دستور gcloud binauthz با گواهی دهنده خود مرتبط کنید:
gcloud beta container binauthz attestors public-keys add \
--attestor="${ATTESTOR_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
اگر دوباره فهرست مقامات را چاپ کنید، اکنون باید یک کلید ثبت شده را مشاهده کنید:
gcloud container binauthz attestors list
ایجاد یک گواهی امضا شده
در این مرحله شما ویژگی هایی را پیکربندی کرده اید که به شما امکان می دهد تصاویر را امضا کنید. برای امضای تصویر کانتینری که با آن کار میکردید، از تأییدکنندهای که قبلاً ایجاد کردهاید، استفاده کنید
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \
--format='get(image_summary.digest)')
اکنون می توانید از gcloud برای ایجاد گواهینامه خود استفاده کنید. این دستور به سادگی جزئیات کلیدی را که میخواهید برای امضا استفاده کنید و تصویر کانتینری خاصی را که میخواهید تأیید کنید، میگیرد.
gcloud beta container binauthz attestations sign-and-create \
--artifact-url="${CONTAINER_PATH}@${DIGEST}" \
--attestor="${ATTESTOR_ID}" \
--attestor-project="${PROJECT_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
به عبارت Container Analysis، این یک اتفاق جدید ایجاد میکند و آن را به یادداشت گواهیدهنده شما متصل میکند. برای اطمینان از اینکه همه چیز طبق انتظار عمل کرده است، می توانید گواهینامه های خود را فهرست کنید
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. امضا با Cloud Build
شما امضای تصویر را فعال کرده اید و به صورت دستی از Attestor برای امضای تصویر نمونه خود استفاده کرده اید. در عمل شما می خواهید گواهینامه ها را در طی فرآیندهای خودکار مانند خطوط لوله CI/CD اعمال کنید.
در این بخش ، Cloud Build را برای تأیید تصاویر به صورت خودکار پیکربندی خواهید کرد
نقش ها
نقش نمایشگر تأیید کننده مجوز باینری را به حساب سرویس ساخت ابری اضافه کنید:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
نقش امضاکننده/تأییدکننده Cloud KMS CryptoKey را به حساب سرویس ساخت ابری (امضا مبتنی بر KMS) اضافه کنید:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
نقش Attacher Notes Analysis Container را به حساب سرویس Cloud Build اضافه کنید:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
مرحله ساخت ابر سفارشی را آماده کنید
شما از یک مرحله ساخت سفارشی در Cloud Build برای ساده کردن فرآیند تأیید استفاده خواهید کرد. Google این مرحله ساخت سفارشی را ارائه میکند که شامل توابع کمکی برای سادهسازی فرآیند است. قبل از استفاده، کد مرحله ساخت سفارشی باید در یک کانتینر ساخته شود و به Cloud Build فشار داده شود. برای این کار دستورات زیر را اجرا کنید:
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/binauthz-attestation
gcloud builds submit . --config cloudbuild.yaml
cd ../..
rm -rf cloud-builders-community
یک مرحله امضا به cloudbuild.yaml خود اضافه کنید
در این مرحله شما مرحله گواهی را به خط لوله ساخت ابری خود که قبلا ساخته اید اضافه می کنید.
- مرحله جدیدی را که اضافه می کنید مرور کنید.
فقط مرور کپی نکنید
#Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image' - '--attestor' - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID' - '--keyversion' - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
- فایل 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']
#Sign the image only if the previous severity check passes
- id: 'create-attestation'
name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
args:
- '--artifact-url'
- 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'
- '--attestor'
- 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
- '--keyversion'
- 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
images:
- us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF
Build را اجرا کنید
gcloud builds submit
ساخت را در Cloud Build History مرور کنید
Cloud Console را به صفحه Cloud Build History باز کنید و آخرین ساخت و اجرای موفقیت آمیز مراحل ساخت را مرور کنید.
8. سیاست های کنترل پذیرش
Binary Authorization یک ویژگی در GKE و Cloud Run است که توانایی اعتبارسنجی قوانین را قبل از اجازه اجرا شدن تصویر کانتینر فراهم میکند. اعتبار سنجی در هر درخواستی برای اجرای یک تصویر اجرا می شود، خواه از یک خط لوله قابل اعتماد CI/CD باشد یا کاربری که به صورت دستی سعی در استقرار یک تصویر دارد. این قابلیت به شما این امکان را می دهد که محیط های زمان اجرا خود را به طور موثرتری نسبت به بررسی های خط لوله CI/CD به تنهایی ایمن کنید.
برای درک این قابلیت، خطمشی پیشفرض GKE را تغییر میدهید تا یک قانون مجوز سختگیرانه اعمال شود.
خوشه GKE را ایجاد کنید
خوشه GKE را ایجاد کنید:
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
به Cloud Build اجازه دهید تا در این خوشه مستقر شود:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
Allow All Policy
ابتدا وضعیت خط مشی پیش فرض و توانایی خود را برای استقرار هر تصویر بررسی کنید
- سیاست موجود را مرور کنید
gcloud container binauthz policy export
- توجه داشته باشید که خط مشی اجرایی روی
ALWAYS_ALLOW
تنظیم شده است
evaluationMode: ALWAYS_ALLOW
- برای تأیید اینکه میتوانید هر چیزی را مستقر کنید، Sample را مستقر کنید
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- بررسی کنید که استقرار کار کرده است
kubectl get pods
خروجی زیر را مشاهده خواهید کرد
- استقرار را حذف کنید
kubectl delete pod hello-server
همه خط مشی ها را رد کنید
اکنون خط مشی را به روز کنید تا همه تصاویر مجاز نباشند.
- خط مشی فعلی را به یک فایل قابل ویرایش صادر کنید
gcloud container binauthz policy export > policy.yaml
- سیاست را تغییر دهید
در یک ویرایشگر متن، ارزیابی حالت را از ALWAYS_ALLOW به ALWAYS_DENY تغییر دهید.
edit policy.yaml
فایل سیاست YAML باید به صورت زیر ظاهر شود:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- ترمینال را باز کنید و سیاست جدید را اعمال کنید و چند ثانیه صبر کنید تا تغییر منتشر شود
gcloud container binauthz policy import policy.yaml
- نمونه استقرار حجم کار را امتحان کنید
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- استقرار با پیام زیر ناموفق است
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule
خط مشی را برگردانید تا به همه اجازه داده شود
قبل از رفتن به بخش بعدی، مطمئن شوید که تغییرات سیاست را برگردانید
- سیاست را تغییر دهید
در یک ویرایشگر متن، ارزیابی حالت را از ALWAYS_DENY به ALWAYS_ALLOW تغییر دهید.
edit policy.yaml
فایل سیاست YAML باید به صورت زیر ظاهر شود:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- سیاست برگردانده شده را اعمال کنید
gcloud container binauthz policy import policy.yaml
9. آسیب پذیری ها را در GKE مسدود کنید
در این بخش، آنچه را که تاکنون آموختهاید، با پیادهسازی خط لوله CI/CD با Cloud Build ترکیب میکنید که تصاویر را اسکن میکند، سپس قبل از امضای تصویر و تلاش برای استقرار، آسیبپذیریها را بررسی میکند. GKE از مجوز باینری استفاده میکند تا تأیید کند که تصویر دارای امضای اسکن آسیبپذیری قبل از اجازه دادن به تصویر است.
خط مشی GKE را برای نیاز به گواهی به روز کنید
با افزودن ClusterAdmissionRules به خطمشی GKE BinAuth، تصاویر الزامی است که توسط تأییدکننده شما امضا شوند.
با استفاده از دستور زیر، خط مشی را با پیکربندی به روز شده بازنویسی کنید.
COMPUTE_ZONE=us-central1-a
cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
evaluationMode: ALWAYS_DENY
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
${COMPUTE_ZONE}.binauthz:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM
سیاست را اعمال کنید
gcloud beta container binauthz policy import binauth_policy.yaml
تلاش برای استقرار تصویر بدون امضا
با استفاده از دستور زیر یک توصیفگر استقرار برای برنامه ای که قبلا ساخته اید ایجاد کنید. تصویری که در اینجا استفاده می شود، تصویری است که قبلاً ساخته اید و حاوی آسیب پذیری های مهم است و حاوی گواهی امضا شده نیست.
کنترلکنندههای پذیرش GKE باید تصویر دقیقی را بدانند که باید مستقر شود تا به طور مداوم امضا را تأیید کنند. برای انجام این کار باید از خلاصه تصویر و یک برچسب ساده استفاده کنید.
خلاصه تصویر را برای تصویر بد دریافت کنید
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \
--format='get(image_summary.digest)')
از خلاصه در پیکربندی Kubernetes استفاده کنید
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
سعی کنید برنامه را در GKE مستقر کنید
kubectl apply -f deploy.yaml
حجم کار را در کنسول مرور کنید و به خطای عدم اجرای برنامه توجه کنید:
No attestations found that were valid and signed by a key trusted by the attestor
یک تصویر امضا شده را نصب کنید
خلاصه تصویر را برای تصویر بد دریافت کنید
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \
--format='get(image_summary.digest)')
از خلاصه در پیکربندی Kubernetes استفاده کنید
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
برنامه را در GKE مستقر کنید
kubectl apply -f deploy.yaml
حجم کار را در کنسول مرور کنید و به استقرار موفقیت آمیز تصویر توجه کنید.
10. تبریک می گویم!
تبریک می گویم، شما نرم افزار کد را تمام کردید!
آنچه ما پوشش داده ایم:
- نحوه فعال کردن اسکن خودکار
- نحوه انجام اسکن درخواستی
- نحوه ادغام اسکن در خط لوله ساخت
- نحوه امضای تصاویر تایید شده
- نحوه استفاده از کنترلرهای GKE Admission برای مسدود کردن تصاویر
- چگونه GKE را پیکربندی کنیم تا فقط تصاویر تایید شده امضا شده را مجاز کند
بعدش چیه:
- ایمن سازی استقرار تصاویر در Cloud Run و Google Kubernetes Engine | مستندات ساخت ابر
- شروع سریع: یک خط مشی مجوز باینری را با GKE | پیکربندی کنید Google Cloud
تمیز کردن
برای جلوگیری از تحمیل هزینه به حساب Google Cloud خود برای منابع استفاده شده در این آموزش، یا پروژه حاوی منابع را حذف کنید یا پروژه را نگه دارید و منابع فردی را حذف کنید.
حذف پروژه
ساده ترین راه برای حذف صورتحساب، حذف پروژه ای است که برای آموزش ایجاد کرده اید.