عمليات نشر القيود باستخدام المصادقة الثنائية

1. مقدمة

‫Binary Authorization هي أداة تحكّم في الأمان في وقت النشر تضمن عدم نشر سوى صور الحاويات الموثوق بها على Google Kubernetes Engine (GKE) أو Cloud Run. باستخدام "المصادقة الثنائية"، يمكنك أن تطلب أن يتم توقيع الصور من قِبل جهات موثوقة أثناء عملية التطوير، ثم فرض التحقّق من التوقيع عند النشر. من خلال فرض عملية التحقّق، يمكنك التحكّم بشكل أكبر في بيئة الحاوية من خلال ضمان دمج الصور التي تم التحقّق منها فقط في عملية الإنشاء والإصدار.

يوضّح المخطّط البياني التالي المكوّنات في عملية إعداد Binary Authorization/Cloud Build:

مسار تأكيد Binary Authorization في Cloud Build**الشكل 1:**مسار Cloud Build الذي ينشئ شهادة Binary Authorization

في مسار التجهيز هذا:

  1. يتم نقل الرمز البرمجي لإنشاء صورة الحاوية إلى مستودع مصدر، مثل Cloud Source Repositories.
  2. تنشئ أداة التكامل المستمر (CI) المعروفة باسم Cloud Build الحاوية وتختبرها.
  3. يدفع الإصدار صورة الحاوية إلى Container Registry أو سجلّ آخر يخزّن الصور التي تم إنشاؤها.
  4. توقّع خدمة إدارة المفاتيح في السحابة الإلكترونية، التي توفّر إدارة المفاتيح لزوج مفاتيح التشفير، صورة الحاوية. يتم بعد ذلك تخزين التوقيع الناتج في شهادة جديدة تم إنشاؤها.
  5. عند النشر، يتحقّق المُصدِر من صحة بيان الإثبات باستخدام المفتاح العام من زوج المفاتيح. تفرض خدمة تفويض الثنائيات السياسة من خلال طلب شهادات إثبات موقَّعة لتفعيل صورة الحاوية.

في هذا الدرس التطبيقي، ستركز على الأدوات والتقنيات اللازمة لتأمين العناصر التي تم نشرها. يركّز هذا التمرين العملي على العناصر (الحاويات) بعد إنشائها ولكن بدون نشرها في أي بيئة معيّنة.

ما ستتعلمه

  • توقيع الصور
  • سياسات التحكّم في القبول
  • توقيع الصور الممسوحة ضوئيًا
  • منح الإذن باستخدام الصور الموقّعة
  • حظر الصور غير الموقَّعة

2. الإعداد والمتطلبات

إعداد البيئة بوتيرة ذاتية

  1. سجِّل الدخول إلى Google Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديله في أي وقت.
  • رقم تعريف المشروع هو معرّف فريد في جميع مشاريع Google Cloud ولا يمكن تغييره بعد ضبطه. تنشئ Cloud Console تلقائيًا سلسلة فريدة، ولا يهمّك عادةً ما هي. في معظم دروس البرمجة، عليك الرجوع إلى رقم تعريف المشروع (يتم تحديده عادةً على أنّه PROJECT_ID). إذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. يمكنك بدلاً من ذلك تجربة اسم مستخدم من اختيارك ومعرفة ما إذا كان متاحًا. لا يمكن تغيير هذا الخيار بعد هذه الخطوة وسيظل ساريًا طوال مدة المشروع.
  • للعلم، هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن كل هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن تكلفك تجربة هذا الدرس البرمجي الكثير من المال، إن لم تكلفك شيئًا على الإطلاق. لإيقاف الموارد كي لا يتم تحصيل رسوم منك بعد هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع بأكمله. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.

إعداد البيئة

في 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

إنشاء دليل عمل والانتقال إليه

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

3- توقيع الصور

ما هو Attestor؟

