הטמעה לדוגמה של Keyfactor EJBCA

סקירה כללית

במדריך הזה מוסבר איך לשלב את Keyfactor EJBCA Enterprise (שנפרס כמכשיר חיצוני) כרשות אישורים (CA) של צד שלישי עבור Google Distributed Cloud ‏ (GDC) עם בידוד פיזי.

‫Keyfactor EJBCA Enterprise היא פלטפורמה חזקה, ניתנת להרחבה ועומדת בתקן FIPS של רשות אישורים (CA), שמאפשרת לארגונים לנהל תשתית מפתח ציבורי (PKI) בסביבות הטרוגניות.

‫GDC עם air gap כולל שירות מובנה של רשות אישורים לניהול אוטומטי של מפתחות ואישורים בתוך הגבול של הענן המארח. עם זאת, ארגונים שהשתמשו ב-Keyfactor EJBCA כדי ליצור סטנדרטיזציה של תשתית ה-PKI שלהם עבור עומסי עבודה קיימים מחוץ ל-GDC, עשויים להעדיף להשתמש באותה ארכיטקטורה עקבית של CA ובאותן מדיניות ניהול עבור עומסי עבודה שפועלים בסביבות GDC שלהם שמוגנות על ידי air-gap.

במדריך הזה נדגים איך להגדיר את הרשת של GDC, DNS פנימי ו-cert-manager של Kubernetes כדי לבצע אוטומציה של ניהול מחזור החיים של האישורים (ACME) ולתמוך בהנפקת אישורים בכמות גדולה באמצעות דפוס של רשות רישום (RA).

הנחות

לפני שממשיכים במדריך הזה, חשוב לוודא שההנחות הבאות מתקיימות:

  • מערכת Keyfactor EJBCA נפרסת כמכשיר תוכנה או כמכשיר חומרה, ומוגדרת לשימוש בכתובת IP יציבה.
  • נוצרו רשויות אישורים (CA) בסיסיות, משניות וניהוליות במופע EJBCA.
  • הוגדרו פרופילים של ישויות קצה (EE) (למשל, לאישורים של שרתי TLS).
  • האישורים של משתמשי ה-CA האדמיניסטרטיביים הורדו.
  • הפרוטוקולים הנדרשים (כמו ACME) מופעלים במופע EJBCA.
  • במדריך הזה נעשה שימוש באלגוריתמי חתימה של RSA. אתם יכולים לשנות את אלגוריתם החתימה בהתאם לדרישות הספציפיות שלכם או למה שהוגדר במופע EJBCA שלכם.

ארכיטקטורה

הארכיטקטורה מבוססת על מודל של רשות אישורים חיצונית, שבו שרת EJBCA ומודול האבטחה של החומרה (HSM) שמשמש כגיבוי מאוחסנים חיצונית מחוץ לגבולות הפיזיים של GDC, אבל אפשר לגשת אליהם דרך הרשת. אפשר לפרוס את שרת EJBCA באופן חיצוני כמכשיר חומרה או תוכנה. השילוב הבסיסי שמתואר במדריך הזה דורש רק שהשרת החיצוני של EJBCA יהיה נגיש באמצעות כתובת IP יציבה.

דיאגרמת ארכיטקטורה של Keyfactor EJBCA.

הרכיבים העיקריים בארכיטקטורה הזו:

  • ‫EJBCA Enterprise Server: פריסה חיצונית כמכשיר חומרה או כמכשיר תוכנה של Keyfactor, שכולל את רשויות האישורים (CA) (בסיסית ומשנית) ויוצר את כל נתוני המפתח של רשות האישורים בתוך HSM עם אישור CC EAL4+.
  • אשכול GDC Standard Kubernetes: סביבת המחשוב שבה פועלים עומסי העבודה של הלקוחות, cert-manager ושרתי proxy לשילוב.
  • ‫GDC Internal DNS: מנהל אזורי DNS פרטיים מקומיים (באמצעות שם הדומיין הפרטי שהוגדר במשתני הסביבה) שמשמשים לפתרון אתגרים של ACME DNS-01.
  • ‫GDC Egress Gateway: מכוון תעבורה יוצאת מתרמילי אשכול לכתובת ה-IP של שרת EJBCA חיצוני.
  • ‫Harbor Private Registry: מארח תמונות קונטיינרים משוכפלות (כמו EJBCA cert-manager issuer) לפריסה במערכות מבודדות.

