1. مقدمة
توفِّر أداة Container Analysis فحص الثغرات الأمنية وتخزين البيانات الوصفية للحاويات. تُجري خدمة الفحص عمليات فحص بحثًا عن ثغرات أمنية على الصور في Artifact Registry وContainer Registry، ثم تخزِّن البيانات الوصفية الناتجة وتجعلها متاحة للاستهلاك من خلال واجهة برمجة تطبيقات. تتيح لك مساحة تخزين البيانات الوصفية تخزين معلومات من مصادر مختلفة، بما في ذلك فحص الثغرات الأمنية وخدمات Google Cloud ومقدّمي الخدمات التابعين لجهات خارجية.
يمكن أن يتم فحص الثغرات الأمنية تلقائيًا أو عند الطلب:
- عند تفعيل الفحص التلقائي، يتم تشغيل الفحص تلقائيًا في كل مرة ترسل فيها صورة جديدة إلى Artifact Registry أو Container Registry. يتم تحديث معلومات الثغرات الأمنية باستمرار عند اكتشاف ثغرات جديدة.
- عندما تكون ميزة الفحص عند الطلب مفعَّلة، عليك تنفيذ أمر لفحص صورة محلية أو صورة في Artifact Registry أو Container Registry. ويمنحك المسح عند الطلب المرونة اللازمة عند فحص الحاويات. على سبيل المثال، يمكنك فحص صورة تم إنشاؤها محليًا ومعالجة الثغرات الأمنية قبل تخزينها في السجل. تتوفر نتائج الفحص لمدة تصل إلى 48 ساعة بعد اكتمال الفحص، ولا يتم تحديث معلومات الثغرات الأمنية بعد الفحص.
من خلال دمج أداة Container Analysis في مسار CI/CD، يمكنك اتّخاذ القرارات استنادًا إلى هذه البيانات الوصفية. مثلاً، يمكنك استخدام التفويض الثنائي لإنشاء سياسات نشر تسمح فقط بعمليات نشر الصور المتوافقة من قواعد بيانات المسجّلين الموثوق بها.
المعلومات التي ستطّلع عليها
- كيفية تفعيل الفحص التلقائي
- طريقة إجراء "المسح عند الطلب"
- كيفية دمج الفحص في مسار الإصدار
- كيفية توقيع الصور التي تمت الموافقة عليها
- طريقة استخدام وحدات التحكّم في قبول GKE لحظر الصور
- كيفية إعداد GKE للسماح فقط بالصور الموقَّعة التي تمت الموافقة عليها
2. الإعداد والمتطلبات
إعداد بيئة ذاتية
- سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.
- اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديله في أي وقت.
- يكون رقم تعريف المشروع فريدًا في جميع مشاريع Google Cloud وغير قابل للتغيير (لا يمكن تغييره بعد تحديده). تنشئ Cloud Console سلسلة فريدة تلقائيًا. فعادةً لا تهتم بما هو. في معظم الدروس التطبيقية حول الترميز، يجب الإشارة إلى رقم تعريف المشروع (يتم تحديده عادةً على أنّه
PROJECT_ID
). وإذا لم يعجبك المعرّف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. ويمكنك بدلاً من ذلك تجربة طلبك الخاص ومعرفة ما إذا كان متوفّرًا. ولا يمكن تغييره بعد هذه الخطوة وسيبقى طوال مدة المشروع. - لمعلوماتك، هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. اطّلِع على مزيد من المعلومات حول هذه القيم الثلاث في المستندات.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام الموارد/واجهات برمجة التطبيقات في Cloud. إنّ تنفيذ هذا الدرس التطبيقي حول الترميز لن يكون مكلفًا أو مكلفًا على الإطلاق. لإيقاف تشغيل الموارد حتى لا تتحمل الفوترة بعد هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع بالكامل. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج فترة تجريبية مجانية بقيمة 300 دولار أمريكي.
بدء محرِّر Cloudshell
تم تصميم هذا الدرس التطبيقي واختباره للاستخدام مع Google Cloud Shell Editor. للوصول إلى المحرر،
- انتقِل إلى مشروع 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
إنشاء الصورة ودفعها إلى الواقع المعزّز
يمكنك استخدام 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
- انقر على Artifact-scanning-repo لعرض المحتوى
- انقر على تفاصيل الصورة.
- انقر على أحدث ملخّص لصورتك.
- بعد انتهاء الفحص، انقر على علامة تبويب الثغرات الأمنية في الصورة.
من علامة تبويب الثغرات الأمنية، سترى نتائج الفحص التلقائي للصورة التي أنشأتها للتو.
يتم تفعيل الفحص الآلي تلقائيًا. يمكنك استكشاف إعدادات Artifact Registry لمعرفة كيفية إيقاف الفحص التلقائي أو تفعيله.
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
مراجعة ملف الإخراج
يُرجى تخصيص بعض الوقت لمراجعة نتائج الخطوة السابقة التي تم تخزينها في ملف delivery_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
يجب أن يحصل 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
تشغيل مسار CI
أرسِل الإصدار للمعالجة للتحقّق من تعطُّله عند العثور على ثغرة أمنية خطيرة.
gcloud builds submit
تعذّر إصدار المراجعة
سيتعذّر الإصدار الذي أرسلته للتوّ لأنّ الصورة تحتوي على ثغرات أمنية خطيرة.
مراجعة المشاكل التي تعذّر تنفيذها في صفحة سجلّ إنشاء Cloud
إصلاح الثغرة الأمنية
عليك تعديل الملف الشامل لاستخدام صورة أساسية لا تحتوي على ثغرات أمنية خطيرة.
استبدِل ملف 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
تنفيذ عملية CI باستخدام الصورة الجيدة
أرسِل الإصدار للمعالجة للتأكّد من نجاحه في حال عدم العثور على ثغرات أمنية خطيرة.
gcloud builds submit
إنشاء مراجعة بنجاح
سينجح الإصدار الذي أرسلته للتوّ لأنّ الصورة المعدّلة لا تحتوي على ثغرات أمنية خطيرة.
مراجعة نجاح الإصدار في صفحة سجلّ إنشاء Cloud
مراجعة نتائج الفحص
مراجعة الصورة الجيدة في سجلّ Artifact
- فتح Artifact Registry في Cloud Console
- انقر على Artifact-scanning-repo لعرض المحتوى
- انقر على تفاصيل الصورة.
- انقر على أحدث ملخّص لصورتك.
- انقر على علامة تبويب الثغرات الأمنية في الصورة
6- توقيع الصور
إنشاء ملاحظة مصادق
ملاحظة المصدق هي مجرد جزء صغير من البيانات يعمل كتصنيف لنوع التوقيع الذي يتم تطبيقه. على سبيل المثال، قد تشير إحدى الملاحظات إلى فحص الثغرات الأمنية، بينما قد يتم استخدام ملاحظة أخرى لتوقيع تأكيد الجودة. ستتم الإشارة إلى الملاحظة أثناء عملية التوقيع.
إنشاء ملاحظة
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 تلقائيًا وتنشئ شهادات لها.
جارٍ إضافة دور "إدارة الهوية وإمكانية الوصول"
سيحتاج حساب خدمة التفويض الثنائي إلى حقوق لعرض ملاحظات المصادقة. توفير إمكانية الوصول من خلال طلب البيانات التالي من واجهة برمجة التطبيقات
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
لقد فعّلت توقيع الصورة واستخدمت المصدق يدويًا للتوقيع على نموذج الصورة. من الناحية العملية، ستحتاج إلى تطبيق الإقرارات أثناء العمليات الآلية مثل مسارات الإحالات الناجحة خارج إطار الإنترنت (CI/CD).
في هذا القسم، سيتم ضبط Cloud Build على "مصادقة الصور" تلقائيًا.
الأدوار
إضافة دور "مُشاهد التفويض الثنائي" إلى حساب خدمة Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
إضافة دور الموقِّع أو جهة التحقُّق من Cloud KMS إلى حساب خدمة Cloud Build (التوقيع المستنِد إلى KMS):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
إضافة دور إرفاق ملاحظات تحليل الحاوية إلى حساب خدمة 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
في هذه الخطوة، عليك إضافة خطوة المصادقة إلى مسار 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 Console للانتقال إلى صفحة "سجلّ إنشاء Cloud" وراجِع آخر إصدار وعملية التنفيذ الناجحة لخطوات الإصدار.
8. سياسات مراقبة الدخول
التفويض الثنائي هو ميزة في GKE وCloud Run توفّر إمكانية التحقّق من صحة القواعد قبل السماح بتشغيل صورة الحاوية. يتم تنفيذ عملية التحقّق على أي طلب لتشغيل أي صورة، سواء كانت من مسار 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 "تفويضًا ثنائيًا" للتأكّد من أنّ الصورة لها توقيع من فحص الثغرات الأمنية قبل السماح بتشغيل الصورة.
تعديل سياسة 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 لحظر الصور
- كيفية إعداد GKE للسماح فقط بالصور الموقَّعة التي تمت الموافقة عليها
الخطوة التالية:
- تأمين عمليات نشر الصور في Cloud Run وGoogle Kubernetes Engine | مستندات Cloud Build
- البدء السريع: ضبط سياسة التفويض الثنائي باستخدام GKE | Google Cloud
تَنظيم
لتجنُّب تحمُّل الرسوم المفروضة على حسابك على Google Cloud مقابل الموارد المُستخدَمة في هذا الدليل التوجيهي، يمكنك إما حذف المشروع الذي يحتوي على الموارد أو الاحتفاظ بالمشروع وحذف الموارد الفردية.
حذف المشروع
أسهل طريقة لإزالة الفوترة هي حذف المشروع الذي أنشأته للبرنامج التعليمي.