المصادِق

  • يكون هذا الشخص أو الإجراء مسؤولاً عن رابط واحد في سلسلة الثقة الخاصة بالنظام.
  • ويحتفظون بمفتاح تشفير ويوقّعون على الصورة إذا اجتازت عملية الموافقة.
  • في حين يحدّد "صانع السياسة" السياسة بطريقة مجرّدة وعالية المستوى، يكون "المصدّق" مسؤولاً عن فرض جانب معيّن من السياسة بشكل ملموس.
  • قد يكون شخصًا حقيقيًا، مثل مختبِر ضمان الجودة أو مدير، أو قد يكون برنامج تتبُّع في نظام دمج متواصل.
  • يعتمد أمان النظام على مدى موثوقية هذه الجهات، لذا من المهم الحفاظ على أمان مفاتيحها الخاصة.

يمكن أن يمثّل كل دور من هذه الأدوار شخصًا واحدًا أو فريقًا من الأشخاص في مؤسستك. في بيئة الإنتاج، من المحتمل أن تتم إدارة هذه الأدوار من خلال مشاريع منفصلة على Google Cloud Platform (GCP)، وسيتمّ مشاركة إذن الوصول إلى الموارد بينها بشكل محدود باستخدام Cloud IAM.

a37eb2ed54b9c2eb.png

يتم تنفيذ أدوات التصديق في Binary Authorization استنادًا إلى Cloud Container Analysis API، لذا من المهم توضيح طريقة عملها قبل المتابعة. تم تصميم Container Analysis API للسماح لك بربط البيانات الوصفية بصور حاويات معيّنة.

على سبيل المثال، يمكن إنشاء ملاحظة لتتبُّع ثغرة Heartbleed الأمنية. بعد ذلك، ينشئ مورّدو الأمان أدوات فحص لاختبار صور الحاويات بحثًا عن الثغرة الأمنية، وينشئون "حدثًا" مرتبطًا بكل حاوية تم اختراقها.

208aa5ebc53ff2b3.png

بالإضافة إلى تتبُّع الثغرات الأمنية، تم تصميم Container Analysis لتكون واجهة برمجة تطبيقات عامة للبيانات الوصفية. تستفيد خدمة "الترخيص الثنائي" من "تحليل الحاويات" لربط التواقيع بصور الحاويات التي يتم التحقّق منها. يتم استخدام "ملاحظة تحليل الحاوية" لتمثيل جهة تصديق واحدة، ويتم إنشاء "الموافقات" وربطها بكل حاوية وافقت عليها جهة التصديق.

تستخدم واجهة برمجة التطبيقات Binary Authorization API مفهومَي "المصدّقين" و"شهادات التصديق"، ولكن يتم تنفيذ هذين المفهومَين باستخدام "الملاحظات" و"المستندات" المقابلة في Container Analysis API.

63a701bd0057ea17.png

إنشاء ملاحظة Attestor

ملاحظة Attestor هي ببساطة جزء صغير من البيانات يعمل كتسمية لنوع التوقيع الذي يتم تطبيقه. على سبيل المثال، قد تشير إحدى الملاحظات إلى فحص الثغرات الأمنية، بينما يمكن استخدام ملاحظة أخرى للموافقة على ضمان الجودة. سيتم الرجوع إلى الملاحظة أثناء عملية التوقيع.

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

تم الآن حفظ ملاحظتك ضمن Container Analysis 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 ينشئ built-by-cloud-build المصدّق تلقائيًا في مشروعك عند تنفيذ إصدار ينشئ صورًا. وبالتالي، يعرض الأمر أعلاه جهتَي تصديق، هما vulnz-attestor وbuilt-by-cloud-build. بعد إنشاء الصور بنجاح، يوقّع عليها Cloud Build تلقائيًا وينشئ شهادات تصديق لها.

إضافة دور IAM

سيحتاج حساب خدمة 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

1e3af7c177f7a311.png

قبل أن تتمكّن من استخدام هذا المصدّق، يجب أن تنشئ الجهة المصدّقة زوج مفاتيح تشفير يمكن استخدامه لتوقيع صور الحاويات. يمكن إجراء ذلك من خلال Google Cloud Key Management Service (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 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 التي أنشأتها سابقًا لتوقيع صورة الحاوية التي كنت تعمل عليها.

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}

4. سياسات التحكّم في القبول

