Python – Sumariza CIDRs

Objetivo

Sumarizar diversos CIDRs usando o script mais simples possível.

Método

É preciso ter um arquivo chamado lista_cidr.txt na mesma pasta deste script.

O conteúdo do arquivo precisa ser uma lista de CIDRs, sendo um em cada linha.
Não podem haver espaços nem antes nem depois do CIDR.
IPs podem ser referenciados utilizando-se /32.
Exemplo:

10.128.0.0/16
10.0.11.0/24
10.0.12.0/24
10.0.8.0/24
10.0.9.0/24
10.0.9.254/32

Código
				
					import os.path
import netaddr
from netaddr import IPNetwork

'''
Sumariza CIDRs.

É preciso ter um arquivo chamado lista_cidr.txt na mesma pasta deste script.
O conteúdo do arquivo precisa ser uma lista de CIDRs, sendo um em cada linha.
Não podem haver espaços nem antes nem depois do CIDR.
IPs podem ser referenciados utilizando-se /32.
Exemplo:
10.128.0.0/16
10.0.11.0/24
10.0.12.0/24
10.0.8.0/24
10.0.9.0/24
10.0.9.254/32
'''

path_output = "./lista_cidr.txt"  # path do arquivo de entrada.
full_path_output = os.path.expanduser(path_output)  # armazena o path completo do arquivo de entrada.

file = open(full_path_output, 'r')  # abre o arquivo.

cidrlist = []  # irá armazenas a lista dos objetos IPNetwork (CIDRs) que serão sumarizados.

for cidr in file:  # lê o arquivo com os CIDRs que serão sumarizados e popula a lista cidrList.
    cidr = IPNetwork(cidr.strip())  # cria os objetos da classe IPNetwork passando os CIDRs do arquivo de entrada.
    cidrlist.append(cidr)  # adiciona o objeto à lista.

sumarizado = netaddr.cidr_merge(cidrlist)  # sumariza os CIDRs.

for ip in sumarizado:  # imprime a lista dos CIDRs sumarizados.
    print(ip)





				
			

Considerando que o código acima tenha como entrada um arquivo chamado lista_cidr.txt com o seguinte conteúdo.

				
					10.128.0.0/16
10.0.11.0/24
10.0.12.0/24
10.0.8.0/24
10.0.9.0/24
10.0.9.254/32
				
			

O resultado da execução do script seria:

				
					10.0.8.0/23
10.0.11.0/24
10.0.12.0/24
10.128.0.0/16
				
			

Repare que:

  • O CIDR 10.128.0.0/16 permaneceu inalterado.
  • Os CIDRs 10.0.11.0/24 e 10.0.12.0/24 não foram sumarizados. 
  • Os CIDRs 10.0.8.0/24, 10.0.9.0/24 e 10.0.9.254/32 foram sumarizados para 10.0.8.0/23.
  • 10.0.9.254/32 representa um IP.

Por que os CIDRs 10.0.8.0/24 e 10.0.9.0/24 foram sumarizados para 10.0.8.0/23, mas os CIDRs 10.0.11.0/24 e 10.0.12.0/24 não foram sumarizados para um 10.0.11.0/23? Isto é, tínhamos CIDRs adjacentes /24 e no primeiro caso eles foram sumarizados para um /23, mas no segundo caso não foram, por que?

Em primeiro lugar vamos analisar o range de IPs de cada uma dos CIDRs que foram sumarizados.

10.0.8.0/24 (CIDR) – 10.0.8.1 (primeiro IP do range) – 10.0.8.254 (último IP do range)
10.0.9.0/24 (CIDR) – 10.0.9.1 (primeiro IP do range) – 10.0.9.254 (último IP do range)

Isto é, como são CIDRs adjacentes, é possível afirmar que se tivermos um outro CIDR que represente o intervalo entre os IPs 10.8.0.1 e 10.0.9.254, este CIDR poderia ser usado para a sumarização de 10.0.8.0/24 e 10.0.9.0/24.

Agora, vamos analisar o range de IPs do CIDR 10.0.8.0/23.

10.0.8.0/23 (CIDR) – 10.0.8.1 (primeiro IP do range) – 10.0.9.254 (último IP do range)

Assim, o CIDR 10.0.8.0/23 pode representar o mesmo range de IPs que antes era representado pelos dois CIDRs /24.

Certo, mas e os CIDRS 10.0.11.0/24 e 10.0.12.0/24 não poderiam ser sumarizados para 10.0.11.0/23?

Vamos analisar o range de IPs para cada um dos CIDRs.

10.0.11.0/24 (CIDR) – 10.0.11.1 (primeiro IP do range) – 10.0.11.254 (último IP do range)
10.0.12.0/24 (CIDR) – 10.0.12.1 (primeiro IP do range) – 10.0.12.254 (último IP do range)

Agora vamos analisar o range de IPs para CIDR 10.0.11.0/23 – que é o CIDR que acreditamos que pudesse ser usado para sumarizar os outros dois.

10.0.11.0/23 (CIDR) – 10.0.10.1 (primeiro IP do range) – 10.0.11.254 (último IP do range)

Perceba que o primeiro IP do /23 é 10.0.10.1, isto é, um IP que não pertence a nenhum dos dois /24. Assim, não há sumarização possível para estes dois /24 e foi exatamente isto que a saída do script mostrou.

Vamos adicionar o CIDR 10.0.10.0/24 ao arquivo lista_cidr.txt e executar o script de sumarização novamente.

A seguir está o conteúdo do arquivo list_cidr.txt.

				
					10.128.0.0/16
10.0.10.0/24
10.0.11.0/24
10.0.12.0/24
10.0.8.0/24
10.0.9.0/24
10.0.9.254/32
				
			

A execução do script de sumarização irá produzir esta saída.

				
					10.0.8.0/22
10.0.12.0/24
10.128.0.0/16
				
			

Perceba que os CIDRs 10.0.8.0/24, 10.0.9.0/24, 10.0.10.0/24 e 10.0.11.0/24 foram sumarizados para 10.0.8.0/22.

Vamos analisar os ranges de IPs de cada um dos CIDRs.

10.0.8.0/24 (CIDR) – 10.0.8.1 (primeiro IP do range) – 10.0.8.254 (último IP do range)
10.0.9.0/24 (CIDR) – 10.0.9.1 (primeiro IP do range) – 10.0.9.254 (último IP do range)
10.0.10.0/24 (CIDR) – 10.0.10.1 (primeiro IP do range) – 10.0.10.254 (último IP do range)
10.0.11.0/23 (CIDR) – 10.0.11.1 (primeiro IP do range) – 10.0.11.254 (último IP do range)

Como os CIDRs são adjacentes e sendo primeiro IP do range 10.0.8.1 e o último 10.0.11.254, então, um outro CIDR que represente este intervalo de IPs pode ser usado no lugar destes quatro CIDRs /24.

Analisando o CIDR 10.0.8.0/22, temos:

10.0.8.0/22 (CIDR) – 10.0.8.1 (primeiro IP do range) – 10.0.11.254 (último IP do range)

Isto é, para representar o mesmo intervalo de IPs dos quatro CIDRs /24 podemos usar o /22.

Este tipo de sumarização é o que o script se propõe a fazer.

It’s done!

Bruno Veiga

Bruno Veiga

Arquiteto Cloud e Arquiteto de Soluções. Me dedicando em compartilhar conhecimento e ajudar empresas a encontrar as melhores soluções tecnológicas para os problemas do negócio com agilidade, segurança, equipes alinhadas e dentro do orçamento.