לפני שמתחילים

לפני שמתחילים בשילוב, חשוב לוודא שסביבת GDC עומדת בדרישות הבאות:

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

    # GDC Environment Configuration
    export GDC_ORG="your-org-name"
    export GDC_ZONE="your-zone-name"
    export GDC_PROJECT_ID="your-project-id"
    export GDC_USER_NAME="your-gdc-user-email"
    export GDC_CLUSTER_NAME="your-cluster-name"
    
    # EJBCA Server Configuration
    export EJBCA_DNS_ZONE="example.internal"
    export EJBCA_HOSTNAME="ejbca.${EJBCA_DNS_ZONE}"
    export EJBCA_LB_IP="XX.XX.XX.XX" # Stable IP of your EJBCA Server
    export EJBCA_CA_NAME="GDC Subordinate CA"
    export EJBCA_NAMESPACE="ejbca-ee"
    export CERTIFICATE_PROFILE_NAME="GDC TLS SERVER PROFILE"
    export END_ENTITY_PROFILE_NAME="GDC TLS SERVER EE PROFILE"
    
    # Harbor Private Registry Configuration
    export HARBOR_INSTANCE_URL="your-harbor-url.internal"
    export HARBOR_PROJECT="your-harbor-project"
    export HARBOR_ROBOT_ACCOUNT="robot$your-robot-name"
    export HARBOR_ROBOT_SECRET="your-robot-secret"
    export HARBOR_PULL_SECRET_NAME="harbor-secret"
    
  • הערה לגבי הרשת: המדריך הזה מבוסס על ההנחה שהוא מופעל מצומת bastion שיש לה גישה לממשקי ה-API של GDC עם air gap, וגם גישה לאינטרנט כדי להוריד את המניפסטים הנדרשים ואת קובצי האימג' של הקונטיינר. אם אתם מריצים את הפקודה הזו ממכונה ללא גישה לאינטרנט, אתם צריכים להשיג את הנכסים האלה בנפרד (למשל, באמצעות docker save לייצוא תמונות ממכונה מחוברת וdocker load לייבוא שלהן) ולהעלות אותם בצורה מאובטחת לסביבה שלכם לפני שתמשיכו.

הגדרת כינויים ל-kubectl

בקטע הזה, יוצרים כינויים נוחים לשורת הפקודה עבור ממשקי ה-API הגלובליים והניהול האזורי של GDC:

  • יוצרים כינוי ל-API לניהול אזורי (מחליפים את MANAGEMENT_API_KUBECONFIG בנתיב אל kubeconfig של ה-API לניהול):

    alias km="kubectl --kubeconfig MANAGEMENT_API_KUBECONFIG"
    
  • יוצרים כינוי ל-API הגלובלי (מחליפים את GLOBAL_API_KUBECONFIG בנתיב לקובץ kubeconfig של ה-API הגלובלי):

    alias kg="kubectl --kubeconfig GLOBAL_API_KUBECONFIG"
    

יצירת אשכול GDC רגיל

בקטע הזה מפרסים אשכול Kubernetes רגיל בתוך GDC ומגדירים תפקידי אדמין באשכול GDC רגיל ופרטי כניסה מקומיים למאגר תמונות של Harbor:

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

```shell
gdcloud compute machine-types list
```

‫2. בוחרים סוג מכונה מתאים לצמתי העובדים באשכול:

```shell
export MACHINE_TYPE="n3-standard-8-gdc"
```

‫3 יוצרים אשכול רגיל עם שני צמתי עובדים באמצעות API לניהול אזורי:

```shell
km create -f - <<EOF
apiVersion: cluster.gdc.goog/v1
kind: Cluster
metadata:
  name: ${GDC_CLUSTER_NAME}
  namespace: ${GDC_PROJECT_ID}
spec:
  nodePools:
  - machineTypeName: ${MACHINE_TYPE}
    nodeCount: 2
    name: ${GDC_CLUSTER_NAME}-node-pool
EOF
```

This creates a simple GDC cluster. Cluster creation
can take up to 60 minutes to complete. To check the status, use the
following command:

```shell
km get clusters/${GDC_CLUSTER_NAME} \
  -n ${GDC_PROJECT_ID} \
  --watch
```

After the cluster is ready, the output should show a STATE of `Running`.

‫4 אחרי שהאשכול מוכן, מאחזרים את פרטי הכניסה שלו:

