استقرار گیتینگ با احراز هویت باینری

۱. مقدمه

مجوز دودویی (Binary Authorization) یک کنترل امنیتی در زمان استقرار است که تضمین می‌کند فقط تصاویر کانتینر مورد اعتماد در موتور گوگل کوبرنتیز (GKE) یا Cloud Run مستقر شوند. با مجوز دودویی، می‌توانید در طول فرآیند توسعه، تصاویر را ملزم به امضای مقامات معتبر کنید و سپس هنگام استقرار، اعتبارسنجی امضا را اعمال کنید. با اجرای اعتبارسنجی، می‌توانید با اطمینان از اینکه فقط تصاویر تأیید شده در فرآیند ساخت و انتشار ادغام می‌شوند، کنترل دقیق‌تری بر محیط کانتینر خود داشته باشید.

نمودار زیر اجزای موجود در تنظیمات Binary Authorization/Cloud Build را نشان می‌دهد:

خط لوله تأیید مجوز دودویی ساخت ابری. شکل ۱. خط لوله ساخت ابری که یک گواهی مجوز دودویی ایجاد می‌کند.

در این خط لوله:

  1. کد لازم برای ساخت تصویر کانتینر به یک مخزن منبع، مانند مخازن منبع ابری (Cloud Source Repositories) ، ارسال می‌شود.
  2. Cloud Build ، ابزاری برای یکپارچه‌سازی مداوم (CI)، کانتینر را می‌سازد و آزمایش می‌کند.
  3. این ساخت، تصویر کانتینر را به رجیستری کانتینر یا رجیستری دیگری که تصاویر ساخته شده شما را ذخیره می‌کند، ارسال می‌کند.
  4. سرویس مدیریت کلید ابری ، که مدیریت کلید را برای جفت کلید رمزنگاری فراهم می‌کند، تصویر کانتینر را امضا می‌کند. امضای حاصل سپس در یک گواهی تازه ایجاد شده ذخیره می‌شود.
  5. در زمان استقرار، گواهی‌دهنده، گواهی را با استفاده از کلید عمومی از جفت کلید تأیید می‌کند. مجوز دودویی با الزام گواهی‌های امضا شده برای استقرار تصویر کانتینر، این سیاست را اعمال می‌کند.

در این آزمایش شما بر ابزارها و تکنیک‌هایی برای ایمن‌سازی مصنوعات مستقر شده تمرکز خواهید کرد. این آزمایش بر مصنوعات (کانتینرها) پس از ایجاد شدن اما عدم استقرار آنها در هیچ محیط خاصی تمرکز دارد.

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

  • امضای تصویر
  • سیاست‌های کنترل پذیرش
  • امضای تصاویر اسکن شده
  • تأیید تصاویر امضا شده
  • تصاویر بدون امضا مسدود شده

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

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

  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 

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

در این آزمایش شما از 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

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

mkdir vuln-scan && cd vuln-scan

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

یک فایل به نام 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

یک فایل به نام 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 استفاده کنید.

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

۳. امضای تصویر

گواهی دهنده چیست؟

گواهی دهنده

  • این شخص/فرآیند مسئول یکی از حلقه‌های زنجیره اعتماد سیستم است.
  • آنها یک کلید رمزنگاری دارند و اگر تصویری از فرآیند تأیید آنها عبور کند، آن را امضا می‌کنند.
  • در حالی که ایجادکننده‌ی سیاست، سیاست را به شیوه‌ای انتزاعی و سطح بالا تعیین می‌کند، گواهی‌دهنده مسئول اجرای عینی برخی از جنبه‌های سیاست است.
  • می‌تواند یک شخص حقیقی باشد، مانند یک تستر تضمین کیفیت یا یک مدیر، یا می‌تواند یک ربات در یک سیستم هوش رقابتی (CI) باشد.
  • امنیت سیستم به قابل اعتماد بودن آنها بستگی دارد، بنابراین مهم است که کلیدهای خصوصی آنها ایمن نگه داشته شوند.

هر یک از این نقش‌ها می‌توانند نماینده یک شخص یا تیمی از افراد در سازمان شما باشند. در یک محیط عملیاتی، این نقش‌ها احتمالاً توسط پروژه‌های جداگانه Google Cloud Platform (GCP) مدیریت می‌شوند و دسترسی به منابع با استفاده از Cloud IAM به صورت محدود بین آنها به اشتراک گذاشته می‌شود.

a37eb2ed54b9c2eb.png

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

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

208aa5ebc53ff2b3.png

