Outbound IP addresses for App Engine services

Outbound services, such as the URL Fetch, Sockets, and Mail APIs, make use of a large pool of IP addresses. The IP address ranges in this pool are subject to routine changes. In fact, two sequential API calls from the same application may appear to originate from two different IP addresses.

You can find the current IP address ranges for App Engine services by using two json files that are published by Google:

  • Google publishes a list of Google-owned IP addresses in goog.json .

  • Google also publishes a list of global and regional external IP addresses ranges available for customers' Google Cloud resources in cloud.json .

Taking away all ranges in cloud.json from those in goog.json results in a large set of IP addresses that are used by global Google APIs and other Google services, including customer-facing products outside of Google Cloud. These lists are updated frequently.

You can use the following Python script to create a list of IP address ranges that include those used by Google APIs and services.

For information about running this script, see How to run .

  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 
 () 
 
Design a Mobile Site
View Site in Mobile | Classic
Share by: