App Engine 服務的傳出 IP 位址

網址擷取、Sockets 和 Mail API 等傳出服務會運用大型的 IP 位址集區。這個集區中的 IP 位址範圍可能會進行例行性的變動。事實上,連續兩個來自相同應用程式的 API 呼叫看起來可能像是從不同 IP 位址發出。

您可以根據 Google 發布的 IP 範圍資訊,找出 App Engine 服務目前的 IP 位址範圍:

  • Google 在網際網路中公布了一份 IP 範圍完整清單,並以 goog.json 的格式發布。

  • 此外,Google 也以 cloud.json 的格式發布了另一份清單,當中列出了客戶可在全球和特定區域內使用的外部 IP 位址範圍。 Google Cloud

Google API 和服務使用的 IP 位址,符合從 goog.json 中移除 cloud.json 所有範圍後計算出的範圍清單。這些清單會經常更新。

您可以使用下列 Python 指令碼,建立包含 Google API 和服務所用 IP 位址範圍的清單。

如要瞭解如何執行這項指令碼,請參閱「如何執行」。

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()