אבטחת אספקת התוכנה

1. סקירה כללית

בעזרת Artifact Registry אפשר לאחסן סוגים שונים של ארטיפקטים, ליצור כמה מאגרים בפרויקט אחד ולשייך כל מאגר לאזור ספציפי או למספר אזורים. יש כמה מצבי מאגר. לכל מצב יש מטרה שונה. התרשים הבא מציג אחת מהדרכים הרבות שבהן אפשר להשתמש במאגרים במצבים שונים יחד. התרשים מציג תהליך עבודה בשני פרויקטים ב-Google Cloud. בפרויקט פיתוח, מפתחים יוצרים אפליקציה ב-Java. בפרויקט נפרד בסביבת זמן ריצה, build נוסף יוצר קובץ אימג' בקונטיינר עם האפליקציה לפריסה ב-Google Kubernetes Engine.

5af5e4da3ccfdff3.png

בשיעור ה-Lab הזה תלמדו איך לבצע את המשימות הבאות:

  • שימוש במאגרים רגילים לפריסה של חבילות פרטיות
  • שימוש במאגרים מרוחקים כדי לשמור במטמון חבילות מרכזיות של Maven
  • שימוש במאגרים וירטואליים כדי לשלב כמה מאגרי upstream בתצורה אחת

הגדרת סביבה בקצב אישי

  1. נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או משתמשים מחדש בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • שם הפרויקט הוא השם המוצג של המשתתפים בפרויקט. זוהי מחרוזת תווים שלא משמשת את Google APIs. אפשר לעדכן את המיקום הזה בכל שלב.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו אחרי שמגדירים אותו. מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית. בדרך כלל לא משנה מה המחרוזת הזו. ברוב ה-codelabs תצטרכו להפנות למזהה הפרויקט (בדרך כלל הוא מזוהה בתור PROJECT_ID). אם המזהה שנוצר לא מוצא חן בעיניכם, תוכלו ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות שם משלכם ולבדוק אם הוא זמין. לא ניתן לשנות את השם אחרי השלב הזה, והוא יישאר למשך כל תקופת הפרויקט.
  • לידיעתך, יש ערך שלישי, מספר פרויקט, שמשתמשים בו בחלק מממשקי ה-API. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי העזרה.
  1. בשלב הבא, כדי להשתמש במשאבים או ב-API של Cloud, תצטרכו להפעיל את החיוב במסוף Cloud. השלמת הקודלאב הזה לא אמורה לעלות הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים אחרי סיום המדריך, אפשר למחוק את המשאבים שיצרתם או למחוק את הפרויקט כולו. משתמשים חדשים ב-Google Cloud זכאים להשתתף בתוכנית תקופת ניסיון בחינם בסך 300$.

הגדרת Workspace

הגדרת gcloud

ב-Cloud Shell, מגדירים את מזהה הפרויקט ואת מספר הפרויקט. שומרים אותם כמשתנים PROJECT_ID ו-PROJECT_NUMBER.

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

הפעלת ממשקי API

gcloud services enable artifactregistry.googleapis.com

שכפול המאגר

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/container-registry/container-analysis

2. מאגרים רגילים

מאגרים רגילים מספקים דרך לאחסן את החבילות הפרטיות שלכם ולשתף אותן עם האפליקציות האחרות שלכם

יצירת מאגר maven רגיל

כדי ליצור מאגר לארטיפקטים של Java, מריצים את הפקודה הבאה ב-Cloud Shell:

gcloud artifacts repositories create container-dev-java-repo \
    --repository-format=maven \
    --location=us-central1 \
    --description="Java package repository for Container Dev Workshop"

אם מופיעה בקשה לאשר את Cloud Shell, לוחצים על Authorize (אישור).

נכנסים למסוף Google Cloud – Artifact Registry – Repositories (מאגרים) ומאתרים את מאגר Maven החדש שנוצר בשם container-dev-java-repo. אם לוחצים עליו, רואים שהוא ריק כרגע.

gcloud artifacts repositories describe container-dev-java-repo \
    --location=us-central1

התגובה אמורה להיראות כך:

Encryption: Google-managed key
Repository Size: 0.000MB
createTime: '2023-03-21T19:01:45.461589Z'
description: Java package repository for Container Dev Workshop
format: MAVEN
mavenConfig: {}
mode: STANDARD_REPOSITORY
name: projects/qwiklabs-gcp-03-4304110dc461/locations/us-central1/repositories/container-dev-java-repo
updateTime: '2023-03-21T19:01:45.461589Z'

הגדרת Maven ל-Artifact Registry

מריצים את הפקודה הבאה כדי להדפיס את הגדרות המאגר שרוצים להוסיף לפרויקט Java:

gcloud artifacts print-settings mvn \
    --repository=container-dev-java-repo \
    --location=us-central1

