Skip to content

Instantly share code, notes, and snippets.

@charlieda
Created November 9, 2018 17:43
Show Gist options
  • Save charlieda/9d5c0a518fbf4b127c5f3122b9251274 to your computer and use it in GitHub Desktop.
Save charlieda/9d5c0a518fbf4b127c5f3122b9251274 to your computer and use it in GitHub Desktop.
import boto3
import botocore
from time import sleep
import requests
import ipaddress
interesting_address = [
'3.0.0.3',
'3.0.0.1',
'3.0.3.0',
'3.0.3.3',
'3.0.6.0',
'3.1.1.1',
'3.1.1.3',
'3.1.3.1',
'3.1.2.1',
'3.2.2.3',
'3.3.3.3',
'3.4.5.6',
'3.2.1.0',
'3.6.9.12',
'3.45.67.89',
'3.21.0.123',
# pi 3.14159265359
'3.1.4.1',
'3.1.4.15',
'3.1.4.16',
'3.1.4.2',
'3.14.15.9',
'3.14.15.92',
'3.14.15.93',
'3.141.59.27',
'3.141.59.26',
]
def reverse(addr):
lst = [x for x in addr]
lst.reverse()
return "".join(lst)
def is_nice(addr):
digits = addr.replace(".", "")
octets = [int(x) for x in addr.split(".")]
if addr in interesting_address:
return True
# all digits the same, e.g. 3.3.3.3
if all([a == b for a in digits for b in digits]):
return True
# digits palindromic, e.g. 3.51.15.3
if list(digits) == list(reversed(digits)):
return True
# octets palindromic, e.g. 3.14.14.3
if octets[0] == octets[3] and octets[1] == octets[2]:
return True
# x.x.y.y, e.g. 3.3.4.4
if octets[0] == octets[1] and octets[2] == octets[3]:
return True
# ascending or descending by 1 or 2, e.g. 3.4.5.6
for i in range(-2, 3):
if octets[3] == octets[2] + i \
and octets[2] == octets[1] + i and \
octets[1] == octets[0] + i:
return True
return False
def allocate_ip(client, tries=1):
# Exponential backoff would be better implemented as a function decorator,
# but it's good enough to copy paste for this small script
try:
resp = ec2.allocate_address(Domain='vpc')
return resp['AllocationId'], resp['PublicIp']
except botocore.exceptions.ClientError as e:
if tries > 10:
raise e
else:
print("Backoff for allocating (try {} of 10): {}".format(tries, str(e)))
sleep(2 ** tries)
return allocate_ip(client, tries=tries+1)
def deallocate_ip(client, eip, tries=1):
try:
return ec2.release_address(AllocationId=eip)
except botocore.exceptions.ClientError as e:
if tries > 10:
raise e
else:
print("Backoff for deallocate (try {} of 10): {}".format(tries, str(e)))
sleep(2 ** tries)
return allocate_ip(client, tries=tries+1)
potential_regions = []
address_range = requests.get("https://ip-ranges.amazonaws.com/ip-ranges.json").json()['prefixes']
interesing = [ipaddress.IPv4Address(unicode(addr)) for addr in interesting_address]
for ip_range in address_range:
network = ipaddress.IPv4Network(ip_range['ip_prefix'])
contained = [ip for ip in interesing if ip in network]
if len(contained) > 0:
print("Found IPs {} in network {} (region={}, usage={})".format(
str(contained),
ip_range['ip_prefix'],
ip_range['region'],
ip_range['service']),
)
if ip_range['service'] == 'EC2':
print("\tSome addresses may be allocatable! Adding as region")
potential_regions += [ip_range['region']]
if len(potential_regions) > 0:
print("Found {} Regions".format(len(potential_regions)))
else:
print("No regions found, exiting...")
assert False
ec2 = boto3.client('ec2', region_name=potential_regions[0])
found_ips = []
while True:
eip, addr = allocate_ip(ec2)
print("Allocated {} (interesting: {})".format(addr, str(found_ips)))
if not is_nice(addr):
deallocate_ip(ec2, eip)
else:
print("Keeping IP {}!".format(addr))
found_ips += [addr]
@emanresu92
Copy link

This is a good example of how not to code 👎

  1. It only checks the first region of interesting_address es
  2. Why would you Allocate every damn IP and check if it is nice? Can't you check if it is nice and then Allocate??

@asheroto
Copy link

Thanks for writing this!

@12932
Copy link

12932 commented Mar 13, 2023

I think they nerfed this. I'm only getting a pool of like 3 total ips.

Edit: you get a pool of ~5 ips per minute, per region, per account. So this still works, just add a 1 minute sleep to the While

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment