Cloud NGFW Essentials for Load Balancers

1. מבוא

ב-Codelab הזה נסביר על Cloud Next Generation Firewall ‏ (NGFW) Essentials למאזני עומסים פנימיים של אפליקציות (ALB) ולמאזני עומסים של רשת בשרת proxy ‏ (NLB) באמצעות מדיניות אזורית של חומת אש בין רשתות.

‫Cloud NGFW הוא שירות חומת אש מבוזרת לחלוטין עם יכולות מתקדמות של הגנה מפני איומים ומיקרו-פילוח, שנועד להגן על עומסי עבודה ב-Google Cloud. הפעלת Cloud NGFW ברמת מאזן העומסים מחילה כללים עקביים של מדיניות חומת אש על כל תעבורת TCP שנכנסת למאזני עומסים פנימיים מבוססי-פרוקסי. הוא מפשט את הקצאת מצב האבטחה של הארגון על ידי אכיפה רחבה יותר של מדיניות בכל השירותים.

המוצרים והתכונות הבאים של Cloud NGFW ושל איזון עומסים ב-Cloud מכוסים ב-Codelab הזה:

  • ‫Cloud NGFW Essentials
  • מדיניות אזורית של חומת אש בין רשתות
  • מאזן עומסים פנימי אזורי של אפליקציות (ALB)
  • קבוצה של מופעי מכונה מנוהלים (MIG) בקצה העורפי וקבוצה של נקודות קצה ברשת (NEG) מסוג Private Service Connect ‏ (PSC)

הערה: בתיעוד של Cloud NFGW אפשר למצוא את הפיצ'רים העדכניים שנתמכים ואת המגבלות של כללי מדיניות חומת האש עבור יעדים של איזון עומסים.

מה לומדים

  • הפעלת כללי מדיניות בסיסיים של חומת אש ב-Cloud NGFW שמטרגטים מאזני עומסים
  • הגנה על שירות פנימי של מאזן עומסים לצרכנים באמצעות מכונה וירטואלית וקצוות עורפיים של PSC
  • בדיקת גישת הלקוח ואימות יומני חומת האש

מה צריך

2. מושגים

רמות של תכונות חומת האש

ל-Cloud NGFW יש שלוש רמות של תכונות: Essentials,‏ Standard ו-Enterprise. כל רמה מתקדמת מציעה רמות נוספות של סינון תעבורת רשת ויכולות בדיקה.

סיכום של יכולות הסינון של Cloud NGFW Essentials:

שכבה

פונקציה

שכבות רשת

דוגמאות לפרמטרים של כללים

Essentials

סינון לפי כתובת IP וטווח כתובות IP

קניין רוחני (IP)

--src-ip-ranges=1.1.1.0/24,2.2.2.2/32

Essentials

קבוצות של כתובות

קניין רוחני (IP)

--src-address-groups=special-ranges

Essentials

סינון לפי פרוטוקול ויציאה

TCP

--layer4-configs=tcp

Essentials

תגים מאובטחים

מטא-נתונים

--src-secure-tags=tagValues/987654321098

Essentials

סינון לפי סוג הרשת

כתובת IP / מטא-נתונים

--src-network-type=INTRA_VPC

כללי ההעברה של מאזן העומסים מגדירים במפורש את יעד יציאת ה-TCP. הפרמטר --layer4-configs= של כלל חומת האש יכול לציין רק tcp. ערך היציאה משתמע מכלל ההעברה עצמו.

קבוצות כתובות וסוגי רשתות יכולים לעזור ליצור כללים יעילים יותר למדיניות חומת האש. סוגי הרשתות VPC_NETWORKS ו-INTRA_VPC נתמכים בכללי מדיניות חומת האש למאזני עומסים.

הערה: כללי מדיניות חומת האש למאזני עומסים תומכים רק ב---direction=INGRESS. הכללים האלה נועדו לשלוט בגישה לשירותים שמאזן העומסים חושף.

סינון במישור הנתונים

התכונות של Cloud NFGW Essentials כוללות כללי חומת אש בסיסיים עם שמירת מצב לשכבה 3 (כתובת IP) ולשכבה 4 (יציאת TCP). כל התכונות האלה של כללי מדיניות חומת האש מבוצעות ביעילות במישור הנתונים של מאזן העומסים בלי הצורך בבדיקה מלאה של החבילות.

כללי מדיניות של Cloud NGFW Essentials שמטרגטים מכונות וירטואליות נאכפים בבד רשת ה-VPC המבוזר כחלק מרשת הליבה של Google Cloud מוגדרת התוכנה (Andromeda). כללי מדיניות חומת אש וסינון מנות נאכפים ברמת ההיפר-ויז'ר של כל מופע של מכונה וירטואלית, לפני שהמנה מגיעה לממשק הרשת של המופע.

אכיפת כללי המדיניות של Cloud NGFW Essentials שמכוונים אל מאזני עומסים מתבצעת באמצעות הטכנולוגיות הבסיסיות של מאזני העומסים של Google Cloud, ובאופן ספציפי באמצעות תשתית פרוקסי השירות של Envoy. באמצעות אותו מודל משאבים ומבנה כללים של Cloud NFGW, סינון מנות עם שמירת מצב נאכף ישירות במישור הנתונים של מאזן העומסים מבוסס-ה-proxy.

יעדים של מאזן עומסים

יש כמה הבדלים עיקריים בין מדיניות Cloud NGFW שמיועדת למאזני עומסים לבין מדיניות שמיועדת למופעי מכונות וירטואליות.

