Uncover the Mystery of Your AWS IP Addresses

A Guide with Boto3

Get ready to embark on a thrilling journey of automation and discovery! I had the vision of creating a dynamic system that would effortlessly uncover all the private and public IP addresses in my environment. Not only that, but I also wanted to make this information accessible to my team through an internal website.

With Python as my tool of choice, I delved into the world of programming to bring my vision to life.

We’ll start by obtaining all the ENIs, then use that information to uncover the private IP addresses associated with them. But we won’t stop there, we’ll also hunt down any public IP addresses linked to the ENIs.

And the adventure doesn’t end there, we’re taking it to the next level by conducting this search across all regions offered by AWS!

But wait, there’s more! If you, like me, have multiple AWS profiles, we can add a cherry on top by allowing you to input the desired profile to run the query against. Get ready to conquer the world of IP addresses like never before!

Prerequisites

  • AWS CLI (click here for CLI installations)
  • AWS IAM programmatic credentials and necessary permissions
  • Python (version 3 is recommended)
  • PIP (version 3 is recommended)
  • Boto (version 3 is recommended)
  • IDE (I use PyCharm)

Code (with comments)

#Importing libraries: The first three lines of the code import the os, boto3, and csv libraries.
import os
import boto3
import csv

#Defining the function get_all_enis_with_ips: This function takes one argument, profile_name, which is the name of an AWS profile stored in the user's computer.
def get_all_enis_with_ips(profile_name):
    os.environ['AWS_PROFILE'] = profile_name #Setting the AWS profile: The os.environ['AWS_PROFILE'] line sets the environment variable AWS_PROFILE to the value of profile_name.
    client = boto3.client('ec2') #Creating a boto3 EC2 client: The line client = boto3.client('ec2') creates a boto3 client for Amazon Elastic Compute Cloud (EC2) using the default region.
    ec2_regions = [region['RegionName'] for region in client.describe_regions()['Regions']] #Getting a list of EC2 regions: The line ec2_regions = [region['RegionName'] for region in client.describe_regions()['Regions']] gets a list of EC2 regions.

    eni_info = {} #Initializing a dictionary for ENI information: The line eni_info = {} creates an empty dictionary eni_info to store information about ENIs.
    for region in ec2_regions: #Creating a boto3 EC2 client for the region: The line client = boto3.client('ec2', region_name=region) creates a boto3 client for EC2 for the current region.
        try: #Error handling: The code uses a try-except block to handle errors that may occur when calling the describe_network_interfaces method. If an error occurs (such as GuardRails or SCPs or other policies that deny regional access), the code prints an error message and continues to the next region.
            client = boto3.client('ec2', region_name=region)
            enis = client.describe_network_interfaces()['NetworkInterfaces'] #Getting ENI information: The line enis = client.describe_network_interfaces()['NetworkInterfaces'] uses the describe_network_interfaces method of the boto3 client to get information about all ENIs in the region.
            eni_info[region] = []
            for eni in enis: #Storing ENI information: The code uses a nested for loop to iterate through each ENI in the region. For each ENI, the code creates a dictionary eni_dict that contains information about the ENI's private IP addresses and public IP. The code appends this dictionary to a list of ENIs for the region, which is stored in the eni_info dictionary.
                eni_dict = {}
                eni_dict['PrivateIpAddresses'] = [private_ip['PrivateIpAddress'] for private_ip in
                                                  eni['PrivateIpAddresses']]
                eni_dict['PublicIp'] = eni.get('Association', {}).get('PublicIp', '')
                eni_info[region].append(eni_dict)
            return eni_info
        except Exception as e:
        # If an error occurs, print the error message and continue to the next region
            print("Error in region", region, ":", e)
            continue

profile_name = input("Enter AWS profile name: ") #Getting the AWS profile name: The line profile_name = input("Enter AWS profile name: ") prompts the user to enter the name of an AWS profile.
eni_info = get_all_enis_with_ips(profile_name) #Getting ENI information: The line eni_info = get_all_enis_with_ips(profile_name) calls the get_all_enis_with_ips function, passing profile_name as an argument, to get information about ENIs.

with open('c:\\users\\arun.daniel\\eni_info.csv', 'w', newline='') as file: #Writing ENI information to a CSV file: The code uses a with statement to open a file named eni_info.csv in the specified
    writer = csv.writer(file)
    writer.writerow(['Region', 'Private IP Addresses', 'Public IP'])
    for region, enis in eni_info.items():
        for eni in enis:
            writer.writerow([region, ','.join(eni['PrivateIpAddresses']), eni['PublicIp']])

Code (Raw)

import os
import boto3
import csv

def get_all_enis_with_ips(profile_name):
    os.environ['AWS_PROFILE'] = profile_name
    client = boto3.client('ec2')
    ec2_regions = [region['RegionName'] for region in client.describe_regions()['Regions']]

    eni_info = {}
    for region in ec2_regions:
        try:
            client = boto3.client('ec2', region_name=region)
            enis = client.describe_network_interfaces()['NetworkInterfaces']
            eni_info[region] = []
            for eni in enis:
                eni_dict = {}
                eni_dict['PrivateIpAddresses'] = [private_ip['PrivateIpAddress'] for private_ip in
                                                  eni['PrivateIpAddresses']]
                eni_dict['PublicIp'] = eni.get('Association', {}).get('PublicIp', '')
                eni_info[region].append(eni_dict)
            return eni_info
        except Exception as e:
            print("Error in region", region, ":", e)
            continue

profile_name = input("Enter AWS profile name: ")
eni_info = get_all_enis_with_ips(profile_name)

with open('c:\\users\\arudani\\eni_info.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(['Region', 'Private IP Addresses', 'Public IP'])
    for region, enis in eni_info.items():
        for eni in enis:
            writer.writerow([region, ','.join(eni['PrivateIpAddresses']), eni['PublicIp']])

Leave a Comment

Your email address will not be published. Required fields are marked *