বাইনারি প্রমাণের সাথে গেটিং স্থাপনা

১. ভূমিকা

বাইনারি অথরাইজেশন হলো একটি ডেপ্লয়-টাইম নিরাপত্তা নিয়ন্ত্রণ ব্যবস্থা যা নিশ্চিত করে যে শুধুমাত্র বিশ্বস্ত কন্টেইনার ইমেজগুলোই গুগল কুবারনেটিস ইঞ্জিন (GKE) বা ক্লাউড রান-এ ডেপ্লয় করা হয়। বাইনারি অথরাইজেশনের মাধ্যমে, আপনি ডেভেলপমেন্ট প্রক্রিয়ার সময় বিশ্বস্ত কর্তৃপক্ষের দ্বারা ইমেজ স্বাক্ষরিত হওয়ার শর্ত আরোপ করতে পারেন এবং তারপর ডেপ্লয় করার সময় সিগনেচার ভ্যালিডেশন প্রয়োগ করতে পারেন। ভ্যালিডেশন প্রয়োগ করার মাধ্যমে, আপনি আপনার কন্টেইনার এনভায়রনমেন্টের উপর আরও কঠোর নিয়ন্ত্রণ অর্জন করতে পারেন, কারণ এটি নিশ্চিত করে যে শুধুমাত্র যাচাইকৃত ইমেজগুলোই বিল্ড-এবং-রিলিজ প্রক্রিয়ায় অন্তর্ভুক্ত হচ্ছে।

নিম্নলিখিত ডায়াগ্রামটি একটি বাইনারি অথরাইজেশন/ক্লাউড বিল্ড সেটআপের উপাদানগুলো দেখায়:

ক্লাউড বিল্ড বাইনারি অনুমোদন প্রত্যয়ন পাইপলাইন। চিত্র ১. ক্লাউড বিল্ড পাইপলাইন যা একটি বাইনারি অনুমোদন প্রত্যয়ন তৈরি করে।

In this pipeline:

  1. কন্টেইনার ইমেজ তৈরির কোড একটি সোর্স রিপোজিটরিতে, যেমন ক্লাউড সোর্স রিপোজিটরিতে, পুশ করা হয়।
  2. ক্লাউড বিল্ড নামক একটি কন্টিনিউয়াস ইন্টিগ্রেশন (CI) টুল কন্টেইনারটি তৈরি ও পরীক্ষা করে।
  3. বিল্ডটি কন্টেইনার ইমেজটিকে কন্টেইনার রেজিস্ট্রি বা আপনার বিল্ড করা ইমেজগুলো সংরক্ষণকারী অন্য কোনো রেজিস্ট্রি-তে পুশ করে।
  4. ক্লাউড কী ম্যানেজমেন্ট সার্ভিস , যা ক্রিপ্টোগ্রাফিক কী পেয়ারের জন্য কী ম্যানেজমেন্ট প্রদান করে, কন্টেইনার ইমেজটিতে স্বাক্ষর করে। এরপর প্রাপ্ত স্বাক্ষরটি একটি নতুন তৈরি অ্যাটেস্টেশনে সংরক্ষণ করা হয়।
  5. ডিপ্লয় করার সময়, অ্যাটেস্টর কী পেয়ার থেকে পাবলিক কী ব্যবহার করে অ্যাটেস্টেশনটি যাচাই করেন। কন্টেইনার ইমেজ ডিপ্লয় করার জন্য স্বাক্ষরিত অ্যাটেস্টেশন আবশ্যক করার মাধ্যমে বাইনারি অথরাইজেশন এই নীতিটি প্রয়োগ করে।

এই ল্যাবে আপনারা ডেপ্লয় করা আর্টিফ্যাক্ট সুরক্ষিত করার সরঞ্জাম ও কৌশল নিয়ে আলোচনা করবেন। এই ল্যাবটি এমন আর্টিফ্যাক্ট (কন্টেইনার)-এর উপর আলোকপাত করে, যা তৈরি হওয়ার পর কোনো নির্দিষ্ট পরিবেশে ডেপ্লয় করা হয়নি।

আপনি যা শিখবেন

  • Image Signing
  • Admission Control Policies
  • Signing Scanned Images
  • Authorizing Signed Images
  • Blocked unsigned Images

২. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিতে পরিবেশ সেটআপ

  1. Google Cloud Console- এ সাইন-ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

b35bf95b8bf3d5d8.pnga99b7ace416376c4.pngbd84a6d3004737c5.png

  • প্রজেক্টের নামটি হলো এই প্রজেক্টের অংশগ্রহণকারীদের প্রদর্শিত নাম। এটি একটি ক্যারেক্টার স্ট্রিং যা গুগল এপিআই ব্যবহার করে না। আপনি যেকোনো সময় এটি আপডেট করতে পারেন।
  • প্রজেক্ট আইডি সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে অনন্য এবং অপরিবর্তনীয় (একবার সেট করার পর এটি পরিবর্তন করা যায় না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত এটি কী তা নিয়ে আপনার মাথা ঘামানোর প্রয়োজন হয় না। বেশিরভাগ কোডল্যাবে, আপনাকে প্রজেক্ট আইডি উল্লেখ করতে হবে (এটি সাধারণত PROJECT_ID হিসাবে চিহ্নিত করা হয়)। তৈরি করা আইডিটি আপনার পছন্দ না হলে, আপনি এলোমেলোভাবে আরেকটি তৈরি করতে পারেন। বিকল্পভাবে, আপনি নিজের আইডি দিয়ে চেষ্টা করে দেখতে পারেন যে সেটি উপলব্ধ আছে কিনা। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রজেক্টের পুরো সময়কাল জুড়ে এটি অপরিবর্তিত থাকবে।
  • আপনার অবগতির জন্য জানাচ্ছি যে, তৃতীয় একটি ভ্যালু রয়েছে, যা হলো প্রজেক্ট নাম্বার এবং কিছু এপিআই এটি ব্যবহার করে। ডকুমেন্টেশনে এই তিনটি ভ্যালু সম্পর্কে আরও বিস্তারিত জানুন।
  1. এরপর, ক্লাউড রিসোর্স/এপিআই ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে। এই কোডল্যাবটি সম্পন্ন করতে খুব বেশি খরচ হওয়ার কথা নয়, এমনকি আদৌ কোনো খরচ নাও হতে পারে। এই টিউটোরিয়ালের পর যাতে কোনো বিলিং না হয়, সেজন্য রিসোর্সগুলো বন্ধ করতে আপনি আপনার তৈরি করা রিসোর্সগুলো অথবা পুরো প্রজেক্টটিই ডিলিট করে দিতে পারেন। গুগল ক্লাউডের নতুন ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।

পরিবেশ সেটআপ

ক্লাউড শেলে, আপনার প্রজেক্টের জন্য প্রজেক্ট আইডি এবং প্রজেক্ট নম্বর সেট করুন। এগুলোকে PROJECT_ID এবং PROJECT_ID ভেরিয়েবল হিসেবে সংরক্ষণ করুন।

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')

Enable services

সকল প্রয়োজনীয় পরিষেবা সক্রিয় করুন:

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 

Create Artifact Registry Repository

এই ল্যাবে আপনি আপনার ইমেজগুলো সংরক্ষণ ও স্ক্যান করার জন্য আর্টিফ্যাক্ট রেজিস্ট্রি ব্যবহার করবেন। নিম্নলিখিত কমান্ডটি ব্যবহার করে রিপোজিটরিটি তৈরি করুন।

gcloud artifacts repositories create artifact-scanning-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository"

আর্টিফ্যাক্ট রেজিস্ট্রি অ্যাক্সেস করার সময় আপনার gcloud ক্রেডেনশিয়াল ব্যবহার করার জন্য ডকার কনফিগার করুন।

gcloud auth configure-docker us-central1-docker.pkg.dev

Create and change into a work directory

mkdir vuln-scan && cd vuln-scan

Define a sample image

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

Build and Push the image to AR

ক্লাউড বিল্ড ব্যবহার করে আপনার কন্টেইনারটি বিল্ড করুন এবং স্বয়ংক্রিয়ভাবে আর্টিফ্যাক্ট রেজিস্ট্রি-তে পুশ করুন।

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

3. Image Signing

What is an Attestor

Attestor

  • এই ব্যক্তি বা প্রক্রিয়াটি সিস্টেমের আস্থার শৃঙ্খলের একটি সংযোগের জন্য দায়ী।
  • তাদের কাছে একটি ক্রিপ্টোগ্রাফিক কী থাকে এবং ছবিটি তাদের অনুমোদন প্রক্রিয়ায় উত্তীর্ণ হলে তারা সেটিতে স্বাক্ষর করেন।
  • নীতি প্রণেতা উচ্চ-স্তরের ও বিমূর্তভাবে নীতি নির্ধারণ করলেও, প্রত্যয়নকারী সেই নীতির কোনো একটি দিককে বাস্তবিকভাবে প্রয়োগ করার জন্য দায়ী থাকেন।
  • তিনি একজন প্রকৃত ব্যক্তি হতে পারেন, যেমন একজন QA টেস্টার বা ম্যানেজার, অথবা CI সিস্টেমের কোনো বটও হতে পারেন।
  • সিস্টেমের নিরাপত্তা তাদের বিশ্বস্ততার উপর নির্ভর করে, তাই তাদের প্রাইভেট কীগুলো সুরক্ষিত রাখা গুরুত্বপূর্ণ।

এই ভূমিকাগুলোর প্রতিটি আপনার প্রতিষ্ঠানের একজন ব্যক্তি বা একটি দলকে প্রতিনিধিত্ব করতে পারে। একটি প্রোডাকশন পরিবেশে, এই ভূমিকাগুলো সম্ভবত পৃথক গুগল ক্লাউড প্ল্যাটফর্ম (GCP) প্রজেক্ট দ্বারা পরিচালিত হবে এবং ক্লাউড আইএএম (Cloud IAM) ব্যবহার করে সীমিত আকারে তাদের মধ্যে রিসোর্সের অ্যাক্সেস শেয়ার করা হবে।

a37eb2ed54b9c2eb.png

বাইনারি অথরাইজেশনে অ্যাটেস্টরগুলো ক্লাউড কন্টেইনার অ্যানালাইসিস এপিআই-এর উপর ভিত্তি করে বাস্তবায়িত হয়, তাই সামনে এগোনোর আগে এটি কীভাবে কাজ করে তা বর্ণনা করা জরুরি। কন্টেইনার অ্যানালাইসিস এপিআই-টি নির্দিষ্ট কন্টেইনার ইমেজের সাথে মেটাডেটা যুক্ত করার সুযোগ দেওয়ার জন্য ডিজাইন করা হয়েছিল।

উদাহরণস্বরূপ, হার্টব্লিড দুর্বলতা ট্র্যাক করার জন্য একটি নোট তৈরি করা যেতে পারে। এরপর নিরাপত্তা বিক্রেতারা দুর্বলতাটির জন্য কন্টেইনার ইমেজ পরীক্ষা করতে স্ক্যানার তৈরি করবে এবং প্রতিটি ক্ষতিগ্রস্ত কন্টেইনারের সাথে যুক্ত একটি অকারেন্স তৈরি করবে।

208aa5ebc53ff2b3.png

দুর্বলতা ট্র্যাক করার পাশাপাশি, কন্টেইনার অ্যানালাইসিসকে একটি জেনেরিক মেটাডেটা এপিআই হিসেবে ডিজাইন করা হয়েছিল। বাইনারি অথরাইজেশন, তাদের যাচাই করা কন্টেইনার ইমেজগুলোর সাথে সিগনেচার যুক্ত করতে কন্টেইনার অ্যানালাইসিস ব্যবহার করে। একটি কন্টেইনার অ্যানালাইসিস নোট একজন একক অ্যাটেস্টরকে প্রতিনিধিত্ব করতে ব্যবহৃত হয়, এবং সেই অ্যাটেস্টরের দ্বারা অনুমোদিত প্রতিটি কন্টেইনারের সাথে অকারেন্স তৈরি ও যুক্ত করা হয়।

বাইনারি অথরাইজেশন এপিআই 'অ্যাটেস্টর' এবং 'অ্যাটেস্টেশন'-এর ধারণাগুলো ব্যবহার করে, কিন্তু কন্টেইনার অ্যানালাইসিস এপিআই-তে এগুলো সংশ্লিষ্ট নোট এবং অকারেন্স ব্যবহার করে বাস্তবায়িত হয়।

63a701bd0057ea17.png

Create an Attestor Note

অ্যাটেস্টর নোট হলো সামান্য কিছু ডেটা, যা ব্যবহৃত স্বাক্ষরের ধরন নির্দেশ করার জন্য একটি লেবেল হিসেবে কাজ করে। উদাহরণস্বরূপ, একটি নোট ভালনারেবিলিটি স্ক্যান নির্দেশ করতে পারে, আবার অন্যটি কিউএ (QA) সাইন অফের জন্য ব্যবহৃত হতে পারে। স্বাক্ষর প্রক্রিয়া চলাকালীন এই নোটটি উল্লেখ করা হবে।

919f997db0ffb881.png

একটি নোট তৈরি করুন

cat > ./vulnz_note.json << EOM
{
  "attestation": {
    "hint": {
      "human_readable_name": "Container Vulnerabilities attestation authority"
    }
  }
}
EOM

Store the note

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

Verify the note

curl -vvv  \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"

আপনার নোটটি এখন কন্টেইনার অ্যানালাইসিস এপিআই-এর মধ্যে সংরক্ষিত হয়েছে।

Creating an Attestor

প্রকৃত ইমেজ স্বাক্ষর প্রক্রিয়াটি সম্পন্ন করার জন্য অ্যাটেস্টর ব্যবহার করা হয় এবং এটি পরবর্তী যাচাইয়ের জন্য ইমেজের সাথে নোটটির একটি অংশ সংযুক্ত করে। আপনার অ্যাটেস্টর ব্যবহার করার জন্য, আপনাকে অবশ্যই বাইনারি অথরাইজেশন-এর সাথে নোটটি রেজিস্টার করতে হবে:

ed05d438c79b654d.png

Create Attestor

ATTESTOR_ID=vulnz-attestor

gcloud container binauthz attestors create $ATTESTOR_ID \
    --attestation-authority-note=$NOTE_ID \
    --attestation-authority-note-project=${PROJECT_ID}

Verify Attestor

gcloud container binauthz attestors list

লক্ষ্য করুন, শেষ লাইনে NUM_PUBLIC_KEYS: 0 নির্দেশ করা হয়েছে, যা আপনি পরবর্তী ধাপে প্রদান করবেন।

আরও মনে রাখবেন যে, যখন আপনি ইমেজ তৈরি করে এমন কোনো বিল্ড চালান, তখন ক্লাউড বিল্ড স্বয়ংক্রিয়ভাবে আপনার প্রোজেক্টে built-by-cloud-build অ্যাটেস্টরটি তৈরি করে। তাই উপরের কমান্ডটি ' vulnz-attestor এবং built-by-cloud-build দুটি অ্যাটেস্টর রিটার্ন করে। ইমেজগুলো সফলভাবে বিল্ড হওয়ার পর, ক্লাউড বিল্ড স্বয়ংক্রিয়ভাবে সেগুলোতে স্বাক্ষর করে এবং অ্যাটেস্টেশন তৈরি করে।

Adding IAM Role

অ্যাটেস্টেশন নোটগুলি দেখার জন্য বাইনারি অথরাইজেশন সার্ভিস অ্যাকাউন্টের অধিকার প্রয়োজন হবে। নিম্নলিখিত API কলের মাধ্যমে অ্যাক্সেস প্রদান করুন।

PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}"  --format="value(projectNumber)")

BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"


cat > ./iam_request.json << EOM
{
  'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
  'policy': {
    'bindings': [
      {
        'role': 'roles/containeranalysis.notes.occurrences.viewer',
        'members': [
          'serviceAccount:${BINAUTHZ_SA_EMAIL}'
        ]
      }
    ]
  }
}
EOM

Use the file to create the IAM Policy

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"

Adding a KMS Key

1e3af7c177f7a311.png

এই অ্যাটেস্টরটি ব্যবহার করার আগে, আপনার কর্তৃপক্ষকে একটি ক্রিপ্টোগ্রাফিক কী পেয়ার তৈরি করতে হবে যা কন্টেইনার ইমেজ সাইন করার জন্য ব্যবহার করা যায়। এটি গুগল ক্লাউড কী ম্যানেজমেন্ট সার্ভিস (KMS)- এর মাধ্যমে করা যেতে পারে।

প্রথমে নতুন কী-টি বর্ণনা করার জন্য কিছু এনভায়রনমেন্ট ভেরিয়েবল যোগ করুন।

KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1

Create a keyring to hold a set of keys

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 পৃষ্ঠায় আপনার কী-টি দেখতে পাবেন।

এখন, 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

Creating a Signed Attestation

এই পর্যায়ে আপনার কাছে ইমেজ সাইন করার জন্য প্রয়োজনীয় ফিচারগুলো কনফিগার করা আছে। আপনি পূর্বে তৈরি করা অ্যাটেস্টরটি ব্যবহার করে আপনার ব্যবহৃত কন্টেইনার ইমেজটি সাইন করুন।

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. Admission Control Policies

বাইনারি অথরাইজেশন হলো GKE এবং ক্লাউড রান-এর একটি ফিচার, যা কোনো কন্টেইনার ইমেজ রান করার অনুমতি দেওয়ার আগে নিয়মগুলো যাচাই করার সুবিধা দেয়। এই যাচাইকরণ প্রক্রিয়াটি ইমেজ রান করার যেকোনো অনুরোধের ক্ষেত্রেই কার্যকর হয়, তা কোনো বিশ্বস্ত CI/CD পাইপলাইন থেকে আসুক বা কোনো ব্যবহারকারী নিজে থেকে ইমেজ ডেপ্লয় করার চেষ্টা করুক। এই সক্ষমতা আপনাকে শুধুমাত্র CI/CD পাইপলাইন চেকের চেয়েও আরও কার্যকরভাবে আপনার রানটাইম এনভায়রনমেন্ট সুরক্ষিত করতে সাহায্য করে।

এই সক্ষমতাটি বুঝতে হলে আপনাকে একটি কঠোর অনুমোদন নিয়ম প্রয়োগ করার জন্য ডিফল্ট GKE পলিসি পরিবর্তন করতে হবে।

Create the GKE Cluster

বাইনারি অনুমোদন সক্রিয় করে GKE ক্লাস্টার তৈরি করুন:

