1. مقدمة
توفّر خدمة "تحليل الحاويات" إمكانية فحص الثغرات الأمنية وتخزين البيانات الوصفية للحاويات. تُجري خدمة الفحص عمليات فحص الثغرات الأمنية على الصور في Artifact Registry وContainer Registry، ثم تخزِّن البيانات الوصفية الناتجة وتتيح استخدامها من خلال واجهة برمجة تطبيقات. يتيح لك تخزين البيانات الوصفية تخزين معلومات من مصادر مختلفة، بما في ذلك فحص الثغرات الأمنية وخدمات Google Cloud ومقدّمي الخدمات الخارجيين.
يمكن إجراء عملية فحص الثغرات الأمنية تلقائيًا أو عند الطلب:
- عند تفعيل الفحص التلقائي، يتم تشغيل الفحص تلقائيًا في كل مرة ترسل فيها صورة جديدة إلى Artifact Registry أو Container Registry. يتم تعديل معلومات الثغرات الأمنية باستمرار عند اكتشاف ثغرات جديدة.
- عند تفعيل المسح عند الطلب، يجب تنفيذ أمر لمسح صورة محلية أو صورة في Artifact Registry أو Container Registry. تمنحك ميزة "المسح عند الطلب" المرونة في تحديد وقت مسح الحاويات. على سبيل المثال، يمكنك فحص صورة تم إنشاؤها محليًا ومعالجة الثغرات الأمنية قبل تخزينها في سجلّ. تتوفّر نتائج الفحص لمدة تصل إلى 48 ساعة بعد اكتماله، ولا يتم تعديل معلومات الثغرات الأمنية بعد الفحص.
من خلال دمج "تحليل الحاويات" في مسار CI/CD، يمكنك اتّخاذ قرارات استنادًا إلى تلك البيانات الوصفية. على سبيل المثال، يمكنك استخدام Binary Authorization لإنشاء سياسات نشر لا تسمح إلا بنشر الصور المتوافقة من سجلات موثوقة.
ما ستتعلمه
- كيفية تفعيل ميزة "المسح التلقائي"
- كيفية إجراء عملية المسح عند الطلب
- كيفية دمج عملية الفحص في مسار الإنشاء
- كيفية توقيع الصور المعتمدة
- كيفية استخدام أدوات التحكّم في القبول في GKE لحظر الصور
- كيفية إعداد GKE للسماح فقط بالصور الموقّعة التي تمت الموافقة عليها
2. الإعداد والمتطلبات
إعداد البيئة بوتيرة ذاتية
- سجِّل الدخول إلى Google Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.



- اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديله في أي وقت.
- رقم تعريف المشروع هو معرّف فريد في جميع مشاريع Google Cloud ولا يمكن تغييره بعد ضبطه. تنشئ Cloud Console تلقائيًا سلسلة فريدة، ولا يهمّك عادةً ما هي. في معظم دروس البرمجة، عليك الرجوع إلى رقم تعريف المشروع (يتم تحديده عادةً على أنّه
PROJECT_ID). إذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. يمكنك بدلاً من ذلك تجربة اسم مستخدم من اختيارك لمعرفة ما إذا كان متاحًا. لا يمكن تغيير هذا الخيار بعد هذه الخطوة وسيظل ساريًا طوال مدة المشروع. - للعلم، هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن كل هذه القيم الثلاث في المستندات.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن تكلفك تجربة هذا الدرس التطبيقي حول الترميز الكثير من المال، إن لم تكلفك شيئًا على الإطلاق. لإيقاف الموارد كي لا يتم تحصيل رسوم منك بعد هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع بأكمله. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.
بدء Cloudshell Editor
تم تصميم هذا المختبر واختباره لاستخدامه مع "محرّر Google Cloud Shell". للوصول إلى المحرِّر، اتّبِع الخطوات التالية:
- الوصول إلى مشروعك على Google من خلال https://console.cloud.google.com
- في أعلى يسار الصفحة، انقر على رمز محرر Cloud Shell