אפשר להחיל כללים של מדיניות חומת אש על מאזן עומסים יחיד על ידי ציון --target-type=INTERNAL_MANAGED_LB לצד ההפניה הספציפית לכלל העברת התנועה של מאזן העומסים --target-forwarding-rules=FR_NAME. כדי לטרגט את כל כללי ההעברה של מאזן העומסים באזור של רשת ה-VPC (כאשר האזור מוגדר על ידי המדיניות), צריך להשמיט את ההפניה הספציפית ולהשתמש רק בדגל --target-type=INTERNAL_MANAGED_LB.

אם הפרמטר --target-type לא מוגדר בהגדרת הכלל, ברירת המחדל של הכלל היא להחיל אותו אוטומטית על כל מכונות ה-VM ולא על מאזני העומסים.

רשת Codelab

ב-Codelab הזה נעשה שימוש בפרויקט יחיד עם רשת VPC אחת ובמשאבים הבאים:

  • שתי תת-רשתות אזוריות
  • מדיניות חומת אש אחת של רשת אזורית
  • שלושה מאזני עומסים פנימיים אזוריים של אפליקציות (ALB)
    • www שירות HTTP עם קצה עורפי של קבוצת מכונות VM
    • api שירות HTTP עם קצה עורפי של קבוצת מכונות VM
    • gcs שירות HTTPS עם עורף קצה של PSC NEG ל-Google APIs
  • שתי מכונות וירטואליות לבדיקת מדיניות הרשאה ומדיניות דחייה שונות

figure1

איור 1. רשת Codelab

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

figure2

איור 1. Cloud NFGW למשאבי מאזן עומסים

מסנני Cloud NGFW Essentials מתוכנתים במישור הנתונים של מאזן העומסים ומיושמים בשכבת שירותי פרוקסי היעד המוגדרת – בדומה לממשק של מכונה וירטואלית – באמצעות אותם מנגנוני חומת אש מבוזרים ועקביים לאכיפת מדיניות.

3. הגדרת הפרויקט

גישה לפרויקט

ב-Codelab הזה נעשה שימוש בפרויקט אחד ב-Google Cloud. בשלבי ההגדרה נעשה שימוש בפקודות CLI של gcloud cli ובפקודות של מעטפת Linux.

כדי להתחיל, ניגשים לשורת הפקודה של הפרויקט בענן ב-Google Cloud:

הגדרת מזהה הפרויקט

gcloud config set project YOUR_PROJECT_ID_HERE

הפעלת שירותי API

gcloud services enable \
  cloudresourcemanager.googleapis.com \
  compute.googleapis.com \
  dns.googleapis.com \
  networksecurity.googleapis.com \
  certificatemanager.googleapis.com

הגדרת סביבת מעטפת

# set your region preference
export REGION_1="us-west1"
# set your zone preference
export ZONE_1="us-west1-c"
# fetch project info and verify vars set
export PROJECT_ID=$(gcloud config list --format="value(core.project)")
export PROJECT_NO=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
echo ${REGION_1}
echo ${ZONE_1}
echo ${PROJECT_ID}
echo ${PROJECT_NO}

4. הבסיס לרשת

בקטע הזה נסביר איך פורסים תשתית רשת עם:

  • רשת VPC גלובלית ורשתות משנה אזוריות
  • מדיניות חומת אש אזורית ברשת כדי לאבטח את רשת ה-VPC
  • ‫Cloud Router ו-Cloud NAT כדי שהשרתים יוכלו לאחזר חבילות תוכנה
  • הזמנות של כתובות IP ורשומות DNS ל-Ingress של מאזן עומסים

יצירת משאבי רשת

# create vpc network
gcloud compute networks create vnet-foo --subnet-mode=custom
# create subnet for clients
gcloud compute networks subnets create subnet-foo-1 \
  --network=vnet-foo \
  --region=${REGION_1} \
  --range=10.0.0.0/24 \
  --enable-private-ip-google-access
# create subnet for backend servers
gcloud compute networks subnets create subnet-foo-2 \
  --network=vnet-foo \
  --region=${REGION_1} \
  --range=172.16.0.0/24 \
  --enable-private-ip-google-access
# create proxy subnet
gcloud compute networks subnets create subnet-foo-3 \
  --purpose=REGIONAL_MANAGED_PROXY \
  --role=ACTIVE \
  --network=vnet-foo \
  --region=${REGION_1} \
  --range=172.16.128.0/23

יצירת רכיבים של חומת אש

מדיניות בסיסית של חומת אש אזורית ברשת שנוצרה כאן תשמש בהמשך להוספת יעדים ספציפיים למאזן העומסים. המדיניות צריכה להיות באותו אזור שבו נמצא מאזן העומסים.

יצירת קבוצת כתובות

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

# create address group
gcloud network-security address-groups create uhc-probes \
  --description="health check probes" \
  --type=IPv4 \
  --capacity=42 \
  --location=${REGION_1}
# add ip ranges to address group
gcloud network-security address-groups add-items uhc-probes \
  --items=35.191.0.0/16,130.211.0.0/22 \
  --location=${REGION_1}

יצירת מדיניות חומת אש

# create fw policy
gcloud compute network-firewall-policies create fw-policy-foo-${REGION_1} \
  --description="foo fw ${REGION_1}" \
  --region=${REGION_1}
# create fw policy rule to allow in iap
gcloud compute network-firewall-policies rules create 1001 \
  --description="allow iap for ssh" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp:22 \
  --src-ip-ranges=35.235.240.0/20
# create fw policy rule to allow in health checks
gcloud compute network-firewall-policies rules create 1002 \
  --description="allow health checks to backends" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp \
  --src-address-groups=projects/${PROJECT_ID}/locations/${REGION_1}/addressGroups/uhc-probes
