במדריך הזה מפורטות הוראות להגדרת NGINX לשימוש במפתח Cloud HSM להעברת עומסי עבודה של TLS ב-Debian 11 (Bullseye). יכול להיות שתצטרכו לשנות את הפקודות האלה כדי שהן יפעלו במערכת ההפעלה או בהפצת Linux שלכם.
גרסה של המדריך הזה שמבוססת על Terraform זמינה במאגר GitHub של kms-solutions.
תרחישים לדוגמה
שימוש במפתח Cloud HSM עם NGINX לביטול העומס של TLS עוזר לתת מענה לצרכי האבטחה הבאים של הארגון:
- אתם רוצים ששרת האינטרנט NGINX יבצע העברה של פעולות קריפטוגרפיות של TLS ל-Cloud HSM.
- לא מומלץ לאחסן את המפתח הפרטי של האישור במערכת הקבצים המקומית של מופע Compute Engine שמארח את אפליקציית האינטרנט.
- אתם צריכים לעמוד בדרישות רגולטוריות שבהן האישורים של אפליקציות שפתוחות לציבור צריכים להיות מוגנים על ידי HSM עם אישור FIPS 140-2 ברמה 3.
- אתם רוצים להשתמש ב-NGINX כדי ליצור שרת proxy הפוך עם סיום TLS כדי להגן על אפליקציית האינטרנט שלכם.
לפני שמתחילים
לפני שממשיכים, צריך לבצע את השלבים במאמר שימוש במפתח Cloud HSM עם OpenSSL.
אחרי שמסיימים את ההגדרה של OpenSSL, מוודאים שמותקנת גרסה עדכנית של nginx:
sudo apt-get update
sudo apt-get install libengine-pkcs11-openssl opensc nginx
המלצות להגדרות אבטחה
כדי לאבטח את המופע שמארח את NGINX, מומלץ לבצע את הפעולות הבאות:
פועלים לפי ההוראות בנושא יצירה והפעלה של חשבונות שירות עבור מופעים כדי לארח את NGINX.
- מקצים את התפקידים הבאים:
roles/cloudkms.signerVerifierroles/cloudkms.viewer
- מקצים את התפקידים הבאים:
כדי להגביל את כתובות ה-IP החיצוניות ואת יצירת המפתחות לחשבונות שירות, צריך להגדיר את מדיניות הארגון באופן הבא.
constraints/compute.vmExternalIpAccessconstraints/iam.disableServiceAccountKeyCreation
יוצרים תת-רשת מותאמת אישית שמאפשרת גישה פרטית ל-Google.
מגדירים כללים לחומת האש.
- יוצרים כללים של חומת אש של IAP רק עבור SSH.
יוצרים מכונה וירטואלית של Linux ומגדירים אותה באופן הבא:
- בוחרים את חשבון השירות הנכון שיצרתם קודם.
- בוחרים את הרשת שיצרתם קודם.
- מוסיפים תוויות מתאימות לכל כלל של חומת אש.
- מוודאים שהשדה 'כתובת IP חיצונית' ברשת המשנה מוגדר לערך
none.
מקצים את התפקיד 'משתמש מנהרה באבטחת IAP' (
roles/iap.tunnelResourceAccessor) למזהה שלכם במופע.- מידע נוסף זמין במאמר הגדרת IAP ל-Compute.
יצירה והגדרה של מפתח חתימה ב-Cloud HSM
בקטעים הבאים מפורטים השלבים שנדרשים כדי ליצור ולהגדיר מפתח חתימה ב-Cloud HSM.
יצירת מפתח חתימה שמתארח ב-Cloud HSM
יוצרים מפתח חתימה של Cloud HSM EC-P256-SHA256 בפרויקטGoogle Cloud , באוסף המפתחות שהגדרתם קודם ל-OpenSSL:
gcloud kms keys create NGINX_KEY \
--keyring "KEY_RING" --project "PROJECT_ID" \
--location "LOCATION" --purpose "asymmetric-signing" \
--default-algorithm "ec-sign-p256-sha256" --protection-level "hsm"
התחברות למכונה הווירטואלית באמצעות SSH ו-IAP
מתחברים ל-VM באמצעות SSH ו-IAP באמצעות הפקודה הבאה:
gcloud compute ssh INSTANCE \
--zone ZONE --tunnel-through-iap
אם נתקלתם בבעיה, ודאו שהשתמשתם בדגל --tunnel-through-iap.
בנוסף, צריך לוודא שיש לזהות שאומתה באמצעות ה-CLI של gcloud את התפקיד 'משתמש מנהרה באבטחת IAP' (roles/iap.tunnelResourceAccessor) במופע.
יצירת אישור באמצעות OpenSSL
בסביבת ייצור, יוצרים בקשת חתימה על אישור (CSR). מידע נוסף על יצירת CSR שולחים את ה-CSR לרשות האישורים (CA) כדי שהיא תוכל ליצור אישור בשבילכם. משתמשים באישור שסופק על ידי רשות האישורים בקטעים הבאים.
לדוגמה, אפשר ליצור אישור עם חתימה עצמית באמצעות מפתח החתימה של Cloud HSM. כדי לעשות זאת, OpenSSL מאפשר לכם להשתמש ב-URI של PKCS #11 במקום בנתיב רגיל, ולזהות את המפתח לפי התווית שלו (במקרה של מפתחות Cloud KMS, התווית היא השם של CryptoKey).
openssl req -new -x509 -days 3650 -subj '/CN=CERTIFICATE_NAME/' \
DIGEST_FLAG -engine pkcs11 -keyform engine \
-key PKCS_KEY_TYPE=KEY_IDENTIFIER > CA_CERT
מחליפים את מה שכתוב בשדות הבאים:
-
CERTIFICATE_NAME: שם לאישור. -
DIGEST_FLAG: אלגוריתם הגיבוב שבו נעשה שימוש במפתח החתימה האסימטרי. משתמשים ב--sha256, ב--sha384או ב--sha512בהתאם למקש. -
PKCS_KEY_TYPE: סוג המזהה שמשמש לזיהוי המפתח. כדי להשתמש בגרסה העדכנית ביותר של המפתח, משתמשים בפונקציהpkcs11:objectעם שם המפתח. כדי להשתמש בגרסה ספציפית של מפתח, משתמשים ב-pkcs11:idעם מזהה המשאב המלא של גרסת המפתח. -
KEY_IDENTIFIER: מזהה של המפתח. אם אתם משתמשים ב-pkcs11:object, צריך להשתמש בשם המפתח – לדוגמה,NGINX_KEY. אם אתם משתמשים ב-pkcs11:id, צריך להשתמש במזהה המשאב המלא של המפתח או של גרסת המפתח – לדוגמה,projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/NGINX_KEY/cryptoKeyVersions/KEY_VERSION. -
CA_CERT: הנתיב שבו רוצים לשמור את קובץ האישור.
אם הפקודה נכשלת, יכול להיות שהאילוץ PKCS11_MODULE_PATH הוגדר בצורה שגויה, או שאין לכם את ההרשאות הנכונות לשימוש במפתח החתימה של Cloud KMS.
עכשיו אמור להיות לכם אישור שנראה כך:
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
התקנת האישור ל-NGINX
מריצים את הפקודות הבאות כדי ליצור מיקום להצבת האישור הציבורי:
sudo mkdir /etc/ssl/nginx
sudo mv CA_CERT /etc/ssl/nginx
הגדרת הסביבה לשימוש בספריית PKCS #11
בקטעים הבאים מפורטים השלבים שצריך לבצע כדי להכין את הסביבה ולבדוק אותה.
הכנת הגדרות של ספריות ל-NGINX
כדי לאפשר ל-NGINX לרשום ביומן את הפעולות של מנוע PKCS #11 באמצעות הספרייה, צריך להשתמש בפקודה הבאה:
sudo mkdir /var/log/kmsp11
sudo chown www-data /var/log/kmsp11
יוצרים קובץ תצורה ריק של הספרייה עם ההרשאות המתאימות ל-NGINX.
sudo touch /etc/nginx/pkcs11-config.yaml
sudo chmod 744 /etc/nginx/pkcs11-config.yaml
עורכים את קובץ ההגדרות הריק ומוסיפים את ההגדרות הנדרשות כמו בקטע הקוד הבא:
# cat /etc/nginx/pkcs11-config.yaml
---
tokens:
- key_ring: "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING"
log_directory: "/var/log/kmsp11"
בדיקת ההגדרה של OpenSSL
מריצים את הפקודה הבאה:
openssl engine -tt -c -v pkcs11
הפלט אמור להיראות כך:
(pkcs11) pkcs11 engine
[RSA, rsaEncryption, id-ecPublicKey]
[ available ]
SO_PATH, MODULE_PATH, PIN, VERBOSE, QUIET, INIT_ARGS, FORCE_LOGIN
הגדרת NGINX לשימוש ב-Cloud HSM
אפשר לאפשר העברת נתוני TLS על ידי עריכה של כמה קובצי NGINX. קודם כל, עורכים את הקובץ /etc/nginx/nginx.conf בשני מקומות כדי להוסיף כמה הנחיות להגדרת NGINX לשימוש ב-PKCS #11.
אחרי הבלוק event ולפני הבלוק http, מוסיפים את ההוראות הבאות:
ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;
באותו קובץ /etc/nginx/nginx.conf, מגדירים הנחיות SSL לשימוש באישור ובמפתח הפרטי שלו ב-Cloud HSM. בבלוק http מוסיפים את המאפיינים הבאים:
ssl_certificate "/etc/ssl/nginx/CA_CERT";
ssl_certificate_key "engine:pkcs11:PKCS_KEY_TYPE=KEY_IDENTIFIER";
ssl_protocols TLSv1.2 TLSv1.3; # Consider changing the default to only TLS1.2 or newer
# Consider defining the `ssl_ciphers` to use ciphers approved by your security teams and handle
# appropriate client compatibility requirements.
קובץ /etc/nginx/nginx.conf צריך להיראות כך:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;
http {
#...
#...
# SSL configuration
ssl_certificate "/etc/ssl/nginx/CA_CERT";
ssl_certificate_key "engine:pkcs11:pkcs11:object=NGINX_KEY";
ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
# ssl_ciphers YOUR_CIPHERS
ssl_prefer_server_ciphers on;
#...
#...
}
הגדרת NGINX להאזנה לתעבורת TLS
עורכים את הקובץ /etc/nginx/sites-enabled/default כדי להאזין לתנועת TLS.
מבטלים את ההערה של הגדרת ה-SSL בבלוק server.
השינוי שיתקבל צריך להיראות כמו בדוגמה הבאה:
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# ...
# ...
}
העברת משתני סביבה לשירות NGINX
מריצים את הפקודה הבאה:
sudo systemctl edit nginx.service
בעורך שמופיע, מוסיפים את השורות הבאות ומחליפים את LIBPATH בערך של המיקום שבו התקנתם את libkmsp11.so:
[Service]
Environment="GRPC_ENABLE_FORK_SUPPORT=1"
Environment="KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml"
Environment="PKCS11_MODULE_PATH=LIBPATH/libkmsp11-1.0-linux-amd64/libkmsp11.so"
אחרי שמגדירים את הערכים האלה, צריך להריץ את הפקודה הבאה כדי שהם יהיו זמינים:
sudo systemctl daemon-reload
הפעלה מחדש של NGINX עם TLS Offloading
מריצים את הפקודה הבאה כדי להפעיל מחדש את NGINX ולהשתמש בהגדרות המעודכנות:
sudo systemctl start nginx
בדיקת NGINX באמצעות העברת TLS ל-Cloud HSM
משתמשים בפקודה openssl s_client כדי לבדוק את החיבור לשרת NGINX:
openssl s_client -connect localhost:443
הלקוח משלים את לחיצת היד של SSL וממתין לקלט שלכם:
# completes SSL handshake
# ...
# ...
# ...
Verify return code: 18 (self signed certificate)
# ...
Max Early Data: 0
---
read R BLOCK
# When the client pauses, it's waiting for instructions.
# Have the client get the index.html file in the root path (`/`), by typing the following:
GET /
# Press enter.
# You should now see the default NGINX index.html file.
עכשיו יומני הביקורת אמורים להציג פעולות במפתח NGINX_KEY.
כדי לראות את היומנים, עוברים אל Cloud Logging במסוף Google Cloud .
בפרויקט שבו אתם משתמשים, מוסיפים את המסנן הבא:
resource.type="cloudkms_cryptokeyversion"
אחרי שמריצים את השאילתה, אמורות להופיע פעולות של מפתח אסימטרי בNGINX_KEY.
הגדרות אופציונליות
יכול להיות שתצטרכו ליצור מאזן עומסי רשת חיצוני להעברת סיגנל ללא שינוי כדי לחשוף את שרת NGINX עם כתובת IP חיצונית.
אם אתם צריכים להשתמש ב-NGINX כשרת proxy הפוך עם איזון עומסים, כדאי לעדכן את קובץ ההגדרות של NGINX. מידע נוסף על הגדרת NGINX כשרת proxy הפוך זמין במאמר All-Active HA for NGINX Plus on the Google CloudPlatform.
השלבים הבאים
הגדרתם את שרת NGINX כך שישתמש ב-TLS offloading ל-Cloud HSM.