- سيتم فتح لوحة جديدة في أسفل النافذة
إعداد البيئة
في 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
في هذا الدرس التطبيقي، ستستخدم Artifact Registry لتخزين صورك وفحصها. أنشئ المستودع باستخدام الأمر التالي.
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository"
اضبط Docker لاستخدام بيانات اعتماد gcloud عند الوصول إلى Artifact Registry.
gcloud auth configure-docker us-central1-docker.pkg.dev
3- المسح التلقائي
يتم تشغيل فحص العناصر تلقائيًا في كل مرة ترسل فيها صورة جديدة إلى Artifact Registry أو Container Registry. يتم تعديل معلومات الثغرات الأمنية باستمرار عند اكتشاف ثغرات جديدة. في هذا القسم، ستنقل صورة إلى Artifact Registry وتستكشف النتائج.
إنشاء دليل عمل والانتقال إليه
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 Registry في Cloud Console
- انقر على مستودع فحص العناصر لعرض المحتوى
- انقر على تفاصيل الصورة
- النقر على أحدث ملخّص لصورتك
- بعد انتهاء عملية الفحص، انقر على علامة التبويب "الثغرات الأمنية" (Vulnerabilities) الخاصة بالصورة.
من علامة التبويب "الثغرات الأمنية"، ستظهر لك نتائج الفحص التلقائي للصورة التي أنشأتها للتو.