# create fw policy rule to allow in lb proxies
gcloud compute network-firewall-policies rules create 1003 \
  --description="allow lb proxy" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp:80,tcp:443,tcp:8080 \
  --src-ip-ranges=172.16.128.0/23
# associate fw policy to vnet
gcloud compute network-firewall-policies associations create \
  --name=fw-policy-association-foo-${REGION_1} \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --network=vnet-foo \
  --firewall-policy-region=${REGION_1}

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

יצירת Cloud Router ושער NAT

# create router for nat
gcloud compute routers create cr-nat-foo \
  --network=vnet-foo \
  --asn=16550 \
  --region=${REGION_1}
# create nat gateway
gcloud compute routers nats create natgw-foo \
  --router=cr-nat-foo \
  --region=${REGION_1} \
  --auto-allocate-nat-external-ips \
  --nat-all-subnet-ip-ranges

שמירת כתובות IP

# reserve vip for lb www service
gcloud compute addresses create vip-foo-www \
  --region=${REGION_1} \
  --subnet=subnet-foo-1 \
  --addresses=10.0.0.101
# reserve vip for lb api service
gcloud compute addresses create vip-foo-api \
  --region=${REGION_1} \
  --subnet=subnet-foo-1 \
  --addresses=10.0.0.102
# reserve vip for lb gcs service
gcloud compute addresses create vip-foo-gcs \
  --region=${REGION_1} \
  --subnet=subnet-foo-1 \
  --addresses=10.0.0.103

יצירת רשומות DNS

# create dns zone
gcloud dns managed-zones create zone-foo \
  --description="private zone for foo" \
  --dns-name=foo.com \
  --networks=vnet-foo \
  --visibility=private
# create dns record for www service
gcloud dns record-sets create www.foo.com \
  --zone=zone-foo \
  --type=A \
  --ttl=300 \
  --rrdatas="10.0.0.101"
# create dns record for api service
gcloud dns record-sets create api.foo.com \
  --zone=zone-foo \
  --type=A \
  --ttl=300 \
  --rrdatas="10.0.0.102"
# create dns record for gcs service
gcloud dns record-sets create gcs.foo.com \
  --zone=zone-foo \
  --type=A \
  --ttl=300 \
  --rrdatas="10.0.0.103"

סיימנו את החלק של הגדרת הרשת. עכשיו נעבור להגדרת מאזני עומסים.

5. שירותי מאזן עומסים

בקטע הזה פורסים רכיבים של מאזן עומסים (שירותים לקצה העורפי, מיפוי של כתובות URL, שרתי proxy ביעד וכללי העברה) לשלושה שירותים:

  1. www service (ilb-foo-www) on port 80
  2. api service (ilb-foo-api) on port 8080
  3. שירות gcs (ilb-foo-gcs) ביציאה 443 עם אישור TLS

בנוסף למשאבי ה-Backend התומכים:

  1. מופעי מכונות וירטואליות שמריצים שרתי HTTP בקבוצת מופעי מכונה מנוהלים
  2. קבוצה של נקודות קצה ברשת (NEG) מסוג Private Service Connect ‏ (PSC) לממשקי API של Google
  3. קטגוריה של Google Cloud Storage‏ (GCS)

הגדרת משאבים בקצה העורפי

יצירת שרתים של קבוצת מופעים של מכונות וירטואליות

מאזן העומסים www ישתמש בשרתי הקצה העורפי של קבוצת מכונות ה-VM שמריצים שרת אינטרנט של Apache ומאזינים ליציאה 80.

מאזן העומסים api ישתמש באותה קבוצת מכונות וירטואליות שמקשיבה ליציאה 8080.

# create vm startup config with http server
cat > vm-server-startup.sh << 'OEOF'
#! /bin/bash
set -e
apt-get update
apt-get install apache2 -y
vm_hostname="$(curl -H "Metadata-Flavor:Google" \
http://169.254.169.254/computeMetadata/v1/instance/name)"
vm_zone="$(curl -H "Metadata-Flavor:Google" \
http://169.254.169.254/computeMetadata/v1/instance/zone | cut -d/ -f4)"
echo "www served from: $vm_hostname in zone $vm_zone on port 80" | \
tee /var/www/html/index.html
echo "Listen 8080" | tee -a /etc/apache2/ports.conf
mkdir -p /var/www/api
echo "api served from: $vm_hostname in zone $vm_zone on port 8080" | \
tee /var/www/api/index.html
tee /etc/apache2/sites-available/api.conf << EOF
<VirtualHost *:8080>
    DocumentRoot /var/www/api
</VirtualHost>
EOF
a2ensite api.conf
systemctl restart apache2
OEOF
# create managed instance group template
gcloud compute instance-templates create mig-template-foo \
  --machine-type=e2-micro \
  --network=vnet-foo \
  --region=${REGION_1} \
  --subnet=subnet-foo-2 \
  --no-address \
  --shielded-secure-boot \
  --metadata-from-file=startup-script=vm-server-startup.sh
# create regional managed instance group
gcloud compute instance-groups managed create mig-foo \
  --region=${REGION_1} \
  --size=2 \
  --template=mig-template-foo \
  --base-instance-name=service-foo
# create named ports for instance group
gcloud compute instance-groups managed set-named-ports mig-foo \
  --named-ports=www-port:80,api-port:8080 \
  --region=${REGION_1}

יצירת קטגוריית אחסון

מאזן העומסים (LB) של gcs ישתמש בקצה העורפי של PSC NEG כדי להתחבר דרך חזית ה-API של Google לקטגוריה של Cloud Storage.