در کنار ردیابی آسیب‌پذیری‌ها، تحلیل کانتینر به عنوان یک API عمومی فراداده طراحی شده است. احراز هویت دودویی از تحلیل کانتینر برای مرتبط کردن امضاها با تصاویر کانتینری که آنها تأیید می‌کنند استفاده می‌کند.**.** یک یادداشت تحلیل کانتینر برای نمایش یک گواهی‌دهنده واحد استفاده می‌شود و رخدادها (Occurrences) ایجاد شده و با هر کانتینری که گواهی‌دهنده تأیید کرده است، مرتبط می‌شوند.

API احراز هویت دودویی از مفاهیم «گواهی‌دهندگان» و «گواهی‌ها» استفاده می‌کند، اما این مفاهیم با استفاده از یادداشت‌ها و رخدادهای مربوطه در API تحلیل کانتینر پیاده‌سازی می‌شوند.

63a701bd0057ea17.png

ایجاد یادداشت گواهی دهنده

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

919f997db0ffb881.png

ایجاد یادداشت

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}"

یادداشت شما اکنون در API تحلیل کانتینر ذخیره شده است.

ایجاد یک گواهی دهنده

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

ed05d438c79b654d.png

ایجاد گواهی‌دهنده

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 هنگام اجرای یک build که تصاویر را تولید می‌کند، به طور خودکار گواهی built-by-cloud-build را در پروژه شما ایجاد می‌کند. بنابراین دستور بالا دو گواهی vulnz-attestor و built-by-cloud-build را برمی‌گرداند. پس از ساخت موفقیت‌آمیز تصاویر، Cloud Build به طور خودکار گواهی‌ها را برای آنها امضا و ایجاد می‌کند.

افزودن نقش IAM

حساب کاربری سرویس احراز هویت دودویی (Binary Authorization) برای مشاهده یادداشت‌های تأیید به دسترسی نیاز دارد. با فراخوانی 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

1e3af7c177f7a311.png

قبل از اینکه بتوانید از این گواهی‌دهنده استفاده کنید، مرجع شما باید یک جفت کلید رمزنگاری ایجاد کند که بتوان از آن برای امضای تصاویر کانتینر استفاده کرد. این کار را می‌توان از طریق سرویس مدیریت کلید ابری گوگل (KMS) انجام داد.

ابتدا چند متغیر محیطی برای توصیف کلید جدید اضافه کنید

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 Cloud مشاهده کنید.

اکنون، کلید را از طریق دستور 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

ایجاد گواهی امضا شده

در این مرحله، ویژگی‌هایی که به شما امکان امضای تصاویر را می‌دهند، پیکربندی شده‌اند. از Attestor که قبلاً ایجاد کرده‌اید، برای امضای تصویر کانتینری که با آن کار می‌کردید، استفاده کنید.

858d7e6feeb6f159.png

یک گواهی باید شامل یک امضای رمزنگاری باشد تا بیان کند که گواهی‌دهنده، یک تصویر کانتینر خاص را تأیید کرده و اجرای آن روی کلاستر شما ایمن است. برای مشخص کردن اینکه کدام تصویر کانتینر را گواهی کنید، باید خلاصه آن را تعیین کنید.

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}"

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

gcloud container binauthz attestations list \
   --attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}

۴. سیاست‌های کنترل پذیرش

