כתובות IP של דואר יוצא לשירותי App Engine

כברירת מחדל, שירותים יוצאים בסביבת ברירת המחדל ב-App Engine, כמו URL Fetch, ‏Sockets ו-Mail API, משתמשים במאגר אזורי של כתובות IP דינמיות שמשותפות לכל עומסי העבודה ללא שרת (serverless). טווחי כתובות ה-IP במאגר הזה משתנים באופן קבוע, כך ששתי קריאות עוקבות מאותה אפליקציה יכולות להגיע מכתובות IP שונות.

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

  • אתם מתחברים למסד נתונים חיצוני או ל-API שמשתמש ברשימת היתרים של כתובות IP או בחומת אש.
  • אתם מתחברים לנקודות קצה חיצוניות שרגישות למוניטין, כמו שערי תשלום, מסדי נתונים שמתארחים או ממשקי API של שותפים שמוגנים על ידי חומות אש של צד שלישי ליישומי אינטרנט (WAF). תעבורת נתונים רועשת מדייר אחר במאגר כתובות ה-IP המשותף שמוגדר כברירת מחדל עלולה לפגוע במוניטין של כתובת ה-IP, ולגרום ל-WAF חיצוניים לחסום או להגביל את הבקשות שלכם.
  • אתם מריצים עומסי עבודה של סריקת רשת מורשית, ספירת יציאות, טביעת אצבע של מארח, בדיקת פגיעויות, גירוד נתונים מהאינטרנט או בדיקת עומסים.

אם אתם צריכים רק לחפש את טווחי כתובות ה-IP שמשויכים לתנועה יוצאת כברירת מחדל מהשירות שלכם, אתם יכולים למצוא את טווחי כתובות ה-IP הנוכחיים שכוללים את כתובות ה-IP של App Engine.

כתובות IP לשירותי App Engine

כדי למצוא את טווחי כתובות ה-IP הנוכחיים של שירותי App Engine, אפשר להשתמש בשני קובצי JSON ש-Google מפרסמת:

  • ‫Google מפרסמת רשימה של כתובות IP שבבעלותה בקובץ goog.json.

  • ‫Google גם מפרסמת ב-cloud.json רשימה של טווחי כתובות IP חיצוניות גלובליות ואזוריות שזמינות למשאבי Google Cloud של הלקוחות.

אם מסירים את כל הטווחים ב-cloud.json מאלה שב-goog.json, מקבלים קבוצה גדולה של כתובות IP שמשמשות את Google APIs הגלובליים ושירותים אחרים של Google, כולל מוצרים שפונים ללקוחות מחוץ ל- Google Cloud. הרשימות האלה מתעדכנות לעיתים קרובות.

אתם יכולים להשתמש בסקריפט הבא של Python כדי ליצור רשימה של טווחי כתובות IP, כולל אלה שמשמשים את השירותים וממשקי ה-API של Google.

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

from __future__ import print_function

import json

try:
    from urllib import urlopen
except ImportError:
    from urllib.request import urlopen
    from urllib.error import HTTPError

import netaddr

IPRANGE_URLS = {
    "goog": "https://www.gstatic.com/ipranges/goog.json",
    "cloud": "https://www.gstatic.com/ipranges/cloud.json",
}


def read_url(url):
    try:
        return json.loads(urlopen(url).read())
    except (IOError, HTTPError):
        print("ERROR: Invalid HTTP response from %s" % url)
    except json.decoder.JSONDecodeError:
        print("ERROR: Could not parse HTTP response from %s" % url)


def get_data(link):
    data = read_url(link)
    if data:
        print("{} published: {}".format(link, data.get("creationTime")))
        cidrs = netaddr.IPSet()
        for e in data["prefixes"]:
            if "ipv4Prefix" in e:
                cidrs.add(e.get("ipv4Prefix"))
            if "ipv6Prefix" in e:
                cidrs.add(e.get("ipv6Prefix"))
        return cidrs


def main():
    cidrs = {group: get_data(link) for group, link in IPRANGE_URLS.items()}
    if len(cidrs) != 2:
        raise ValueError("ERROR: Could process data from Google")
    print("IP ranges for Google APIs and services default domains:")
    for ip in (cidrs["goog"] - cidrs["cloud"]).iter_cidrs():
        print(ip)


if __name__ == "__main__":
    main()

הגדרה של כתובת IP סטטית לשיחות יוצאות

כדי להגדיר כתובת IP סטטית לשירות בסביבה הרגילה של App Engine, צריך לנתב את תעבורת הנתונים היוצאת לרשת של ענן וירטואלי פרטי (VPC) באמצעות תעבורת נתונים יוצאת ישירה של VPC או גישה ל-VPC ללא שרת (serverless) עם Cloud Router ו-Cloud NAT. הוספת שער Cloud NAT לרשת ה-VPC מנתבת את תעבורת הנתונים היוצאת של App Engine דרך כתובת ה-IP הסטטית השמורה.

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

ניתוב התנועה דרך Cloud NAT לא מוסיף עוד דילוג במקבץ הרשת (network stack), כי שער Cloud NAT ו-Cloud Router מספקים רק מישור בקרה, והחבילות לא עוברות דרך שער Cloud NAT או Cloud Router.