```shell
KUBECONFIG=kubeconfig-${GDC_CLUSTER_NAME}.yaml gdcloud clusters \
  get-credentials ${GDC_CLUSTER_NAME} \
  --standard \
  --project ${GDC_PROJECT_ID} \
  --zone ${GDC_ZONE}
```

‫5 מקצים תפקידי אדמין סטנדרטיים של אשכול GDC למשתמש GDC:

```shell
gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
  --member="user:${GDC_USER_NAME}" \
  --role=cluster-admin

gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
  --member="user:${GDC_USER_NAME}" \
  --role=standard-cluster-admin
```

‫6 יוצרים מופע של Harbor ופרויקט של Harbor ב-GDC כדי לארח את תמונות הקונטיינר המשוכפלות:

```shell
gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
  --member="user:${GDC_USER_NAME}" \
  --role=harbor-instance-admin
```

‫7. יוצרים חשבון רובוט ב-Harbor ורושמים את שם המשתמש ואת המפתח הסודי שלו.

‫8 מאמתים את עצמכם באמצעות מופע Harbor:

```shell
docker --config=./docker-harbor login ${HARBOR_INSTANCE_URL} \
  -u ${HARBOR_ROBOT_ACCOUNT} \
  -p ${HARBOR_ROBOT_SECRET}
```

This saves the robot account credentials to
`./docker-harbor/config.json` for subsequent Secret creation.

הגדרת התשתית והרשת

בקטע הזה, תגדירו את התשתית הבסיסית של GDC ואת הגדרות הרשת. כך תוכלו לוודא שעומסי העבודה של Kubernetes יוכלו לפתור את שם הדומיין של המארח החיצוני EJBCA ולנתב בהצלחה קריאות ל-API יוצאות לכתובת ה-IP שלו.

הגדרת שרת DNS פרטי ב-GDC עם air gap

כדי להגדיר פתרון דומיין, פורסים אזור DNS פרטי וקבוצת רשומות כדי למפות את שרת EJBCA החיצוני לשם דומיין מקומי, וכך לאפשר לשירותים ב-GDC להתחבר באמצעות שם מארח יציב במקום כתובת IP גולמית:

  • מקצים למשתמש את התפקיד Managed DNS Project Admin:

    gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
      --member=user:${GDC_USER_NAME} \
      --role=managed-dns-project-admin
    
  • פורסים את משאב ManagedDNSZone הגלובלי:

    kubectl --kubeconfig GLOBAL_API_KUBECONFIG apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ManagedDNSZone
    metadata:
      name: private-example-internal
      namespace: ${GDC_PROJECT_ID}
    spec:
      dnsName: ${EJBCA_DNS_ZONE}
      visibility: PRIVATE
    EOF
    
  • מבצעים פריסה של ResourceRecordSet שמפנה לכתובת ה-IP של מכשיר EJBCA:

    kubectl --kubeconfig GLOBAL_API_KUBECONFIG apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ResourceRecordSet
    metadata:
      name: ${EJBCA_HOSTNAME}
      namespace: ${GDC_PROJECT_ID}
    spec:
      name: ${EJBCA_HOSTNAME}
      ttlSeconds: 600
      type: A
      rrData:
      - ${EJBCA_LB_IP}
      dnsZone: private-example-internal
    EOF
    

הגדרת שער NAT לדואר יוצא

לאחר מכן, מגדירים רשת יוצאת של GDC על ידי הגדרת רשת משנה מותאמת אישית ושער NAT כדי לאפשר לעומסי עבודה של Kubernetes (כמו cert-manager ולקוחות של רשות רישום) לנתב באופן מאובטח תנועה יוצאת לשרת EJBCA:

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

    gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
      --member=user:${GDC_USER_NAME} \
      --role=cloud-nat-developer
    
    gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
      --member=user:${GDC_USER_NAME} \
      --role=subnet-project-admin
    
    gdcloud organizations add-iam-policy-binding ${GDC_ORG} \
      --member="user:${GDC_USER_NAME}" \
      --role=subnet-org-admin
    
  • יוצרים את תת-הרשת ליציאה:

    kubectl --kubeconfig MANAGEMENT_API_KUBECONFIG apply -f - <<EOF
    apiVersion: ipam.gdc.goog/v1
    kind: Subnet
    metadata:
      name: ejbca-cluster-egress
      namespace: ${GDC_PROJECT_ID}
    spec:
      ipv4Request:
        prefixLength: 32
      parentReference:
        name: data-network-segment-${GDC_ZONE}-group
        namespace: platform
        type: SubnetGroup
      type: Leaf
    EOF
    
  • יוצרים את CloudNATGateway בהתאם לסלקטור של מנפיק האישורים ב-cert-manager:

    kubectl --kubeconfig MANAGEMENT_API_KUBECONFIG apply -f - <<EOF
    apiVersion: networking.gdc.goog/v1
    kind: CloudNATGateway
    metadata:
      name: ejbca-egress-gateway
      namespace: ${GDC_PROJECT_ID}
    spec:
      subnetRefs:
      - ejbca-cluster-egress
      workloadSelector:
        labelSelector:
          clusters:
            matchLabels:
              kubernetes.io/metadata.name: ${GDC_CLUSTER_NAME}
          workloads:
            matchLabels:
              app.kubernetes.io/name: ejbca-cert-manager-issuer
    EOF
    