gcloud beta container clusters create binauthz \
    --zone us-central1-a  \
    --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE

Allow Cloud Build to deploy to this cluster:

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

Allow All Policy

প্রথমে ডিফল্ট পলিসি অবস্থা এবং যেকোনো ইমেজ ডেপ্লয় করার আপনার সক্ষমতা যাচাই করুন।

  1. Review existing policy
gcloud container binauthz policy export
  1. লক্ষ্য করুন যে প্রয়োগ নীতিটি ALWAYS_ALLOW তে সেট করা আছে।

evaluationMode: ALWAYS_ALLOW

  1. Deploy Sample to verify you can deploy anything
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. Verify the deploy worked
kubectl get pods

You will see the following output

161db370d99ffb13.png

  1. Delete deployment
kubectl delete pod hello-server

Deny All Policy

Now update the policy to disallow all images.

  1. Export the current policy to an editable file
gcloud container binauthz policy export  > policy.yaml
  1. Change the policy

টেক্সট এডিটরে, evaluationMode-টি ALWAYS_ALLOW থেকে ALWAYS_DENY- তে পরিবর্তন করুন।

edit policy.yaml

The policy YAML file should appear as follows:

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_DENY
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy

এই পলিসিটি তুলনামূলকভাবে সহজ। `globalPolicyEvaluationMode` লাইনটি ঘোষণা করে যে এই পলিসিটি গুগল দ্বারা সংজ্ঞায়িত গ্লোবাল পলিসিকে সম্প্রসারিত করে। এটি সমস্ত অফিসিয়াল GKE কন্টেইনারকে ডিফল্টরূপে চালানোর অনুমতি দেয়। এছাড়াও, পলিসিটি একটি `defaultAdmissionRule` ঘোষণা করে, যা বলে যে অন্য সমস্ত পডকে প্রত্যাখ্যান করা হবে । এই অ্যাডমিশন রুলে একটি `enforcementMode` লাইন অন্তর্ভুক্ত রয়েছে, যা বলে যে এই নিয়ম মেনে চলে না এমন সমস্ত পডকে ক্লাস্টারে চালানো থেকে ব্লক করা উচিত।