# create random bucket name
export BUCKET=$(openssl rand -hex 12)
echo ${BUCKET}

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

# create bucket
gcloud storage buckets create gs://${BUCKET} --location=${REGION_1}
# give compute sa object admin role on bucket
gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \
  --member=serviceAccount:${PROJECT_NO}-compute@developer.gserviceaccount.com \
  --role=roles/storage.objectAdmin

צור אישור

מאזן העומסים gcs יסיים את בקשות ה-HTTPS של הלקוח באמצעות אישור בחתימה עצמית שנפרס בשרת ה-proxy של יעד ה-HTTPS.

# create cert
openssl req -x509 -newkey rsa:2048 \
  -nodes \
  -days 365 \
  -keyout foo-gcs-key.pem \
  -out foo-gcs-cert.pem \
  -subj "/CN=Foo, Inc." \
  -addext "subjectAltName=DNS:gcs.foo.com"
# upload to certificate manager
gcloud certificate-manager certificates create cert-foo-gcs \
  --private-key-file=foo-gcs-key.pem \
  --certificate-file=foo-gcs-cert.pem \
  --location=${REGION_1}

יצירת רכיבים של מאזן עומסים

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

פריסת סקריפט ליצירת מאזן עומסים

# create script file
cat > create_lbs.sh << EOF
#!/bin/bash
set -e

# --- Create load balancer for www service port 80 ---
echo "--- Creating Load Balancer for WWW Service (ilb-foo-www) on port 80 ---"

echo "ilb-foo-www: creating health check (hc-foo-www)"
gcloud compute health-checks create http hc-foo-www \
  --use-serving-port \
  --region=${REGION_1}

echo "ilb-foo-www: creating backend service (bes-foo-www)"
gcloud compute backend-services create bes-foo-www \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --protocol=HTTP \
  --port-name=www-port \
  --health-checks=hc-foo-www \
  --health-checks-region=${REGION_1} \
  --region=${REGION_1}

echo "ilb-foo-www: adding managed instance group (mig-foo) to backend service (bes-foo-www)"
gcloud compute backend-services add-backend bes-foo-www \
  --balancing-mode=UTILIZATION \
  --instance-group=mig-foo \
  --instance-group-region=${REGION_1} \
  --region=${REGION_1}

echo "ilb-foo-www: creating url map (ilb-foo-www)"
gcloud compute url-maps create ilb-foo-www \
  --default-service=bes-foo-www \
  --region=${REGION_1}

echo "ilb-foo-www: creating target http proxy (proxy-foo-www)"
gcloud compute target-http-proxies create proxy-foo-www \
  --url-map=ilb-foo-www \
  --url-map-region=${REGION_1} \
  --region=${REGION_1}

echo "ilb-foo-www: creating forwarding rule (fr-foo-www)"
gcloud compute forwarding-rules create fr-foo-www \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --network=vnet-foo \
  --subnet=subnet-foo-1 \
  --subnet-region=${REGION_1} \
  --address=vip-foo-www \
  --ports=80 \
  --target-http-proxy=proxy-foo-www \
  --target-http-proxy-region=${REGION_1} \
  --region=${REGION_1}

echo "--- Successfully created Load Balancer for WWW Service (ilb-foo-www) ---"
echo

# --- Create load balancer for api service port 8080 ---
echo "--- Creating Load Balancer for API Service (ilb-foo-api) on port 8080 ---"

echo "ilb-foo-api: creating health check (hc-foo-api)"
gcloud compute health-checks create http hc-foo-api \
  --use-serving-port \
  --region=${REGION_1}

echo "ilb-foo-api: creating backend service (bes-foo-api)"
gcloud compute backend-services create bes-foo-api \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --protocol=HTTP \
  --port-name=api-port \
  --health-checks=hc-foo-api \
  --health-checks-region=${REGION_1} \
  --region=${REGION_1}

echo "ilb-foo-api: adding managed instance group (mig-foo) to backend service (bes-foo-api)"
gcloud compute backend-services add-backend bes-foo-api \
  --balancing-mode=UTILIZATION \
  --instance-group=mig-foo \
  --instance-group-region=${REGION_1} \
  --region=${REGION_1}

echo "ilb-foo-api: creating url map (ilb-foo-api)"
gcloud compute url-maps create ilb-foo-api \
  --default-service=bes-foo-api \
  --region=${REGION_1}

echo "ilb-foo-api: creating target http proxy (proxy-foo-api)"
gcloud compute target-http-proxies create proxy-foo-api \
  --url-map=ilb-foo-api \
  --url-map-region=${REGION_1} \
  --region=${REGION_1}

echo "ilb-foo-api: creating forwarding rule (fr-foo-api)"
gcloud compute forwarding-rules create fr-foo-api \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --network=vnet-foo \
  --subnet=subnet-foo-1 \
  --subnet-region=${REGION_1} \
  --address=vip-foo-api \
  --ports=8080 \
  --target-http-proxy=proxy-foo-api \
  --target-http-proxy-region=${REGION_1} \
  --region=${REGION_1}

echo "--- Successfully created Load Balancer for API Service (ilb-foo-api) ---"
echo

# --- Create load balancer for gcs service port 443 ---
echo "--- Creating Load Balancer for GCS Service (ilb-foo-gcs) on port 443 ---"

echo "ilb-foo-gcs: creating network endpoint group (neg-psc-gcs)"
gcloud compute network-endpoint-groups create neg-psc-gcs \
  --network-endpoint-type=private-service-connect \
  --psc-target-service=storage.${REGION_1}.rep.googleapis.com \
  --region=${REGION_1}

echo "ilb-foo-gcs: creating backend service (bes-foo-gcs)"
gcloud compute backend-services create bes-foo-gcs \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --protocol=HTTPS \
  --region=${REGION_1}

echo "ilb-foo-gcs: adding network endpoint group (neg-psc-gcs) to backend service (bes-foo-gcs)"
gcloud compute backend-services add-backend bes-foo-gcs \
  --network-endpoint-group=neg-psc-gcs \
  --network-endpoint-group-region=${REGION_1} \
  --region=${REGION_1}

echo "ilb-foo-gcs: creating url map (ilb-foo-gcs)"
gcloud compute url-maps create ilb-foo-gcs \
  --default-service=bes-foo-gcs \
  --region=${REGION_1}

echo "ilb-foo-gcs: creating target https proxy (proxy-foo-gcs)"
gcloud compute target-https-proxies create proxy-foo-gcs \
  --url-map=ilb-foo-gcs \
  --url-map-region=${REGION_1} \
  --certificate-manager-certificates=cert-foo-gcs \
  --region=${REGION_1}

echo "ilb-foo-gcs: creating forwarding rule (fr-foo-gcs)"
gcloud compute forwarding-rules create fr-foo-gcs \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --network=vnet-foo \
  --subnet=subnet-foo-1 \
  --subnet-region=${REGION_1} \
  --address=vip-foo-gcs \
  --ports=443 \
  --target-https-proxy=proxy-foo-gcs \
  --target-https-proxy-region=${REGION_1} \
  --region=${REGION_1}

echo "--- Successfully created Load Balancer for GCS Service (ilb-foo-gcs) ---"
echo

echo "All load balancers created successfully."
EOF
# make script executable
chmod +x create_lbs.sh
# run script
./create_lbs.sh

הערה: הפעלת הסקריפט הזה תימשך כמה דקות.

אימות של יצירת מאזן עומסים

בודקים שכללי ההעברה ושירותי הקצה העורפי נפרסו.

# check forwarding rules
gcloud compute forwarding-rules list
# check backend services
gcloud compute backend-services list

כאן מסתיים החלק של הגדרת מאזן העומסים… עכשיו נעבור להגדרת מכונות VM של לקוחות.

6. גישת לקוח

יצירת משאבי לקוח של מכונה וירטואלית

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

יצירת מכונות וירטואליות

# set variables for client ip addresses
export VM_ALLOW_IP="10.0.0.11"
export VM_DENY_IP="10.0.0.12"
echo ${VM_ALLOW_IP}
echo ${VM_DENY_IP}
# create client 1 vm
gcloud compute instances create vm-allow \
  --machine-type=e2-micro \
  --zone=${ZONE_1} \
  --subnet=subnet-foo-1 \
  --no-address \
  --private-network-ip=${VM_ALLOW_IP} \
  --scopes=cloud-platform \
  --shielded-secure-boot
# create client 2 vm
gcloud compute instances create vm-deny \
  --machine-type=e2-micro \
  --zone=${ZONE_1} \
  --subnet=subnet-foo-1 \
  --no-address \
  --private-network-ip=${VM_DENY_IP} \
  --scopes=cloud-platform \
  --shielded-secure-boot

בדיקת שירות בסיסי

בדיקה מלקוח vm-allow

הערה: מכונות ה-VM יתחברו לאינטרנט ויהיה אפשר לגשת אליהן דרך ssh באמצעות IAP זמן קצר אחרי הפעלת הפקודות instances create. אם הבקשה נכשלת בניסיון הראשון, יכול להיות שתצטרכו להמתין רגע.

# send request to foo www service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  curl -s www.foo.com"
# send request to foo api service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  curl -s api.foo.com:8080"

בודקים את העלאת הקובץ ל-Google Cloud Storage דרך מאזן העומסים.

# send request to foo gcs service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  echo 'test one on the way' > test-upload-1.txt
  TOKEN=\$(gcloud auth print-access-token)
  curl -s -k -X POST \"https://gcs.foo.com/upload/storage/v1/b/${BUCKET}/o?uploadType=media&name=test-upload-object-1.txt\" \
  -H \"Authorization: Bearer \${TOKEN}\" \
  -H \"Content-Type: text/plain\" \
  --data-binary @test-upload-1.txt"

התגובה של Cloud Storage API מאשרת שנתיב הרשת פועל בצורה תקינה.

בדיקה מלקוח vm-deny

# send request to foo www service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s www.foo.com"
# send request to foo api service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s api.foo.com:8080"
# send request to foo gcs service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  echo 'test two on the way' > test-upload-2.txt
  TOKEN=\$(gcloud auth print-access-token)
  curl -s -k -X POST \"https://gcs.foo.com/upload/storage/v1/b/${BUCKET}/o?uploadType=media&name=test-upload-object-2.txt\" \
  -H \"Authorization: Bearer \${TOKEN}\" \
  -H \"Content-Type: text/plain\" \
  --data-binary @test-upload-2.txt"

הערה: הבדיקות האלה אמורות להצליח גם כן, כי עדיין לא הוגדרו כללי חומת אש שמוגדרים למאזן העומסים.

כאן מסתיימים כל החלקים העיקריים של ההגדרה… עכשיו נעבור ליצירת כללים של חומת אש למאזן העומסים.

7. חומת אש של מאזן עומסים

בקטע הזה נסביר איך פורסים כללים של מדיניות חומת אש שמטרגטים מאזני עומסים. רצף ההגדרות יבנה מצב אבטחה שיאפשר גישה ל-vm-allow ויחסום תעבורת נתונים של vm-deny לכל השירותים.