שילוב של Kubernetes cert-manager

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

תרשים שילוב של EJBCA עם cert-manager.

הגדרת EJBCA עבור המוסד המנפיק

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

יצירת פרופיל אישורים לאדמין

מתחילים בהגדרת פרופיל אישור בתוך EJBCA כדי להגדיר את המאפיינים הטכניים והמגבלות הקריפטוגרפיות (כמו אלגוריתמים ותקופות תוקף) של האישור האדמיניסטרטיבי:

  • פותחים את ממשק המשתמש של EJBCA Admin, עוברים אל CA Functions (פונקציות של רשות אישורים) > Certificate Profiles (פרופילים של אישורים).
  • משכפלים את הפרופיל ENDUSER ונותנים לו את השם GDC ADMIN PROFILE.
  • עורכים את GDC ADMIN PROFILE וקובעים את ההגדרות הבאות:
    • אלגוריתמים זמינים של מפתחות: RSA
    • אורכים זמינים בביטים: 2048, ‏ 3072, ‏ 4096
    • אלגוריתם חתימה: SHA512WithRSA
    • תוקף: 200d
    • שם חלופי של המוסד המנפיק: מחיקה שימוש
    • CRL Distribution Points: מסמנים את התיבה Use (שימוש).
    • שימוש בנקודת הפצה של CRL שמוגדרת על ידי רשות אישורים: מסמנים את התיבה שימוש.
    • Authority Information Access: מסמנים את התיבה Use (שימוש)
    • שימוש במיקום OCSP שהוגדר על ידי CA: מסמנים את התיבה שימוש.
    • שימוש במוסד המנפיק (CA) שהוגדר על ידי CA: מסמנים את התיבה שימוש.
    • רשויות אישורים זמינות: בוחרים באפשרות GDC Subordinate CA
  • לוחצים על Save.

יצירת פרופיל של ישות קצה לאדמין

בשלב הבא, יוצרים פרופיל של ישות קצה ב-EJBCA כדי להגדיר שדות ברירת מחדל והקצאות של רשות אישורים (CA), וכך מפשטים את תהליך ההרשמה והנפקת האישור האדמיניסטרטיבי:

  • עוברים אל RA Functions (פונקציות של רשות רישום) > End Entity Profiles (פרופילים של ישויות קצה).
  • בקטע Add End Entity Profile (הוספת פרופיל של ישות קצה), מזינים את GDC ADMIN EE PROFILE ולוחצים על Add Profile (הוספת פרופיל).
  • עורכים את הפרופיל ומגדירים את ההגדרות הבאות:
    • פרופיל ברירת מחדל של אישורים: GDC ADMIN PROFILE
    • פרופילים זמינים של אישורים: GDC ADMIN PROFILE
    • Default CA: GDC Subordinate CA
    • רשויות אישורים זמינות: GDC Subordinate CA
  • לוחצים על Save.

רישום אישור אדמין

אחרי שיוצרים את הפרופילים, נרשמים באמצעות ממשק EJBCA Registration Authority (RA) ומחלצים את המפתח הפרטי, את האישור הציבורי ואת שרשרת האמון כדי ליצור את קובצי אמצעי הזיהוי הפיזיים שנדרשים לאימות cert-manager:

  • עוברים לכרטיסייה RA Web (גישה מרחוק לאינטרנט).
  • לוחצים על יצירת בקשה חדשה ומגדירים:
    • סוג האישור: GDC ADMIN EE PROFILE
    • יצירת זוג מפתחות: על ידי רשות האישורים (CA)
    • אלגוריתם המפתח: RSA 4096 ביט
    • שם נפוץ (CN): cert-manager
    • שם משתמש: cert-manager
    • קוד הרשמה: abcd
  • לוחצים על הורדת PEM ושומרים אותו כ-cert-manager.pem.
  • מפצלים את קובצי ה-PEM לשלושה קבצים:

    • ‫client.key (המפתח הסודי):

      openssl pkey -in cert-manager.pem -out client.key
      
    • ‫client.crt (האישור הציבורי):

      openssl x509 -in cert-manager.pem -out client.crt
      
    • ca.crt (שרשרת האמון עם האישורים של רשות האישורים המשנית ורשות האישורים הבסיסית):

      awk '/BEGIN CERTIFICATE/{i++} i>1' cert-manager.pem > ca.crt
      

הגדרת תפקידים וכללי גישה

לבסוף, יוצרים תפקיד אדמין ב-EJBCA ומקשרים אותו למספר הסידורי של האישור ב-cert-manager כדי לוודא שלגורם המנפיק יש רק את קבוצת ההרשאות המינימלית שנדרשת לאישור ולבקשה של אישורים:

  • בממשק המשתמש של EJBCA Admin, עוברים אל RA Functions (פונקציות של רשות רישום) > Search End Entities (חיפוש ישויות קצה).
  • מחפשים את cert-manager הישות הסופית ורושמים את המספר הסידורי של האישור שלה.
  • עוברים אל System Functions (פונקציות מערכת) > Roles and Access Rules (תפקידים וכללי גישה) ולוחצים על Add (הוספה).
  • נותנים לתפקיד את השם cert-manager ומוסיפים חבר חדש באמצעות המספר הסידורי שרשמתם.
  • לוחצים על עריכת כללי הגישה ומגדירים את ההרשאות הבאות:
    • תבנית תפקיד: אדמינים של RA
    • רשויות אישורים מורשות: GDC Subordinate CA
    • כללים לגבי ישויות סופיות: אישור, יצירה ועריכה של ישויות סופיות
    • פרופילים של ישויות קצה: GDC TLS SERVER EE PROFILE
    • כללים אחרים: מבטלים את הסימון של הצגת יומן הביקורת.
  • לוחצים על Save.

הכנת אשכול GDC

כדי להכין את סביבת GDC, צריך לבצע אימות באמצעות אשכול Kubernetes רגיל ולאחסן את פרטי הכניסה האדמיניסטרטיביים שחולצו מ-EJBCA בתוך Kubernetes Secrets, כדי שיהיו נגישים בצורה מאובטחת ל-pods של cert-manager issuer:

  • אחזור פרטי כניסה לאשכול רגיל:

    gdcloud clusters get-credentials "${GDC_CLUSTER_NAME}" \
      --standard \
      --project "${GDC_PROJECT_ID}" \
      --zone "${GDC_ZONE}"
    
  • יוצרים את מרחב השמות של היעד עבור מנפיק בהתאמה אישית:

    kubectl create ns ejbca-issuer-system
    
  • פורסים את הסוד של אימות TLS:

    kubectl create secret tls ejbca-secret \
      -n ejbca-issuer-system \
      --cert=client.crt \
      --key=client.key
    
  • פורסים את הסוד של שרשרת האמון של EJBCA:

    kubectl create secret generic ejbca-ca-secret \
      -n ejbca-issuer-system \
      --from-file=ca.crt
    

התקנת מנפיק EJBCA