আরও জটিল পলিসি তৈরির নির্দেশাবলীর জন্য বাইনারি অথরাইজেশন ডকুমেন্টেশনটি দেখুন।

657752497e59378c.png

  1. টার্মিনাল খুলুন এবং নতুন পলিসিটি প্রয়োগ করুন, এবং পরিবর্তনটি কার্যকর হওয়ার জন্য কয়েক সেকেন্ড অপেক্ষা করুন।
gcloud container binauthz policy import policy.yaml
  1. Attempt sample workload deployment
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. Deployment fails with the following message
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

Revert the policy to allow all

পরবর্তী বিভাগে যাওয়ার আগে নীতিগত পরিবর্তনগুলো পূর্বাবস্থায় ফিরিয়ে আনতে ভুলবেন না।

  1. Change the policy

টেক্সট এডিটরে, evaluationMode-টি ALWAYS_DENY থেকে ALWAYS_ALLOW- তে পরিবর্তন করুন।

edit policy.yaml

The policy YAML file should appear as follows:

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_ALLOW
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
  1. Apply the reverted policy
gcloud container binauthz policy import policy.yaml

5. Signing Scanned Images

আপনি ইমেজ সাইনিং সক্ষম করেছেন এবং আপনার নমুনা ইমেজটি সাইন করার জন্য অ্যাটেস্টর ম্যানুয়ালি ব্যবহার করেছেন। বাস্তবে, আপনি CI/CD পাইপলাইনের মতো স্বয়ংক্রিয় প্রক্রিয়া চলাকালীন অ্যাটেস্টেশন প্রয়োগ করতে চাইবেন।

এই অংশে আপনি ইমেজ স্বয়ংক্রিয়ভাবে অ্যাটেস্ট করার জন্য ক্লাউড বিল্ড কনফিগার করবেন।

ভূমিকা

ক্লাউড বিল্ড সার্ভিস অ্যাকাউন্টে বাইনারি অথরাইজেশন অ্যাটেস্টর ভিউয়ার রোল যোগ করুন:

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

ক্লাউড বিল্ড সার্ভিস অ্যাকাউন্টে ক্লাউড কেএমএস ক্রিপ্টো-কী সাইনার/ভেরিফায়ার রোল যোগ করুন (কেএমএস-ভিত্তিক সাইনিং):

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

ক্লাউড বিল্ড সার্ভিস অ্যাকাউন্টে কন্টেইনার অ্যানালাইসিস নোটস অ্যাটাচার রোল যোগ করুন:

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

Provide access for Cloud Build Service Account

অন-ডিমান্ড স্ক্যানিং এপিআই অ্যাক্সেস করার জন্য ক্লাউড বিল্ডের অধিকার প্রয়োজন হবে। নিম্নলিখিত কমান্ডগুলো ব্যবহার করে অ্যাক্সেস প্রদান করুন।

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"

Prepare the Custom Build Cloud Build Step

অ্যাটেস্টেশন প্রক্রিয়া সহজ করার জন্য আপনি ক্লাউড বিল্ড-এ একটি কাস্টম বিল্ড স্টেপ ব্যবহার করবেন। গুগল এই কাস্টম বিল্ড স্টেপটি সরবরাহ করে, যাতে প্রক্রিয়াটিকে সুবিন্যস্ত করার জন্য সহায়ক ফাংশন রয়েছে। ব্যবহারের আগে, কাস্টম বিল্ড স্টেপের কোডটিকে একটি কন্টেইনারে বিল্ড করে ক্লাউড বিল্ড-এ পুশ করতে হবে। এটি করার জন্য, নিম্নলিখিত কমান্ডগুলো চালান:

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