احراز هویت دودویی (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"

اجازه دادن به همه سیاست‌ها

ابتدا وضعیت پیش‌فرض سیاست و توانایی خود را برای استقرار هر تصویری بررسی کنید

  1. بررسی سیاست‌های موجود
gcloud container binauthz policy export
  1. توجه داشته باشید که سیاست اعمال قانون روی ALWAYS_ALLOW تنظیم شده است.

evaluationMode: ALWAYS_ALLOW

  1. نمونه را مستقر کنید تا تأیید کنید که می‌توانید هر چیزی را مستقر کنید
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. تأیید کنید که استقرار کار کرده است
kubectl get pods

خروجی زیر را مشاهده خواهید کرد

۱۶۱db370d99ffb13.png

  1. حذف استقرار
kubectl delete pod hello-server

رد کردن همه سیاست‌ها

اکنون خط‌مشی را به‌روزرسانی کنید تا همه تصاویر را مجاز نکنید.

  1. سیاست فعلی را به یک فایل قابل ویرایش صادر کنید
gcloud container binauthz policy export  > policy.yaml
  1. تغییر سیاست

در یک ویرایشگر متن، evaluationMode را از 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

این سیاست نسبتاً ساده است. خط globalPolicyEvaluationMode اعلام می‌کند که این سیاست، سیاست جهانی تعریف‌شده توسط گوگل را گسترش می‌دهد. این امر به همه کانتینرهای رسمی GKE اجازه می‌دهد تا به‌طور پیش‌فرض اجرا شوند. علاوه بر این، این سیاست یک defaultAdmissionRule اعلام می‌کند که بیان می‌کند همه پادهای دیگر رد خواهند شد . قانون پذیرش شامل یک خط enforcementMode است که بیان می‌کند همه پادهایی که با این قانون مطابقت ندارند باید از اجرا در کلاستر مسدود شوند.

برای دستورالعمل‌هایی در مورد نحوه‌ی ساخت سیاست‌های پیچیده‌تر، به مستندات Binary Authorization مراجعه کنید.

657752497e59378c.png

  1. ترمینال را باز کنید و سیاست جدید را اعمال کنید و چند ثانیه صبر کنید تا تغییر اعمال شود.
gcloud container binauthz policy import policy.yaml
  1. نمونه‌ای از استقرار حجم کار را امتحان کنید
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. نصب با پیغام زیر با شکست مواجه می‌شود
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

سیاست را برگردانید تا همه مجاز باشند

قبل از رفتن به بخش بعدی، حتماً تغییرات سیاست را به حالت اولیه برگردانید

  1. تغییر سیاست

در یک ویرایشگر متن، evaluationMode را از 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
  1. اعمال سیاست برگشتی
gcloud container binauthz policy import policy.yaml

۵. امضای تصاویر اسکن شده

شما امضای تصویر را فعال کرده‌اید و به صورت دستی از Attestor برای امضای تصویر نمونه خود استفاده کرده‌اید. در عمل، شما می‌خواهید Attestationها را در طول فرآیندهای خودکار مانند CI/CD pipelines اعمال کنید.

در این بخش ، Cloud Build را طوری پیکربندی می‌کنید که تصاویر را به طور خودکار تأیید کند.

نقش‌ها

نقش Binary Authorization Attestor Viewer را به حساب سرویس Cloud Build اضافه کنید:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/binaryauthorization.attestorsViewer

نقش امضاکننده/تأییدکننده‌ی کلید رمزنگاری‌شده‌ی Cloud KMS را به حساب سرویس ساخت ابری (امضای مبتنی بر KMS) اضافه کنید:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/cloudkms.signerVerifier

نقش Attacher مربوط به یادداشت‌های تحلیل کانتینر را به حساب سرویس Cloud Build اضافه کنید:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/containeranalysis.notes.attacher

دسترسی به حساب سرویس ساخت ابری (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"

آماده‌سازی مرحله ساخت ابری سفارشی

شما از یک مرحله ساخت سفارشی در Cloud Build برای ساده‌سازی فرآیند گواهی استفاده خواهید کرد. گوگل این مرحله ساخت سفارشی را ارائه می‌دهد که شامل توابع کمکی برای ساده‌سازی فرآیند است. قبل از استفاده، کد مرحله ساخت سفارشی باید در یک کانتینر ساخته شده و به 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 خود اضافه کنید

در این مرحله، مرحله‌ی تأیید را به خط تولید ابری خود اضافه خواهید کرد.

  1. مرحله امضای زیر را مرور کنید.

فقط نقد. کپی نکنید

#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'
  1. یک فایل 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

اجرای ساخت

gcloud builds submit

بررسی ساخت در تاریخچه ساخت ابری

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

۶. تأیید تصاویر امضا شده

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

d5c41bb89e22fd61.png

به‌روزرسانی سیاست 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

اکنون باید یک فایل جدید روی دیسک به نام updated_policy.yaml داشته باشید. اکنون، به جای اینکه قانون پیش‌فرض همه تصاویر را رد کند، ابتدا گواهی‌دهنده شما را برای تأیید بررسی می‌کند.

822240fc0b02408e.png

سیاست جدید را در Binary Authorization آپلود کنید:

gcloud beta container binauthz policy import binauth_policy.yaml

یک تصویر امضا شده را مستقر کنید

خلاصه تصویر را برای تصویر خوب دریافت کنید

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)')

از 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

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

۷. تصاویر بدون امضا مسدود شده

ساخت یک تصویر

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

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

تصویر امضا نشده را به مخزن ارسال کنید

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

خلاصه تصویر بد را دریافت کنید

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)')

از 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

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

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

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

  • امضای تصویر
  • سیاست‌های کنترل پذیرش
  • امضای تصاویر اسکن شده
  • تأیید تصاویر امضا شده
  • تصاویر بدون امضا مسدود شده

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

تمیز کردن

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

حذف پروژه

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

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