Managing Unique CIDR blocks for Private networks | unique-cidr-manager

Artiom Levinton
XM Cyber
Published in
3 min readJun 22, 2022

Any network architecture implementation, whether if it’s built on cloud/on-prem or hybrid platforms, is likely to face this very common challenge:

How to choose a UNIQUE CIDR block for each project/cluster/deployment.

Although there are millions of possible IP addresses in Private ranges, eventually humans “choosing” the VPC/Subnet to provide to some Terraform for example. As a matter of fact, the most common CIDRs are 192.168.1.0/24 , 10.0.0.1/24, 172.16.0.1/24 — Also the fact that usually more than one person is responsible for cloud/private network architecture deployments, the chances for collision are not that low as you might think.

Let’s take the Cloud for example, if you don’t enforce the uniqueness of VPC CIDR across the organization projects, you will quickly find yourself unable to peer across VPCs (even with third party vendors like Mongo — Atlas)

Enough about the problem, let’s talk about the solution!

I created a simple tool that manages the CIDR blocks and keeping track of all occupied CIDRs in a Git repository of your choice (in github.com)

All you need to do is pull the image and run it

Make sure to have a valid env file when you run it, here is an example of such:
https://github.com/XMCyber/unique-cidr-manager/blob/master/env
Read the README.md carefully to setup your GitHub repo properly

~$ docker pull xmcyber/unique-cidr-manager:latest
~$ docker run -d -p 127.0.0.1:8000:8000/tcp --env-file env xmcyber/unique-cidr-manager:latest

Deep dive

The tool is build with Python, and the core functionality implemented with ‘ipaddress’ library (https://docs.python.org/3/library/ipaddress.html). The main function is wrapped with a basic web server, which allow to run the tool as a service in any location (ec2,ecs,eks..)
While browsing to http://127.0.0.1:8000/get-cidr , the web server will invoke the main function which should return a unique CIDR block.
The main function reads the static file, addresses-range.json, as a reference to all possible CIDR in a specific range (10/172/192). After choosing the first subnet (according to subnet size configured in the tool env file, eg. subnet_size=26)

Then, it will load the already occupied ranges defined in this file occupied-range.json (this file should be located in user’s GitHub own repo) and will check if those subnet are overlapping(!), so if they overlaps the statement will be true and the function will choose the next CIDR block. Unfortunately if these blocks are identical, this statement is false:

IPv4Network(subnet).overlaps(IPv4Network(occupied_cidr))

so there is still need to check if those subnet are actual the same one:

if str(subnet) == str(occupied_cidr):
overlapping subnets

eventually, if non of the already occupied ranges overlaps with the newly elected, the function returns it as a unique CIDR block to use (it goes back as HTTP response for the GET request.

The final step is adding this new occupied CIDR to the list, so the tool appends it to the occupied-range.json file, commits the change and lastly pushes the change to the owner’s repo which is now updated and holding the list of ALL occupied ranges in organization.

References

--

--