Viewing the list of IP address ranges for AmazonAWS

If you need to create firewall rules for outgoing connectivity to Amazon Web Services (AWS) addresses, you can obtain a complete listing of the IP address ranges that Amazon uses in JavaScript Object Notation (JSON) format from AWS IP Ranges Are Now Available in JSON Format - the download URL for the file is https://ip-ranges.amazonaws.com/ip-ranges.json

I downloaded the IP address range file from https://ip-ranges.amazonaws.com/ip-ranges.json using cURL, which is present on Apple OS X/macOS systems and is available for Linux and many other operating systems, including Microsoft Windows - see Releases and Downloads.

$ curl -o ip-ranges.json https://ip-ranges.amazonaws.com/ip-ranges.json
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   99k  100   99k    0     0   191k      0 --:--:-- --:--:-- --:--:--  191k
$

The following Python script can be used to extract just the Classless Inter-Domain Routing (CIDR) address blocks, i.e., the ip_prefix information from the JSON data stored in the ip-ranges.json file downloaded from the Amazon website and display it.

#!/usr/bin/python
import json

data = json.load(open('ip-ranges.json'))
for d in data["prefixes"]:
    print d["ip_prefix"]

The output from the script to display just the CIDR output would be similar to the following output (current as of 2017-02-21):

Python by Example
Python by Example
1x1 px



Learn Cloud Computing With AWS
Learn Cloud Computing With AWS
1x1 px

$ python ./aws_ip_cidr.py
13.32.0.0/15
13.54.0.0/15
13.56.0.0/16
13.112.0.0/14
13.124.0.0/16
23.20.0.0/14
27.0.0.0/22
34.192.0.0/12
34.208.0.0/12
34.224.0.0/12
34.248.0.0/13
35.154.0.0/16
35.156.0.0/14
35.160.0.0/13
35.176.0.0/15
43.250.192.0/24
43.250.193.0/24
46.51.128.0/18
46.51.192.0/20
46.51.216.0/21
46.51.224.0/19
46.137.0.0/17
46.137.128.0/18
46.137.192.0/19
46.137.224.0/19
50.16.0.0/15
50.18.0.0/16

The following Python script, aws_ip_ranges.py, though, can be used to extract the JSON data and put it into a more readable format showing the ip_prefix, region, and service data.

Udemy - April2516-25off-sitewide120x600

#!/usr/bin/python

# Name: aws_ip_ranges
# Written by: Jim Cameron
# Created: 2017-02-21
# Last updated: 2017-02-21
# Version: 1.0
#
# Purpose: Parse a JSON file downloaded from 
# https://ip-ranges.amazonaws.com/ip-ranges.json that contains a list of the
# IP address ranges used by Amazon Web Services (AWS). See
# http://support.moonpoint.com/languages/python/aws for example output.

import getopt, json, os.path, urllib2, sys

inputfile = ""

# Print usage information
def usage():
   print 'Usage: aws_ip_ranges [-hd] [-i inputfile]'
   print
   print '-h --help                print this message'
   print '-d --download            download the current JSON data from Amazon'
   print '-i, --input input_file   use input file'

# Download current JSON data from Amazon
def downloadJSONdata():

    url = "https://ip-ranges.amazonaws.com/ip-ranges.json"
    outfile = "ip-ranges.json"
    page = urllib2.urlopen(url)
    source=page.read()
    f=open(outfile, 'w')
    f.write(source)
    f.close()

try:
    opts, args = getopt.getopt(sys.argv[1:], "hdi:", ["help","download","input="])
except getopt.GetoptError as err:
    # print help information and exit
    print str(err)
    usage()
    sys.exit(2)

for o, a in opts:
    if o in ('-h', '--help'):
       usage()
       sys.exit()
    elif o in ('-d', '--download'):
       downloadJSONdata()
    elif o in ('-i', '--input'):
         inputfile = a
    else:
         assert False, "unhandled option"

# if the input file isn't specified assume it is a file named ip-ranges.json
# in the current directory
if not inputfile:
   inputfile = 'ip-ranges.json'
if not os.path.isfile(inputfile):
   print "Input file ", inputfile, "not found"
   print "Use", sys.argv[0], "-d or --download to download ip-ranges.json"
   sys.exit(2)