Binary Authorization هي ميزة في GKE وCloud Run تتيح التحقّق من صحة القواعد قبل السماح بتشغيل صورة حاوية. يتم تنفيذ عملية التحقّق عند أي طلب لتشغيل صورة، سواء كان ذلك من مسار CI/CD موثوق به أو من مستخدم يحاول نشر صورة يدويًا. تتيح لك هذه الإمكانية تأمين بيئات وقت التشغيل بفعالية أكبر من عمليات التحقّق في مسار CI/CD وحدها.

لفهم هذه الإمكانية، عليك تعديل سياسة GKE التلقائية لفرض قاعدة ترخيص صارمة.

إنشاء مجموعة GKE

أنشئ مجموعة GKE مع تفعيل خدمة Binary Authorization:

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

ستظهر لك النتيجة التالية

161db370d99ffb13.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 إلى أنّ هذه السياسة توسّع السياسة العامة التي تحدّدها Google. يتيح ذلك تشغيل جميع حاويات GKE الرسمية تلقائيًا. بالإضافة إلى ذلك، تحدّد السياسة defaultAdmissionRule التي تنص على أنّه سيتم رفض جميع وحدات Pod الأخرى. يتضمّن قاعدة القبول سطر enforcementMode، والذي ينص على أنّه يجب منع تشغيل جميع وحدات pod التي لا تتوافق مع هذه القاعدة على المجموعة.

للحصول على تعليمات حول كيفية إنشاء سياسات أكثر تعقيدًا، اطّلِع على مستندات Binary Authorization.

657752497e59378c.png

  1. افتح Terminal وطبِّق السياسة الجديدة وانتظر بضع ثوانٍ حتى يتم نشر التغيير.
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

5- توقيع الصور الممسوحة ضوئيًا

لقد فعّلت ميزة "توقيع الصورة" واستخدمت خدمة 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

منح إذن الوصول إلى حساب خدمة 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"

إعداد خطوة 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.

  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

مراجعة الإصدار في "سجلّ Cloud Build"

افتح Cloud Console وانتقِل إلى صفحة "سجلّ Cloud Build" وراجِع أحدث إصدار وتنفيذ خطوات الإصدار بنجاح.

6. منح الإذن باستخدام الصور الموقّعة

في هذا القسم، ستعدّل GKE لاستخدام Binary Authorization من أجل التحقّق من أنّ الصورة تتضمّن توقيعًا من خدمة "فحص الثغرات الأمنية" قبل السماح بتشغيل الصورة.

d5c41bb89e22fd61.png

تعديل سياسة 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

من المفترض أن يكون لديك الآن ملف جديد على القرص باسم updated_policy.yaml. الآن، بدلاً من أن ترفض القاعدة التلقائية جميع الصور، فإنّها تتحقّق أولاً من خدمة التصديق بحثًا عن عمليات التحقّق.

822240fc0b02408e.png

حمِّل السياسة الجديدة إلى خدمة "تفويض الثنائيات":

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

استخدام الملخّص في إعدادات 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

راجِع حِمل العمل في وحدة التحكّم ودوِّن ملاحظة بشأن نشر الصورة بنجاح.

7. حظر الصور غير الموقَّعة

إنشاء صورة

في هذه الخطوة، ستستخدم Docker المحلي لإنشاء الصورة في ذاكرة التخزين المؤقت المحلية.

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

استخدام الملخّص في إعدادات 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

8. تهانينا!

تهانينا، لقد أكملت درس البرمجة.

المواضيع التي تناولناها:

  • توقيع الصور
  • سياسات التحكّم في القبول
  • توقيع الصور الممسوحة ضوئيًا
  • منح الإذن باستخدام الصور الموقّعة
  • حظر الصور غير الموقَّعة

الخطوة التالية:

تَنظيم

لتجنُّب تحمّل رسوم في حسابك على Google Cloud مقابل الموارد المستخدَمة في هذا البرنامج التعليمي، احذف المشروع الذي يحتوي على الموارد أو احتفظ بالمشروع واحذف الموارد الفردية.

حذف المشروع

أسهل طريقة لإيقاف الفوترة هي حذف المشروع الذي أنشأته لتنفيذ البرنامج التعليمي.

تاريخ آخر تعديل: 21/3/2023