אפשרות לאפשר תעבורת נתונים נבחרת אל fr-foo-www

מוסיפים כלל חדש למדיניות חומת האש הקיימת fw-policy-foo-${REGION_1}

  • מתן גישה לטווח כתובות IP של מקור שכולל את כתובות ה-IP vm-allow ומחריג את כתובות ה-IP vm-deny
  • מוסיפים עוד מסנן מקור INTRA_VPC כדי להשתמש בסוג הרשת בכלל של מדיניות חומת האש שמכוון למאזן העומסים

סוג הרשת של המקורות INTRA_VPC ו-VPC_NETWORKS נתמך בכללים של מדיניות חומת האש שמטרגטים מאזני עומסים כשמשתמשים בו בשילוב עם פרמטר מקור אחר. לוגיקת ההערכה היא AND בין שני פרמטרים של מקורות. כדי לאפשר את תעבורת הנתונים, היא צריכה לעמוד בקריטריונים של INTRA_VPC וגם --src-ip-ranges=${VM_ALLOW_IP}/32.

יצירת כלל כדי לאפשר טירגוט של vm-allow fr-foo-www

# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2001 \
  --description="allow vm traffic to fr-www" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --enable-logging \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp \
  --src-network-type=INTRA_VPC \
  --src-ip-ranges=${VM_ALLOW_IP}/32 \
  --target-type=INTERNAL_MANAGED_LB \
  --target-forwarding-rules=projects/${PROJECT_ID}/regions/${REGION_1}/forwardingRules/fr-foo-www

בדיקה מלקוח vm-allow

# send request to foo www service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  curl -s www.foo.com"

בדיקה מלקוח vm-deny

# send request to foo www service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s www.foo.com"

הערה: הפעולה הזו מצליחה כי התנהגות ברירת המחדל המשתמעת של כלל מדיניות חומת האש למאזני עומסים היא --action=allow. כדי לשנות את זה, צריך כלל ברירת מחדל (catchall) של דחייה.

דחיית תנועה שמוגדרת כברירת מחדל אל fr-foo-www

מוסיפים כלל חדש למדיניות חומת האש עם עדיפות נמוכה יותר (מספר גבוה יותר).

  • דחיית כל התנועה מכל כתובת IP של מקור
  • תעבורת נתונים מ-vm-allow אל fr-foo-www תאושר לפני שהיא תגיע לכלל הדחייה

יצירת כלל לדחיית טירגוט תנועה fr-foo-www

# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2999 \
  --description="allow vm traffic to fr-www" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --enable-logging \
  --action=deny \
  --direction=INGRESS \
  --layer4-configs=tcp \
  --src-ip-ranges=0.0.0.0/0 \
  --target-type=INTERNAL_MANAGED_LB \
  --target-forwarding-rules=projects/${PROJECT_ID}/regions/${REGION_1}/forwardingRules/fr-foo-www

שיקולים לגבי בדיקות תקינות

בדומה לכללים של מדיניות חומת אש שמכוונים למכונות וירטואליות, כלל ברירת המחדל (המשתמע) שמונע תעבורת נתונים נכנסת (ingress) חוסם תעבורת נתונים שמגיעה מטווחים של בדיקות תקינות ומיועדת לשרתים עורפיים של מאזן העומסים. לכן הוגדר כלל הרשאה מפורש כדי לאפשר טווחי בדיקה של בדיקת תקינות של תעבורת נתונים נכנסת (ראו כלל 1002).

חשוב: באופן דומה, כשיוצרים כלל דחייה (מפורש) כללי לתעבורת נתונים נכנסת (ingress) עבור יעדים של מאזן עומסים, צריך ליצור כלל נוסף בעדיפות גבוהה יותר (מספר עדיפות נמוך יותר) כדי לאפשר תעבורת נתונים נכנסת (ingress) מטווח בקשה לבדיקת תקינות (probe). צריך לכוון את הכלל הזה למאזני העומסים.

# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2002 \
  --description="allow health checks to fr-www" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp \
  --src-address-groups=projects/${PROJECT_ID}/locations/${REGION_1}/addressGroups/uhc-probes \
  --target-type=INTERNAL_MANAGED_LB \
  --target-forwarding-rules=projects/${PROJECT_ID}/regions/${REGION_1}/forwardingRules/fr-foo-www

בדיקה מלקוח vm-deny

# send request to foo www service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s www.foo.com"

הפעולה הזו אמורה להיכשל עכשיו כי כלל חומת האש 2999 דוחה את כל תעבורת הנתונים שמגיעה מרשת ה-VPC. הכלל 2001 בעדיפות הגבוהה יותר (מספר עדיפות נמוך יותר) אפשר רק טווח מקור שכולל את vm-allow.

מפסיקים את התהליך של curl על ידי לחיצה על Ctrl+C.

# send request to foo api service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s api.foo.com:8080"

ל-vm-deny עדיין יש גישה לשירות ה-API. הפעולה הצליחה כי כלל חומת האש הוחל באופן ספציפי רק על כלל ההעברה fr-foo-www ולא על fr-foo-api.

עדכון הכללים כך שיטרגטו את כל מאזני העומסים

הערה: אפשר להחיל כללים של מדיניות חומת אש על כל מאזני העומסים ברשת VPC על ידי השמטת --target-forwarding-rules=FR_NAME.