כדי להגדיר את הפריסה, משכפלים את קובץ האימג' של קונטיינר הנפקת האישורים של EJBCA cert-manager למאגר הפרטי של Harbor ופורסים את תרשים Helm. הפקודה הזו יוצרת מופע של בקר מותאם אישית שנדרש כדי לתרגם בקשות לאישור Kubernetes לקריאות ל-EJBCA API:

  • יוצרים סוד למשיכת תמונות מ-Harbor במרחב השמות של המנפיק:

    # Authenticate with the private Harbor registry
    docker --config=./docker-harbor login ${HARBOR_INSTANCE_URL} \
      -u ${HARBOR_ROBOT_ACCOUNT} \
      -p ${HARBOR_ROBOT_SECRET}
    
    kubectl create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker-harbor/config.json \
      -n ejbca-issuer-system
    
  • משכפלים את תמונת ה-issuer הרשמית של EJBCA cert-manager ל-Harbor:

    docker pull keyfactor/ejbca-cert-manager-issuer:latest --platform linux/amd64
    
    docker tag keyfactor/ejbca-cert-manager-issuer:latest \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/ejbca-cert-manager-issuer:latest
    
    docker --config=./docker-harbor push \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/ejbca-cert-manager-issuer:latest
    
  • מוסיפים את מאגר Helm ומורידים את התרשים:

    helm repo add ejbca-issuer https://keyfactor.github.io/ejbca-cert-manager-issuer
    helm repo update
    helm pull ejbca-issuer/ejbca-cert-manager-issuer --untar
    
  • פורסים את תרשים Helm באמצעות מאגר התמונות המשוכפל:

    helm install ejbca-cert-manager-issuer ./ejbca-cert-manager-issuer \
      --namespace ejbca-issuer-system \
      --set image.repository=${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/ejbca-cert-manager-issuer \
      --set "imagePullSecrets[0].name=${HARBOR_PULL_SECRET_NAME}" \
      --set image.tag=latest
    

יצירת משאב המנפיק

בשלב הבא, מגדירים הרשאות RBAC ב-GDC ומפריסים משאב ClusterIssuer גלובלי, שרושם את שרת EJBCA כמקור חתימה מהימן במסגרת cert-manager של Kubernetes:

  • מגדירים הרשאות RBAC כדי לאפשר לבקר cert-manager של GDC להשתמש במונפק EJBCA בהתאמה אישית:

    kubectl apply -f - <<EOF
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com
    rules:
    - verbs:
      - approve
      apiGroups:
      - cert-manager.io
      resources:
      - signers
      resourceNames:
      - issuers.ejbca-issuer.keyfactor.com/*
      - clusterissuers.ejbca-issuer.keyfactor.com/*
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com
    subjects:
    - kind: ServiceAccount
      name: cert-manager
      namespace: cert-manager
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com
    EOF
    
  • פורסים את משאב ClusterIssuer הגלובלי:

    kubectl apply -f - <<EOF
    apiVersion: ejbca-issuer.keyfactor.com/v1alpha1
    kind: ClusterIssuer
    metadata:
      name: clusterissuer-ejbca
    spec:
      hostname: "${EJBCA_HOSTNAME}"
      ejbcaSecretName: "ejbca-secret"
      caBundleSecretName: "ejbca-ca-secret"
      certificateAuthorityName: "${EJBCA_CA_NAME}"
      certificateProfileName: "${CERTIFICATE_PROFILE_NAME}"
      endEntityProfileName: "${END_ENTITY_PROFILE_NAME}"
      endEntityName: ""
    EOF
    
  • בודקים את הסטטוס של המנפיק:

    kubectl get clusterissuer.ejbca-issuer.keyfactor.com/clusterissuer-ejbca \
      -o "custom-columns=NAME:.metadata.name,STATUS:.status.conditions[0].message"
    

    הפלט צריך לכלול את:

    NAME                  STATUS
    clusterissuer-ejbca   Success
    

בקשת אישור

כדי לאמת את השילוב, פורסים משאב אישור רגיל של Kubernetes כדי לבדוק את התהליך מקצה לקצה של cert-manager ולוודא ש-EJBCA חותם על האישור המבוקש ומקצה אותו בהצלחה:

יוצרים משאב Certificate לבדיקה כדי לוודא שהשילוב בוצע בהצלחה:

kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: ejbca-test-certificate
  namespace: ${EJBCA_NAMESPACE}
spec:
  commonName: example.com
  secretName: ejbca-certificate
  issuerRef:
    name: clusterissuer-ejbca
    group: ejbca-issuer.keyfactor.com
    kind: ClusterIssuer
EOF

מוודאים שהאישור נוצר ומוכן לשימוש:

kubectl get certificates.cert-manager.io -n ${EJBCA_NAMESPACE}

הפלט צריך לכלול את:

NAME                     READY   SECRET              AGE
ejbca-test-certificate   True    ejbca-certificate   12s

ACME אוטומטי עם אתגרים מסוג DNS-01

בקטע הזה מוגדר שירות ACME של EJBCA ומשתמשים במשאבי DNS פנימיים של GDC כדי להנפיק אישורים מאומתי-דומיין באופן אוטומטי. השילוב הזה מאפשר ללקוחות רגילים של cert-manager או Certbot לבקש אישורים באמצעות פרוטוקולי ACME אוטומטיים רגילים.

הגדרת EJBCA ל-ACME

כדי להכין את השרת, מפעילים את שירות ACME בתוך EJBCA ומגדירים כינוי ACME עם מפענח DNS ייעודי. כך מכינים את שרת EJBCA לעיבוד ולאימות של תגובות לאתגר DNS-01 בתוך GDC:

  • בממשק המשתמש של EJBCA Admin, עוברים אל System Configuration (הגדרת מערכת) > ACME Configuration (הגדרת ACME).
  • לוחצים על הוספה ומגדירים את האפשרויות הבאות:
    • שם: default
    • פרופיל של ישות קצה: GDC TLS SERVER EE PROFILE
    • הנפקת אישור עם תו כללי לחיפוש מותרת: מסמנים את התיבה
    • סוגי אתגרים של מזהה DNS לאימות MPIC של תגובה לאתגר: בוחרים באפשרות dns-01
    • DNS resolver (פענוח DNS): מזינים את כתובת ה-IP של ה-DNS הגלובלי.
    • אימות DNSSEC: ברור (כי מדובר בסביבה פרטית מקומית)
  • לוחצים על Save.

יצירת משתני סביבה של ACME

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

# ACME Alias created in the EJBCA configuration
export ACME_ALIAS="default"

# Arbitrary email address used for ACME registration
export ACME_EMAIL="your-email@example.com"

רישום לקוח Certbot

לאחר מכן, מתקינים את לקוח Certbot הרגיל ורושמים אותו בנקודת הקצה הפרטית של ACME ב-EJBCA. כך נוצר חשבון לקוח מהימן שנדרש כדי לבצע פעולות אוטומטיות של אישורים:

  • מתקינים את certbot בתחנת העבודה. לדוגמה, ב-macOS:

    brew install certbot
    
  • יוצרים תיקיות מקומיות להגדרות וליומנים:

    mkdir -p ./certbot/config ./certbot/work ./certbot/logs
    
  • רושמים את הלקוח בנקודת הקצה של ספריית ACME ב-EJBCA:

    certbot register \
      --config-dir ./certbot/config \
      --work-dir ./certbot/work \
      --logs-dir ./certbot/logs \
      --server https://${EJBCA_HOSTNAME}/ejbca/acme/${ACME_ALIAS}/directory \
      --email ${ACME_EMAIL} \
      --agree-tos \
      --no-eff-email
    

הנפקת אישור באמצעות אתגר DNS

לבסוף, מריצים בקשת Certbot ידנית ופורסים משאב DNS TXT זמני של GDC כדי לפתור את אתגר DNS-01. הפעולה הזו מאמתת את הבעלות שלכם על דומיין היעד ומפעילה הנפקת אישורים אוטומטית:

  • מריצים את פקודת האתגר הידני:

    certbot certonly \
      --manual \
      --preferred-challenges dns \
      --key-type rsa \
      --rsa-key-size 2048 \
      --config-dir ./certbot/config \
      --work-dir ./certbot/work \
      --logs-dir ./certbot/logs \
      --server https://${EJBCA_HOSTNAME}/ejbca/acme/${ACME_ALIAS}/directory \
      -d test.${EJBCA_DNS_ZONE}
    

    הטרמינל ייעצר ויוצג בו ערך לאימות. פלט לדוגמה:

    Please deploy a DNS TXT record under the name:
    
    _acme-challenge.test.example.internal.
    
    with the following value:
    
    q3pCmzXfIhsTpT4f4JAulHmHaAR3udC_9Wf1G498ER0
    
    Before continuing, verify the TXT record has been deployed.
    
  • מפרסים את רשומת ה-TXT ל-DNS הגלובלי עם המחרוזת שסופקה על ידי Certbot.

  • ממתינים כ-30 שניות להפצת ה-DNS, חוזרים למסוף Certbot ולוחצים על Enter.

    פלט לדוגמה:

    Successfully received certificate.
    Certificate is saved at:./certbot/config/live/test.example.internal/fullchain.pem
    Key is saved at:./certbot/config/live/test.example.internal/privkey.pem
    This certificate expires on 2026-11-16.
    These files will be updated when the certificate renews.
    
  • מוודאים שהאישור נכתב ב-./certbot/config/live/test.${EJBCA_DNS_ZONE}/.