Add a signing step to your cloudbuild.yaml

এই ধাপে আপনি আপনার ক্লাউড বিল্ড পাইপলাইনে অ্যাটেস্টেশন ধাপটি যোগ করবেন।

  1. Review the signing step below.

Review only. Do Not Copy

#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

Run the Build

gcloud builds submit

Review the build in Cloud Build History

ক্লাউড কনসোলের ক্লাউড বিল্ড হিস্ট্রি পৃষ্ঠাটি খুলুন এবং সর্বশেষ বিল্ড ও বিল্ড ধাপগুলোর সফল সম্পাদন পর্যালোচনা করুন।

6. Authorizing Signed Images

এই অংশে আপনি GKE আপডেট করবেন, যাতে এটি ইমেজটি চালানোর অনুমতি দেওয়ার আগে, ভালনারেবিলিটি স্ক্যানিং থেকে প্রাপ্ত সিগনেচারটি যাচাই করার জন্য বাইনারি অথরাইজেশন ব্যবহার করে।

d5c41bb89e22fd61.png

Update GKE Policy to Require Attestation

আপনার GKE BinAuth Policy-তে clusterAdmissionRules যোগ করার মাধ্যমে প্রয়োজনীয় ইমেজগুলো আপনার Attestor দ্বারা স্বাক্ষরিত হয়।

বর্তমানে, আপনার ক্লাস্টারটি এমন একটি পলিসি চালাচ্ছে যার একটিই নিয়ম: অফিসিয়াল রিপোজিটরি থেকে আসা কন্টেইনারগুলোকে অনুমতি দেওয়া এবং বাকি সবগুলোকে প্রত্যাখ্যান করা।

নিচের কমান্ডটি ব্যবহার করে আপডেট করা কনফিগারেশন দিয়ে পলিসিটি ওভাররাইট করুন।

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

Upload the new policy to Binary Authorization:

gcloud beta container binauthz policy import binauth_policy.yaml

Deploy a signed image

Get the image digest for the good image

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

Use the digest in the Kubernetes configuration

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

Deploy the app to GKE

kubectl apply -f deploy.yaml

কনসোলে ওয়ার্কলোড পর্যালোচনা করুন এবং ইমেজটির সফল ডেপ্লয়মেন্ট লক্ষ্য করুন।

7. Blocked unsigned Images

Build an Image

এই ধাপে আপনি আপনার লোকাল ক্যাশে ইমেজটি বিল্ড করার জন্য লোকাল ডকার ব্যবহার করবেন।

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

Push the unsigned image to the repo

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

Get the image digest for the bad image

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

Use the digest in the Kubernetes configuration

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

Attempt to deploy the app to GKE

kubectl apply -f deploy.yaml

কনসোলে ওয়ার্কলোড পর্যালোচনা করুন এবং ডিপ্লয়মেন্ট প্রত্যাখ্যাত হওয়ার ত্রুটিটি নোট করুন:

No attestations found that were valid and signed by a key trusted by the attestor

৮. অভিনন্দন!

অভিনন্দন, আপনি কোডল্যাবটি সম্পন্ন করেছেন!

What we've covered:

  • Image Signing
  • Admission Control Policies
  • Signing Scanned Images
  • Authorizing Signed Images
  • Blocked unsigned Images

এরপর কী হবে:

পরিষ্কার করা

এই টিউটোরিয়ালে ব্যবহৃত রিসোর্সগুলোর জন্য আপনার গুগল ক্লাউড অ্যাকাউন্টে চার্জ হওয়া এড়াতে, হয় রিসোর্সগুলো যে প্রজেক্টে রয়েছে সেটি ডিলিট করে দিন, অথবা প্রজেক্টটি রেখে দিয়ে আলাদা আলাদা রিসোর্সগুলো ডিলিট করে দিন।

প্রকল্পটি মুছে ফেলা হচ্ছে

বিলিং বন্ধ করার সবচেয়ে সহজ উপায় হলো টিউটোরিয়ালের জন্য তৈরি করা প্রজেক্টটি ডিলিট করে দেওয়া।

Last update: 3/21/23