تكون ميزة "أتمتة عملية المسح" مفعّلة تلقائيًا. استكشِف إعدادات Artifact Registry لمعرفة كيفية إيقاف/تفعيل ميزة "المسح التلقائي".
4. On-Demand Scanning
هناك سيناريوهات مختلفة قد تحتاج فيها إلى إجراء عملية فحص قبل إرسال الصورة إلى مستودع. على سبيل المثال، يمكن لمطوّر حاوية فحص صورة وإصلاح المشاكل قبل إرسال الرمز إلى نظام التحكّم بالمصادر. في المثال أدناه، ستنشئ الصورة وتحلّلها محليًا قبل اتّخاذ إجراء بشأن النتائج.
إنشاء صورة
في هذه الخطوة، ستستخدم 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- Build Pipeline Scanning
في هذا القسم، ستنشئ مسار إنشاء آليًا ينشئ صورة الحاوية ويفحصها ثم يقيّم النتائج. إذا لم يتم العثور على ثغرات أمنية خطيرة، سيتم إرسال الصورة إلى المستودع. في حال العثور على ثغرات أمنية CRITICAL، سيتعذّر إنشاء الإصدار وسيتم الخروج منه.
منح إذن الوصول إلى حساب خدمة Cloud Build
ستحتاج Cloud Build إلى أذونات للوصول إلى واجهة برمجة التطبيقات الخاصة بالفحص عند الطلب. امنح الإذن بالوصول باستخدام الأوامر التالية.
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
سينشئ الأمر التالي ملف 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
تشغيل مسار التكامل المستمر
أرسِل الإصدار للمعالجة للتحقّق من تعطّله عند العثور على ثغرة أمنية ذات خطورة بالغة.
gcloud builds submit
تعذُّر إنشاء المراجعة
ستتعذّر عملية إنشاء الإصدار الذي أرسلته للتو لأنّ الصورة تحتوي على ثغرات أمنية خطيرة.
مراجعة خطأ الإنشاء في صفحة سجلّ Cloud Build
إصلاح الثغرة الأمنية
عدِّل Dockerfile لاستخدام صورة أساسية لا تحتوي على ثغرات أمنية خطيرة.
استبدِل Dockerfile لاستخدام صورة Debian 10 باستخدام الأمر التالي
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
تنفيذ عملية التكامل المستمر باستخدام الصورة الجيدة
أرسِل الإصدار للمعالجة للتحقّق من نجاحه في حال عدم العثور على ثغرات أمنية ذات خطورة بالغة.
gcloud builds submit
مراجعة نجاح عملية الإنشاء
سيكون الإصدار الذي أرسلته للتو ناجحًا لأنّ الصورة المعدَّلة لا تحتوي على ثغرات أمنية CRITICAL.
راجِع نجاح عملية الإنشاء في صفحة سجلّ Cloud Build.
مراجعة نتائج الفحص
مراجعة الصورة الجيدة في Artifact Registry
- افتح Artifact Registry في Cloud Console
- انقر على مستودع فحص العناصر لعرض المحتوى
- انقر على تفاصيل الصورة
- النقر على أحدث ملخّص لصورتك
- انقر على علامة التبويب "الثغرات الأمنية" الخاصة بالصورة.
6. توقيع الصور
إنشاء ملاحظة Attestor
ملاحظة Attestor هي ببساطة جزء صغير من البيانات يعمل كتسمية لنوع التوقيع الذي يتم تطبيقه. على سبيل المثال، قد تشير إحدى الملاحظات إلى فحص الثغرات الأمنية، بينما يمكن استخدام ملاحظة أخرى للموافقة على ضمان الجودة. سيتم الرجوع إلى الملاحظة أثناء عملية التوقيع.
إنشاء ملاحظة
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 عليها تلقائيًا وتنشئ شهادات إثبات صحة لها.
إضافة دور "إدارة الهوية وإمكانية الوصول"
سيحتاج حساب خدمة Binary Authorization إلى أذونات لعرض ملاحظات التصديق. امنح الإذن بالوصول من خلال طلب بيانات من واجهة برمجة التطبيقات التالي
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
استخدام الملف لإنشاء سياسة إدارة الهوية وإمكانية الوصول
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
يحتاج "المُصدِّق" إلى مفاتيح تشفير لإرفاق الملاحظة وتقديم توقيعات يمكن التحقّق منها. في هذه الخطوة، ستنشئ مفاتيح وتخزّنها في 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 Cloud Console.
الآن، اربط المفتاح بجهة التصديق من خلال الأمر 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 التي أنشأتها سابقًا لتوقيع صورة الحاوية التي كنت تعمل عليها.
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}
7. التوقيع باستخدام Cloud Build
لقد فعّلت ميزة "توقيع الصور" واستخدمت خدمة Attestor يدويًا لتوقيع الصورة النموذجية. في الواقع، ستحتاج إلى تطبيق الشهادات أثناء العمليات المبرمَجة، مثل مسارات CI/CD.
في هذا القسم، ستضبط Cloud Build لإثبات صحة الصور تلقائيًا.
الأدوار
أضِف دور "مُشاهد شهادة Binary Authorization" إلى حساب خدمة Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
أضِف دور Cloud KMS CryptoKey Signer/Verifier إلى حساب خدمة Cloud Build (التوقيع المستند إلى KMS):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
أضِف دور "مرفق الملاحظات في Container Analysis" إلى حساب خدمة Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
إعداد خطوة Custom Build Cloud Build
ستستخدم خطوة "إنشاء مخصّص" في 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
في هذه الخطوة، ستضيف خطوة التصديق إلى مسار Cloud Build الذي أنشأته سابقًا.
- راجِع الخطوة الجديدة التي ستضيفها.
المراجعة فقط عدم النسخ
#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
تشغيل الإصدار
gcloud builds submit
مراجعة الإصدار في "سجلّ Cloud Build"
افتح Cloud Console وانتقِل إلى صفحة "سجلّ Cloud Build" وراجِع أحدث إصدار وتنفيذ خطوات الإصدار بنجاح.
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"
سياسة "السماح بالكل"
عليك أولاً التحقّق من حالة السياسة التلقائية ومن إمكانية نشر أي صورة
- مراجعة السياسة الحالية
gcloud container binauthz policy export
- لاحظ أنّ سياسة التنفيذ مضبوطة على
ALWAYS_ALLOW
evaluationMode: ALWAYS_ALLOW
- نشر نموذج للتحقّق من إمكانية نشر أي شيء
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
- تغيير السياسة
في محرّر نصوص، غيِّر قيمة 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
- افتح Terminal وطبِّق السياسة الجديدة وانتظر بضع ثوانٍ حتى يتم نشر التغيير.
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
إعادة السياسة إلى السماح بالكل
قبل الانتقال إلى القسم التالي، احرص على إعادة تغييرات السياسة إلى حالتها السابقة.
- تغيير السياسة
في محرّر نصوص، غيِّر قيمة 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
- تطبيق السياسة التي تمّت إعادتها
gcloud container binauthz policy import policy.yaml
9- حظر الثغرات الأمنية في GKE
في هذا القسم، ستجمع بين ما تعلّمته حتى الآن من خلال تنفيذ مسار CI/CD باستخدام Cloud Build الذي يفحص الصور، ثم يتحقّق من الثغرات الأمنية قبل توقيع الصورة ومحاولة نشرها. سيستخدم GKE خدمة Binary Authorization للتحقّق من أنّ الصورة تتضمّن توقيعًا من خدمة "فحص الثغرات الأمنية" قبل السماح بتشغيل الصورة.

تعديل سياسة GKE لتتطلّب شهادة إثبات
تتطلّب الصور أن يوقّع عليها Attestor من خلال إضافة 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 لحظر الصور
- كيفية إعداد GKE للسماح فقط بالصور الموقّعة التي تمت الموافقة عليها
الخطوة التالية:
- تأمين عمليات نشر الصور في Cloud Run وGoogle Kubernetes Engine | مستندات Cloud Build
- بدء الاستخدام السريع: ضبط سياسة Binary Authorization باستخدام GKE | Google Cloud
تَنظيم
لتجنُّب تحمّل رسوم في حسابك على Google Cloud مقابل الموارد المستخدَمة في هذا البرنامج التعليمي، احذف المشروع الذي يحتوي على الموارد أو احتفظ بالمشروع واحذف الموارد الفردية.
حذف المشروع
أسهل طريقة لإيقاف الفوترة هي حذف المشروع الذي أنشأته لتنفيذ البرنامج التعليمي.