משנים את הכללים במדיניות חומת האש כך שיחולו עכשיו על כל יעדי כללי ההעברה של מאזן העומסים ברשת ה-VPC.

  1. יוצרים כלל חדש של תעבורת נתונים נכנסת (ingress) allow2003 שמטרגט את כל כללי ההעברה כדי לאפשר תעבורת נתונים של מכונות וירטואליות (טווח כתובות ה-IP‏ vm-allow)
  2. יוצרים כלל חדש של תעבורת נתונים נכנסת (ingress) מסוג allow2004 שמטרגט את כל כללי ההעברה כדי לאפשר תעבורת נתונים של בדיקות תקינות (קבוצת כתובות uhc-probes).
  3. יצירת כלל חדש של דחייה לתעבורת נתונים נכנסת (ingress) 2998 שמכוון לכל כללי ההעברה כדחייה כללית לכל שאר התעבורה

שינוי כללים של חומת אש כדי לטרגט את כל מאזני העומסים

# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2003 \
  --description="allow vm traffic to all vnet lb fr" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --enable-logging \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp  \
  --src-ip-ranges=${VM_ALLOW_IP}/32 \
  --target-type=INTERNAL_MANAGED_LB
# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2004 \
  --description="allow health checks to all vnet lb fr" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --enable-logging \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp \
  --src-address-groups=projects/${PROJECT_ID}/locations/${REGION_1}/addressGroups/uhc-probes \
  --target-type=INTERNAL_MANAGED_LB
# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2998 \
  --description="deny all vnet traffic to all vnet lb fr" \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1} \
  --enable-logging \
  --action=deny \
  --direction=INGRESS \
  --layer4-configs=tcp \
  --src-ip-ranges=0.0.0.0/0 \
  --target-type=INTERNAL_MANAGED_LB

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

# delete redundant fw policy rules
gcloud beta compute network-firewall-policies rules delete 2001 \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1}

gcloud beta compute network-firewall-policies rules delete 2002 \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1}

gcloud beta compute network-firewall-policies rules delete 2999 \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1}

בדיקה מלקוח vm-deny

# send request to foo api service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s api.foo.com:8080"

הפעולה הזו אמורה להיכשל עכשיו כי fr-foo-api מטוגרט גם על ידי כל כללי מדיניות חומת האש עם --target-type=INTERNAL_MANAGED_LB.

מפסיקים את התהליך של curl על ידי לחיצה על Ctrl+C.

בודקים את ההורדה של קובץ מ-Google Cloud Storage דרך מאזן העומסים.

# send request to foo gcs service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  TOKEN=\$(gcloud auth print-access-token)
  curl -s -k \"https://gcs.foo.com/storage/v1/b/${BUCKET}/o/test-upload-object.txt?alt=media\" \
  -H \"Authorization: Bearer \${TOKEN}\" \
  -o test-download.txt"

מפסיקים את התהליך של curl על ידי לחיצה על Ctrl+C.

בדיקה מלקוח vm-allow

# send request to foo www service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  curl -s www.foo.com"
# send request to foo api service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  curl -s api.foo.com:8080"
# send request to foo gcs service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  TOKEN=\$(gcloud auth print-access-token)
  curl -s -k \"https://gcs.foo.com/storage/v1/b/${BUCKET}/o/test-upload-object-1.txt?alt=media\" \
  -H \"Authorization: Bearer \${TOKEN}\" \
  -o test-download-1.txt"

אימות תוכן ההורדה

# send request from vm
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  cat test-download-1.txt"

כל שירותי איזון העומסים זמינים ל-vm-allow ונחסמים בהצלחה ל-vm-deny.

כאן מסתיים החלק של הבדיקה... עכשיו נסביר בקצרה על רישום ביומן.

8. רישום ביומן של כללי חומת אש

פורמט יומן חומת האש כולל שדות ורשומות של כללים שמיועדים למאזני עומסים (--target-type=INTERNAL_MANAGED_LB).

היומנים יכללו שדה נוסף עם התווית load_balancer_details ומידע נוסף על מאזן העומסים שאליו כוון כלל מדיניות חומת האש. זה דומה לפורמט השדה InstanceDetails כשמכונות וירטואליות הן היעד בכללים של מדיניות חומת האש.

  • load_balancer_details.forwarding_rule_name מציג את כלל ההעברה של היעד של כלל מדיניות חומת האש
  • load_balancer_details.type מציין את הטעם של מאזן העומסים מבוסס ה-proxy שאליו מכוונים
  • load_balancer_details.url_map_name מתעד את משאב מפת ה-URL שנעשה בו שימוש כשסוג המאזן הוא מאזן עומסים של אפליקציה

צפייה ביומנים

מריצים שאילתה ביומני חומת האש כדי לראות את התוצאות של כללי מדיניות חומת האש.

gcloud logging read \
  "logName=projects/${PROJECT_ID}/logs/compute.googleapis.com%2Ffirewall \
  AND (jsonPayload.connection.src_ip=\"${VM_ALLOW_IP}\" OR jsonPayload.connection.src_ip=\"${VM_DENY_IP}\")" \
  --project=${PROJECT_ID} \
  --freshness=30m \
  --limit=50 \
  --format="table(
    timestamp:label=TIMESTAMP,
    jsonPayload.connection.src_ip:label=SRC_IP,
    jsonPayload.connection.src_port:label=SRC_PORT,
    jsonPayload.connection.dest_ip:label=DEST_IP,
    jsonPayload.connection.dest_port:label=DEST_PORT,
    jsonPayload.disposition:label=ACTION,
    jsonPayload.rule_details.priority:label=PRIORITY,
    jsonPayload.load_balancer_details.forwarding_rule_name:label=FWD_RULE
  )"

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

  • הכלל 2011 מאפשר את כל התנועה של vm-allow לכל מאזני העומסים
  • הכלל 2998 דוחה את כל התנועה שמיועדת למאזני עומסים
