بناء آمن النشر باستخدام Cloud Build و Artifact Registry وGKE

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. الإعداد والمتطلبات

إعداد بيئة ذاتية

  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 دولار أمريكي.

بدء محرِّر Cloudshell

تم تصميم هذا الدرس التطبيقي واختباره للاستخدام مع Google Cloud Shell Editor. للوصول إلى المحرر،

  1. انتقِل إلى مشروع Google على https://console.cloud.google.com.
  2. في أعلى يسار الشاشة، انقر على رمز محرِّر Cloud Shell

8560cc8d45e8c112.png

  1. سيتم فتح جزء جديد في أسفل النافذة.

إعداد البيئة

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

  1. فتح Artifact Registry في Cloud Console
  2. انقر على Artifact-scanning-repo لعرض المحتوى
  3. انقر على تفاصيل الصورة.
  4. انقر على أحدث ملخّص لصورتك.
  5. بعد انتهاء الفحص، انقر على علامة تبويب الثغرات الأمنية في الصورة.

من علامة تبويب الثغرات الأمنية، سترى نتائج الفحص التلقائي للصورة التي أنشأتها للتو.

361be7b3bf293fca.png

يتم تفعيل الفحص الآلي تلقائيًا. يمكنك استكشاف إعدادات 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

  1. فتح Artifact Registry في Cloud Console
  2. انقر على Artifact-scanning-repo لعرض المحتوى
  3. انقر على تفاصيل الصورة.
  4. انقر على أحدث ملخّص لصورتك.
  5. انقر على علامة تبويب الثغرات الأمنية في الصورة

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 الذي أنشأته سابقًا.

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

السماح بجميع السياسات

تحقَّق أولاً من حالة السياسة التلقائية ومن قدرتك على نشر أي صورة

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

9. حظر الثغرات الأمنية في GKE

في هذا القسم، ستدمج ما تعلمته حتى الآن من خلال تنفيذ مسار CI/CD مع Cloud Build الذي يفحص الصور، ثم يتحقّق من الثغرات الأمنية قبل توقيع الصورة ومحاولة نشرها. سيستخدم 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

تطبيق السياسة

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 للسماح فقط بالصور الموقَّعة التي تمت الموافقة عليها

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

تَنظيم

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

حذف المشروع

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