כך מגדירים כתובת IP סטטית לתעבורה יוצאת בשירות של סביבת ברירת המחדל ב-App Engine:

  1. מוודאים שיש לכם את התפקיד roles/compute.networkAdmin או תפקיד בהתאמה אישית עם אותן הרשאות.

  2. יוצרים רשת משנה (subnet) בתוך רשת ה-VPC לתנועה של App Engine. כך משאבים אחרים ברשת ה-VPC לא יוכלו להשתמש בכתובת ה-IP הסטטית.

    gcloud compute networks subnets create SUBNET_NAME \
        --range=RANGE \
        --network=NETWORK_NAME \
        --region=REGION

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫SUBNET_NAME: שם לתת-הרשת.
    • ‫RANGE: טווח ה-IP בפורמט CIDR שרוצים להקצות לרשת המשנה הזו (לדוגמה, 10.124.0.0/28). לתעבורת נתונים יוצאת ישירה ב-VPC נדרש טווח של /26 או יותר. למחבר של חיבור לרשת VPC ללא שרת נדרש טווח /28.
    • ‫NETWORK_NAME: השם של רשת ה-VPC
    • ‫REGION: האזור של שירות App Engine.
  3. מחברים את שירות App Engine לרשת המשנה באחת מהדרכים הבאות:

    • תעבורת נתונים יוצאת ישירה של VPC: פועלים לפי השלבים להגדרת תעבורת נתונים יוצאת ישירה של VPC, ומציינים את שם רשת המשנה שיצרתם בשלב הקודם בשדה subnet.
    • מחבר של גישה ל-VPC ללא שרת: פועלים לפי השלבים להתחברות לרשת VPC, ומציינים את השם של רשת המשנה שיצרתם בשלב הקודם בתור רשת המשנה של המחבר.
  4. יוצרים Cloud Router חדש. ‫Cloud Router הוא רכיב חיוני במישור הבקרה של Cloud NAT.

    gcloud compute routers create ROUTER_NAME \
        --network=NETWORK_NAME \
        --region=REGION

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫ROUTER_NAME: שם למשאב Cloud Router שרוצים ליצור.
    • ‫NETWORK_NAME: השם של רשת ה-VPC
    • ‫REGION: האזור שבו רוצים ליצור שער NAT.
  5. שמירת כתובת IP סטטית.

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

    gcloud compute addresses create ORIGIN_IP_NAME \
        --region=REGION

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫ORIGIN_IP_NAME: השם שרוצים להקצות למשאב של כתובת ה-IP.
    • ‫REGION: האזור שבו יופעל הנתב של Cloud NAT. כדי לצמצם את זמן האחזור ואת עלויות הרשת, מומלץ להשתמש באותו אזור שבו נמצא שירות App Engine.

    משתמשים בפקודה compute addresses describe כדי לראות את התוצאה:

    gcloud compute addresses describe ORIGIN_IP_NAME
  6. יוצרים שער Cloud NAT ומציינים את כתובת ה-IP.

    תעבורת הנתונים שמגיעה מתת-הרשת תעבור דרך השער הזה ותשתמש בכתובת ה-IP הסטטית ששמרתם בשלב הקודם.

    gcloud compute routers nats create NAT_NAME \
        --router=ROUTER_NAME \
        --region=REGION \
        --nat-custom-subnet-ip-ranges=SUBNET_NAME \
        --nat-external-ip-pool=ORIGIN_IP_NAME
      

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫NAT_NAME: שם למשאב של שער Cloud NAT שרוצים ליצור.
    • ‫ROUTER_NAME: השם של Cloud Router.
    • ‫REGION: האזור שבו רוצים ליצור שער NAT.
    • ‫ORIGIN_IP_NAME: השם של משאב כתובת ה-IP השמורה שיצרתם בשלב הקודם.
  7. מגדירים את ההגדרה של תעבורת הנתונים היוצאת ל-all-traffic.

    כברירת מחדל, שירותי App Engine שולחים רק תנועה פנימית לרשת ה-VPC. כדי לשלוח תעבורת נתונים עם יעדים חיצוניים דרך רשת VPC, כך שהיא תשתמש בכתובת ה-IP הסטטית שציינתם, צריך לשנות את הגדרת תעבורת הנתונים היוצאת (egress).

    מציינים את הגדרת תעבורת הנתונים היוצאת בקובץ app.yaml של השירות.

    אם אתם משתמשים ב-Direct VPC egress, הגדירו את vpc_egress לערך all-traffic:

    vpc_access:
    network_interface:
    network: NETWORK_NAME
    subnet: SUBNET_NAME
    vpc_egress: all-traffic

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫NETWORK_NAME: השם של רשת ה-VPC
    • ‫SUBNET_NAME: השם של רשת המשנה שיצרתם.

    אם אתם משתמשים במחבר של חיבור לרשת (VPC) מאפליקציית serverless, צריך להגדיר את הגדרת תעבורת הנתונים היוצאת ל-all-traffic:

    vpc_access_connector:
    name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR_NAME
    egress_setting: all-traffic

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • ‫REGION: האזור שבו נמצא המחבר.
    • ‫CONNECTOR_NAME: השם של המחבר.
  8. פורסים את השירות:

    gcloud app deploy