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 com base nas informações de intervalos de IP que o Google publica:

  • O Google publica a lista completa de intervalos de IP que disponibiliza para usuários na Internet em goog.json.

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

Os endereços IP usados pelas APIs e serviços do Google se encaixam na lista de intervalos calculados removendo todos os intervalos em cloud.json daqueles em goog.json. 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()