Endereços IP de saída para serviços do App Engine

Os serviços de saída, como as APIs URL Fetch, Sockets e Mail, utilizam um grande pool de endereços IP. Os intervalos de endereços IP nesse conjunto estão sujeitos a alterações de rotina. Na verdade, duas chamadas de API sequenciais do mesmo aplicativo podem parecer originadas de dois endereços IP diferentes.

É possível encontrar os intervalos de endereços IP atuais dos serviços do App Engine usando dois arquivos JSON publicados pelo Google:

  • O Google publica uma lista de endereços IP de propriedade do Google em goog.json.

  • O Google também publica uma lista de intervalos de endereços IP externo globais e regionais disponíveis para os recursos do Google Cloud dos clientes em cloud.json.

Remover todos os intervalos em cloud.json daqueles em goog.json resulta em um grande conjunto de endereços IP usados pelas APIs globais do Google e outros serviços do Google, incluindo produtos voltados ao cliente fora de Google Cloud. Essas listas são atualizadas com frequência.

É possível usar o script Python a seguir para criar uma lista de intervalos de endereços IP que incluem aqueles usados pelas APIs e serviços do Google.

Para mais informações sobre como executar esse script, consulte Como executar.

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