TIMESTAMP                       SRC_IP     SRC_PORT  DEST_IP     DEST_PORT  ACTION   PRIORITY  FWD_RULE
YYYY-MM-DDTHH:MM:SS.850967068Z  10.0.0.11  48480     10.0.0.103  443        ALLOWED  2003      fr-foo-gcs
YYYY-MM-DDTHH:MM:SS.418613380Z  10.0.0.11  37340     10.0.0.101  80         ALLOWED  2003      fr-foo-www
YYYY-MM-DDTHH:MM:SS.213234118Z  10.0.0.12  55950     10.0.0.103  443        DENIED   2998      fr-foo-gcs
YYYY-MM-DDTHH:MM:SS.981484412Z  10.0.0.11  41738     10.0.0.101  80         ALLOWED  2003      fr-foo-www
YYYY-MM-DDTHH:MM:SS.189358071Z  10.0.0.12  55950     10.0.0.103  443        DENIED   2998      fr-foo-gcs
YYYY-MM-DDTHH:MM:SS.061463883Z  10.0.0.12  55950     10.0.0.103  443        DENIED   2998      fr-foo-gcs
YYYY-MM-DDTHH:MM:SS.965498098Z  10.0.0.12  53284     10.0.0.102  8080       DENIED   2998      fr-foo-api

אפשר גם לראות את היומנים במסוף Google Cloud באמצעות Logs Explorer. עוברים אל console.cloud.google.com/logs/query ומשתמשים ביומן חומת האש הרגיל של VPC‏ compute.googleapis.com/firewall.

logName=projects/${PROJECT_ID}/logs/compute.googleapis.com%2Ffirewall

הגענו לסוף החלק של הרישום ביומן... עכשיו נעבור לניקוי.

9. הסרת המשאבים

# delete client compute resources
gcloud -q compute instances delete vm-deny --zone=${ZONE_1}

gcloud -q compute instances delete vm-allow --zone=${ZONE_1}

# next
# delete load balancer resources for gcs
gcloud -q compute forwarding-rules delete fr-foo-gcs --region=${REGION_1}

gcloud -q compute target-https-proxies delete proxy-foo-gcs --region=${REGION_1}

gcloud -q compute url-maps delete ilb-foo-gcs --region=${REGION_1}

gcloud -q compute backend-services delete bes-foo-gcs --region=${REGION_1}

gcloud -q compute addresses delete vip-foo-gcs --region=${REGION_1}

# next
# delete load balancer resources for api
gcloud -q compute forwarding-rules delete fr-foo-api --region=${REGION_1}

gcloud -q compute target-http-proxies delete proxy-foo-api --region=${REGION_1}

gcloud -q compute url-maps delete ilb-foo-api --region=${REGION_1}

gcloud -q compute backend-services delete bes-foo-api --region=${REGION_1}

gcloud -q compute health-checks delete hc-foo-api --region=${REGION_1}

gcloud -q compute addresses delete vip-foo-api --region=${REGION_1}

# next
# delete load balancer resources for www
gcloud -q compute forwarding-rules delete fr-foo-www --region=${REGION_1}

gcloud -q compute target-http-proxies delete proxy-foo-www --region=${REGION_1}

gcloud -q compute url-maps delete ilb-foo-www --region=${REGION_1}

gcloud -q compute backend-services delete bes-foo-www --region=${REGION_1}

gcloud -q compute health-checks delete hc-foo-www --region=${REGION_1}

gcloud -q compute addresses delete vip-foo-www --region=${REGION_1}

# next
# delete service backend resources
gcloud -q storage rm --recursive gs://${BUCKET}

gcloud -q certificate-manager certificates delete cert-foo-gcs --location=${REGION_1}

gcloud -q compute network-endpoint-groups delete neg-psc-gcs --region=${REGION_1}

gcloud -q compute instance-groups managed delete mig-foo --region=${REGION_1}

gcloud -q compute instance-templates delete mig-template-foo --global

# next
# delete dns, nat, fw resources
gcloud -q dns record-sets delete gcs.foo.com --type=A --zone=zone-foo

gcloud -q dns record-sets delete api.foo.com --type=A --zone=zone-foo

gcloud -q dns record-sets delete www.foo.com --type=A --zone=zone-foo

gcloud -q dns managed-zones delete zone-foo

gcloud -q compute routers delete cr-nat-foo --region=${REGION_1}

gcloud -q compute network-firewall-policies associations delete \
  --firewall-policy=fw-policy-foo-${REGION_1} \
  --name=fw-policy-association-foo-${REGION_1} \
  --firewall-policy-region=${REGION_1}

gcloud -q compute network-firewall-policies delete fw-policy-foo-${REGION_1} --region=${REGION_1}

gcloud -q network-security address-groups delete uhc-probes --location=${REGION_1}

# next
# delete network resources
gcloud -q compute networks subnets delete subnet-foo-3 --region=${REGION_1}

gcloud -q compute networks subnets delete subnet-foo-2 --region=${REGION_1}

gcloud -q compute networks subnets delete subnet-foo-1 --region=${REGION_1}

gcloud -q compute networks delete vnet-foo

# next
# delete shell variables and local files
unset PROJECT_ID REGION_1 ZONE_1 VM_ALLOW_IP VM_DENY_IP BUCKET

rm vm-server-startup.sh create_lbs.sh foo-gcs-key.pem foo-gcs-cert.pem

# end

10. סיכום

מעולה! הצלחתם להגדיר את Cloud NGFW Essentials למאזני עומסים.

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

תודה!