else: 
    data = json.load(open(inputfile))

# Print the data left-justified in 3 columns of 20 characters in length
print "IP Prefix".ljust(20) + "Region".ljust(20) + "Service".ljust(20)
for d in data["prefixes"]:
    print d["ip_prefix"].ljust(20) + d["region"].ljust(20) + d["service"].ljust(20)

The script can be run with the command python ../aws_ip_ranges.py or you can make the script itself executable by changing the file permissions using the command chmod 755 aws_ip_ranges.py, which will allow it to be read and executed by any account on the system, but grants write access only to the file owner. The script can then be run with ./aws_ip_ranges.py.

If run with no options the script will assume that the ip-ranges.json file is in the current working directory and use that file. If it isn't there it will print the message below:

$ python ../aws_ip_ranges.py
Input file  ip-ranges.json not found
Use ../aws_ip_ranges.py -d or --download to download ip-ranges.json
$

You can specify an alternate location for the JSON input file with -i inputfile or --input inputfile where inputfile is the name or path/name for the file containing the Amazon JSON data.

If the script is run with the -h or --help options, it will display the usage information below:

$ python ./aws_ip_ranges.py -h
Usage: aws_ip_ranges [-hd] [-i inputfile]

-h --help                print this message
-d --download            download the current JSON data from Amazon
-i, --input input_file   use input file
$

If the -d or --download option is used, the script will download the current JSON data file from Amazon and use it.

The output data (current as of February 21, 2017) will look like the following:

IP Prefix           Region              Service             
13.32.0.0/15        GLOBAL              AMAZON              
13.54.0.0/15        ap-southeast-2      AMAZON              
13.56.0.0/16        us-west-1           AMAZON              
13.112.0.0/14       ap-northeast-1      AMAZON              
13.124.0.0/16       ap-northeast-2      AMAZON              
23.20.0.0/14        us-east-1           AMAZON              
27.0.0.0/22         ap-northeast-1      AMAZON              
34.192.0.0/12       us-east-1           AMAZON              
34.208.0.0/12       us-west-2           AMAZON              
34.224.0.0/12       us-east-1           AMAZON              
34.248.0.0/13       eu-west-1           AMAZON              
35.154.0.0/16       ap-south-1          AMAZON              
35.156.0.0/14       eu-central-1        AMAZON              
35.160.0.0/13       us-west-2           AMAZON              
35.176.0.0/15       eu-west-2           AMAZON              
43.250.192.0/24     ap-southeast-1      AMAZON              
43.250.193.0/24     ap-southeast-1      AMAZON              
46.51.128.0/18      eu-west-1           AMAZON              
46.51.192.0/20      eu-west-1           AMAZON              
46.51.216.0/21      ap-southeast-1      AMAZON              
46.51.224.0/19      ap-northeast-1      AMAZON              
46.137.0.0/17       eu-west-1           AMAZON              
46.137.128.0/18     eu-west-1           AMAZON              
46.137.192.0/19     ap-southeast-1      AMAZON              
46.137.224.0/19     ap-southeast-1      AMAZON              
50.16.0.0/15        us-east-1           AMAZON              
50.18.0.0/16        us-west-1           AMAZON              
50.19.0.0/16        us-east-1           AMAZON              
50.112.0.0/16       us-west-2           AMAZON              
52.0.0.0/15         us-east-1           AMAZON
<text snipped>
54.240.128.0/18     GLOBAL              CLOUDFRONT
204.246.164.0/22    GLOBAL              CLOUDFRONT
204.246.168.0/22    GLOBAL              CLOUDFRONT
204.246.174.0/23    GLOBAL              CLOUDFRONT
204.246.176.0/20    GLOBAL              CLOUDFRONT
205.251.192.0/19    GLOBAL              CLOUDFRONT
205.251.249.0/24    GLOBAL              CLOUDFRONT
205.251.250.0/23    GLOBAL              CLOUDFRONT
205.251.252.0/23    GLOBAL              CLOUDFRONT
205.251.254.0/24    GLOBAL              CLOUDFRONT
216.137.32.0/19     GLOBAL              CLOUDFRONT