הפקודה הקודמת מחזירה קובץ XML שצריך להוסיף לקובץ pom.xml של הפרויקטים.

  • בקטע repositories מצוין לאן Maven יכול להוריד פריטי מידע שנוצרו בתהליך פיתוח (artifacts) מרחוק לשימוש בפרויקט הנוכחי.
  • בקטע distributionManagement מצוין לאיזה מאגר מרוחק הפרויקט יועבר ב-push כשהוא יפורס.
  • בקטע extensions מוסיפים את artifactregistry-maven-wagon שמפעיל את שכבת האימות והתעבורה הנדרשת כדי להתחבר ל-Artifact Registry.
  • הערה: תוספים יכולים להופיע בקובץ pom.xml או בקובץ extensions.xml. במקרים שבהם הפרויקט תלוי בפרויקט הורה, הגישה ליחסי התלות האלה מתבצעת לפני טעינת שאר הרשומות ב-pom.xml. כדי לוודא שההורה יקבל גישה להרחבה, אפשר למקם אותה בקובץ extensions.xml שנטען לפני pom.xml, וכך היא תהיה זמינה ליחסי התלות של ההורה.

מעתיקים את שלושת הקטעים, פותחים את הקובץ pom.xml ב-Cloud Shell Editor ומוסיפים את ההגדרות שהוחזרו לתחתית הקובץ, ממש בתוך תג ה-project הסגור.

טיפ: ב-Cloud Shell, מריצים את הפקודה הבאה בטרמינל כדי לפתוח את העורך בספרייה הנוכחית.

cloudshell workspace .

דוגמה: (שמות הפרויקטים יהיו שונים בכתובות ה-URL)

  ...

  <distributionManagement>
    <snapshotRepository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </snapshotRepository>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </repository>
  </distributionManagement>

  <repositories>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
  </repositories>

  <build>
    <extensions>
      <extension>
        <groupId>com.google.cloud.artifactregistry</groupId>
        <artifactId>artifactregistry-maven-wagon</artifactId>
        <version>2.2.0</version>
      </extension>
    </extensions>
  </build>

</project>

העלאת חבילת Java ל-Artifact Registry

אחרי שמגדירים את Artifact Registry ב-Maven, אפשר להשתמש ב-Artifact Registry כדי לאחסן קובצי jar של Java לשימוש בפרויקטים אחרים בארגון.

מריצים את הפקודה הבאה כדי להעלות את חבילת ה-Java ל-Artifact Registry:

mvn deploy -DskipTests

אם רוצים להריץ את הפקודה הזו שוב, צריך להגדיל את הגרסה בקובץ pom.xml.

בדיקת חבילת Java ב-Artifact Registry

עוברים אל Cloud Console - Artifact Registry - Repositories לוחצים על container-dev-java-repo ובודקים שפריט המידע הבינארי hello-world נמצא שם:

147eac5168648db1.png

3. מאגרים מרוחקים

מאגרים מרוחקים מאפשרים לשמור במטמון חבילות של צד שלישי כדי לשפר את האמינות והאבטחה.

יצירת מאגר מרוחק

הערה: פרטים על אימות והגדרה זמינים במסמכי העזרה של המוצר.

מריצים את הפקודה הבאה ב-Cloud Shell כדי ליצור מאגר מרוחק לארטיפקטים של Maven Central:

gcloud artifacts repositories create maven-central-cache \
    --project=$PROJECT_ID \
    --repository-format=maven \
    --location=us-central1 \
    --description="Remote repository for Maven Central caching" \
    --mode=remote-repository \
    --remote-repo-config-desc="Maven Central" \
    --remote-mvn-repo=MAVEN-CENTRAL

בדיקת המאגר במסוף

עוברים אל Cloud Console - Artifact Registry - Repositories לוחצים על maven-central-cache ומבחינים שהוא נוצר כרגע ריק.

בדיקת המאגר בטרמינל

gcloud artifacts repositories describe maven-central-cache \
    --location=us-central1

שילוב המאגר בפרויקט

מריצים את הפקודה הבאה כדי להדפיס את הגדרות המאגר שרוצים להוסיף לפרויקט Java:

gcloud artifacts print-settings mvn \
    --repository=maven-central-cache \
    --location=us-central1

מוסיפים את הקטע של המאגר לקובץ pom.xml. חשוב לא להעתיק את התג החיצוני <repositories> מהפלט.

משנים את המזהה של המאגר החדש שנוסף ל-'central' כדי לוודא שלכל רשומה במאגר יש מזהה ייחודי.

דוגמה: (שמות הפרויקטים יהיו שונים בכתובות ה-URL)

  ...

  <distributionManagement>
    <snapshotRepository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </snapshotRepository>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </repository>
  </distributionManagement>

  <repositories>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>

    <repository>
      <id>central</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/maven-central-cache</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>


  </repositories>

  <build>
    <extensions>
      <extension>
        <groupId>com.google.cloud.artifactregistry</groupId>
        <artifactId>artifactregistry-maven-wagon</artifactId>
        <version>2.2.0</version>
      </extension>
    </extensions>
  </build>

</project>

מריצים את הפקודות הבאות בטרמינל כדי ליצור קובץ extensions.xml לפרויקט. כדי להשתמש במנגנון של תוספים ליבה, שמבטיח ש-Maven יוכל לפתור יחסי תלות של הורה או פלאגין מ-Artifact Registry.

mkdir .mvn 
cat > .mvn/extensions.xml << EOF
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
  <extension>
    <groupId>com.google.cloud.artifactregistry</groupId>
    <artifactId>artifactregistry-maven-wagon</artifactId>
    <version>2.2.0</version>
  </extension>
</extensions>
EOF

משיכת יחסי התלות מהמאגר המרוחק

מריצים את הפקודה הבאה כדי לקמפל את האפליקציה באמצעות המאגר המרוחק:

rm -rf ~/.m2/repository 
mvn compile

בדיקת החבילות במסוף

עוברים אל Cloud Console - Artifact Registry - Repositories לוחצים על maven-central-cache ובודקים אם פריטי המידע הבינאריים שנוצרים בתהליך הפיתוח (Artifacts) שמאוחסנים במטמון:

9deea93caa5fefd7.png

4. מאגרים וירטואליים

מאגרים וירטואליים משמשים כממשק לגישה לכמה מאגרים באמצעות הגדרה אחת. כך אפשר לפשט את הגדרת הלקוח לצרכני הארטיפקטים שלכם, ולשפר את האבטחה על ידי צמצום התקפות של בלבול ביחסי התלות.

יצירת קובץ מדיניות

cat > ./policy.json << EOF
[
  {
    "id": "private",
    "repository": "projects/${PROJECT_ID}/locations/us-central1/repositories/container-dev-java-repo",
    "priority": 100
  },
  {
    "id": "central",
    "repository": "projects/${PROJECT_ID}/locations/us-central1/repositories/maven-central-cache",
    "priority": 80
  }
]

EOF

יצירת המאגר הווירטואלי

gcloud artifacts repositories create virtual-maven-repo \
    --project=${PROJECT_ID} \
    --repository-format=maven \
    --mode=virtual-repository \
    --location=us-central1 \
    --description="Virtual Maven Repo" \
    --upstream-policy-file=./policy.json

שילוב המאגר בפרויקט

מריצים את הפקודה הבאה כדי להדפיס את הגדרות המאגר שרוצים להוסיף לפרויקט Java:

gcloud artifacts print-settings mvn \
    --repository=virtual-maven-repo \
    --location=us-central1

מחליפים את כל הקטע repositories ב-pom בקטע אחד של מאגרים וירטואליים מהפלט.

דוגמה: (שמות הפרויקטים יהיו שונים בכתובות ה-URL)

  ...


  <distributionManagement>
    <snapshotRepository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </snapshotRepository>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </repository>
  </distributionManagement>

  <repositories>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/virtual-maven-repo</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
  </repositories>

  <build>
    <extensions>
      <extension>
        <groupId>com.google.cloud.artifactregistry</groupId>
        <artifactId>artifactregistry-maven-wagon</artifactId>
        <version>2.2.0</version>
      </extension>
    </extensions>
  </build>

</project>


אחזור יחסי התלות מהמאגר הווירטואלי

מכיוון שהמאגר הווירטואלי הוא דרך מעבר ולא יאחסן חבילות בפועל, כדי להמחיש בבירור את התהליך, תמחקו את המאגר maven-central-cache שיצרתם מקודם ותייצרו אותו מחדש, כדי להתחיל מחדש עם מאגר ריק.

מריצים את הפקודות הבאות כדי ליצור מחדש את מאגר המטמון

gcloud artifacts repositories delete maven-central-cache \
    --project=$PROJECT_ID \
    --location=us-central1 \
    --quiet

gcloud artifacts repositories create maven-central-cache \
    --project=$PROJECT_ID \
    --repository-format=maven \
    --location=us-central1 \
    --description="Remote repository for Maven Central caching" \
    --mode=remote-repository \
    --remote-repo-config-desc="Maven Central" \
    --remote-mvn-repo=MAVEN-CENTRAL

אפשר לעיין במאגר הריק במסוף. עוברים אל מסוף Cloud – Artifact Registry – Repositories

עכשיו אפשר לבדוק את המאגר הווירטואלי על ידי בניית הפרויקט באמצעות הפקודה הבאה:

rm -rf ~/.m2/repository 
mvn compile

בדיקת החבילות במסוף

עוברים אל Cloud Console – Artifact Registry – Repositories לוחצים על maven-central-cache ובודקים שפרטי המידע הבינאריים (artifacts) הוגדרו לצורך משיכה מהמאגר הווירטואלי, אבל בסופו של דבר נשלפו מהמאגר maven-central-cache:

9deea93caa5fefd7.png

5. מעולה!

כל הכבוד, סיימת את הקודלאב!

מה כבר כיסית

  • שימוש במאגרים רגילים לפריסה של חבילות פרטיות
  • שימוש במאגרים מרוחקים כדי לשמור במטמון חבילות מרכזיות של Maven
  • שימוש במאגרים וירטואליים כדי לשלב כמה מאגרים של מקור (upstream) בתצורה אחת

הסרת המשאבים

מריצים את הפקודה הבאה כדי למחוק את הפרויקט:

gcloud projects delete ${PROJECT_ID}

תאריך העדכון האחרון: 22 במרץ 2023