import EmailSubscribe from ’../../../components/EmailSubscribe.astro’;
Extraire les adresses d’un sous-réseau avec Python
L’extraction et l’analyse des adresses IP d’un sous-réseau sont des tâches essentielles pour les administrateurs réseau, les spécialistes en sécurité et les développeurs d’outils de monitoring. Dans ce guide, nous allons explorer comment utiliser Python pour extraire efficacement toutes les adresses d’un sous-réseau, les filtrer selon différents critères, et les analyser pour diverses applications pratiques.
Pourquoi extraire les adresses d’un sous-réseau?
L’extraction des adresses IP d’un sous-réseau est utile pour:
- Inventaire réseau: Cataloguer toutes les adresses disponibles
- Audit de sécurité: Vérifier quelles adresses sont actives ou utilisées
- Planification de capacité: Évaluer l’utilisation du sous-réseau
- Monitoring réseau: Surveiller systématiquement toutes les adresses
- Configuration d’équipements: Préparer des scripts de configuration pour des équipements réseau
Le module ipaddress à la rescousse
Python offre un puissant module nommé ipaddress
qui simplifie grandement la manipulation des adresses IP et des sous-réseaux. Importons-le pour commencer:
import ipaddress
Extraire toutes les adresses d’un sous-réseau
Technique de base
La méthode la plus simple pour extraire toutes les adresses d’un sous-réseau est d’itérer sur l’objet réseau:
def extract_all_addresses(cidr):
"""Extrait toutes les adresses IP d'un sous-réseau donné en notation CIDR."""
network = ipaddress.ip_network(cidr)
return list(network.hosts())
# Exemple pour un petit sous-réseau
subnet = "192.168.1.0/29"
addresses = extract_all_addresses(subnet)
print(f"Le sous-réseau {subnet} contient {len(addresses)} adresses utilisables:")
for addr in addresses:
print(f" - {addr}")
Résultat:
Le sous-réseau 192.168.1.0/29 contient 6 adresses utilisables:
- 192.168.1.1
- 192.168.1.2
- 192.168.1.3
- 192.168.1.4
- 192.168.1.5
- 192.168.1.6
Optimisation pour grands sous-réseaux
Pour les grands sous-réseaux, il est préférable d’éviter de stocker toutes les adresses en mémoire d’un coup. Utilisons des générateurs:
def address_generator(cidr):
"""Générateur qui produit les adresses IP d'un sous-réseau sans les charger toutes en mémoire."""
network = ipaddress.ip_network(cidr)
for host in network.hosts():
yield host
# Utilisation pour un sous-réseau plus grand
subnet = "10.0.0.0/24" # 254 adresses utilisables
for i, addr in enumerate(address_generator(subnet)):
if i < 5: # Afficher seulement les 5 premières
print(f"Adresse {i+1}: {addr}")
elif i == 5:
print("...")
Extraire des sous-ensembles d’adresses
Adresses au début et à la fin du sous-réseau
def get_subnet_boundaries(cidr, count=5):
"""Retourne les premières et dernières adresses d'un sous-réseau."""
network = ipaddress.ip_network(cidr)
hosts = list(network.hosts())
if len(hosts) <= count * 2:
return hosts
return hosts[:count] + hosts[-count:]
# Exemple
subnet = "172.16.0.0/20"
boundaries = get_subnet_boundaries(subnet)
print(f"Premières adresses de {subnet}:")
for addr in boundaries[:5]:
print(f" - {addr}")
print(f"Dernières adresses de {subnet}:")
for addr in boundaries[-5:]:
print(f" - {addr}")
Extraire des adresses par plage
def extract_address_range(cidr, start_idx, end_idx):
"""Extrait une plage spécifique d'adresses d'un sous-réseau."""
network = ipaddress.ip_network(cidr)
hosts = list(network.hosts())
if start_idx >= len(hosts) or end_idx > len(hosts):
raise ValueError("Indices hors limites")
return hosts[start_idx:end_idx]
# Exemple: obtenir les adresses 10 à 20 d'un sous-réseau
subnet = "192.168.2.0/24"
middle_range = extract_address_range(subnet, 10, 20)
print(f"Adresses 10 à 20 de {subnet}:")
for addr in middle_range:
print(f" - {addr}")
Analyse et filtrage d’adresses
Filtrer par motif d’adresse
def filter_by_pattern(cidr, pattern):
"""Filtre les adresses d'un sous-réseau selon un motif."""
network = ipaddress.ip_network(cidr)
pattern_str = str(pattern)
result = []
for addr in network.hosts():
if pattern_str in str(addr):
result.append(addr)
return result
# Exemple: trouver toutes les adresses contenant "100"
subnet = "192.168.0.0/22"
matching_addrs = filter_by_pattern(subnet, "100")
print(f"Adresses contenant '100' dans {subnet}:")
for addr in matching_addrs:
print(f" - {addr}")
Déterminer les adresses paires et impaires
def categorize_addresses(cidr):
"""Catégorise les adresses en paires et impaires."""
network = ipaddress.ip_network(cidr)
even = []
odd = []
for host in network.hosts():
if int(host) % 2 == 0:
even.append(host)
else:
odd.append(host)
return {
'even': even,
'odd': odd
}
# Exemple
subnet = "192.168.1.16/28"
categories = categorize_addresses(subnet)
print(f"Adresses paires de {subnet}: {len(categories['even'])}")
print(f"Adresses impaires de {subnet}: {len(categories['odd'])}")
Applications pratiques
Scanner un sous-réseau pour les hôtes actifs
import subprocess
import concurrent.futures
import platform
def ping(ip):
"""Vérifie si une adresse IP répond au ping."""
param = "-n" if platform.system().lower() == "windows" else "-c"
command = ["ping", param, "1", str(ip)]
return subprocess.call(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0
def scan_subnet(cidr, max_workers=10):
"""Scanne un sous-réseau pour trouver les hôtes actifs."""
network = ipaddress.ip_network(cidr)
active_hosts = []
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
# Créer un dictionnaire de futures
future_to_ip = {executor.submit(ping, ip): ip for ip in network.hosts()}
for future in concurrent.futures.as_completed(future_to_ip):
ip = future_to_ip[future]
try:
if future.result():
active_hosts.append(ip)
print(f"Hôte actif trouvé: {ip}")
except Exception as exc:
print(f"{ip} a généré une exception: {exc}")
return active_hosts
# Exemple d'utilisation (attention: peut prendre du temps selon la taille du sous-réseau)
# active_hosts = scan_subnet("192.168.1.0/24")
# print(f"Total des hôtes actifs: {len(active_hosts)}")
Générer des fichiers de configuration pour équipements réseau
def generate_dhcp_config(cidr, domain="example.com"):
"""Génère une configuration DHCP pour un sous-réseau."""
network = ipaddress.ip_network(cidr)
config = [
f"subnet {network.network_address} netmask {network.netmask} {{",
f" option domain-name \"{domain}\";",
f" option domain-name-servers 8.8.8.8, 8.8.4.4;",
f" option routers {next(network.hosts())};",
f" option broadcast-address {network.broadcast_address};",
f" default-lease-time 600;",
f" max-lease-time 7200;",
"}",
"",
"# Réservations statiques"
]
# Ajouter quelques réservations d'exemple
for i, host in enumerate(list(network.hosts())[:5]):
config.append(f"host device{i+1} {{")
config.append(f" hardware ethernet 00:11:22:33:44:{i+1:02x};")
config.append(f" fixed-address {host};")
config.append("}")
return "\n".join(config)
# Exemple
subnet = "192.168.5.0/24"
dhcp_config = generate_dhcp_config(subnet)
print("Configuration DHCP générée:")
print(dhcp_config)
Gestion d’IPv6
Le module ipaddress
fonctionne aussi bien avec IPv6 qu’avec IPv4:
def compare_ipv4_ipv6_extraction(ipv4_cidr, ipv6_cidr, count=5):
"""Compare l'extraction d'adresses IPv4 et IPv6."""
ipv4_net = ipaddress.ip_network(ipv4_cidr)
ipv6_net = ipaddress.ip_network(ipv6_cidr)
ipv4_hosts = list(ipv4_net.hosts())[:count]
ipv6_hosts = list(ipv6_net.hosts())[:count]
print(f"Premiers {count} hôtes IPv4 dans {ipv4_cidr}:")
for host in ipv4_hosts:
print(f" - {host}")
print(f"\nPremiers {count} hôtes IPv6 dans {ipv6_cidr}:")
for host in ipv6_hosts:
print(f" - {host}")
print(f"\nTaille totale IPv4: {ipv4_net.num_addresses} adresses")
print(f"Taille totale IPv6: {ipv6_net.num_addresses} adresses")
# Exemple
compare_ipv4_ipv6_extraction("192.168.1.0/24", "2001:db8::/120")
Optimisation des performances
Pour les très grands sous-réseaux (comme /16
ou plus grand en IPv4, ou la plupart des sous-réseaux IPv6), l’énumération complète peut être inefficace ou impossible. Voici quelques approches optimisées:
def sample_large_subnet(cidr, sample_size=1000):
"""Échantillonne un grand sous-réseau de manière statistique."""
network = ipaddress.ip_network(cidr)
total_addresses = network.num_addresses
# Si le réseau a des adresses de broadcast/réseau, les exclure du calcul
if network.version == 4:
host_addresses = total_addresses - 2
else: # IPv6 n'a pas ces restrictions
host_addresses = total_addresses
if host_addresses <= sample_size:
return list(network.hosts())
# Calculer des points d'échantillonnage statistiques
step = host_addresses // sample_size
result = []
current = int(network.network_address) + (1 if network.version == 4 else 0)
for _ in range(sample_size):
addr = ipaddress.ip_address(current)
if addr in network:
result.append(addr)
current += step
return result
# Exemple avec un grand sous-réseau
large_subnet = "10.0.0.0/16" # 65,534 adresses utilisables
samples = sample_large_subnet(large_subnet, 10)
print(f"Échantillon de 10 adresses du sous-réseau {large_subnet}:")
for addr in samples:
print(f" - {addr}")
Points clés à retenir
- Le module
ipaddress
est essentiel pour manipuler efficacement les adresses IP en Python - Pour les petits sous-réseaux, l’énumération complète est simple et efficace
- Pour les grands sous-réseaux, privilégiez les générateurs et l’échantillonnage
- Les techniques d’extraction peuvent être adaptées pour IPv4 et IPv6
- Les applications pratiques incluent le scanning réseau, la configuration d’équipements, et l’inventaire d’adresses
Conclusion
L’extraction d’adresses IP d’un sous-réseau est une compétence fondamentale pour tout administrateur réseau ou développeur travaillant avec des applications réseau. Python, avec son module ipaddress
, offre des outils puissants pour automatiser ces tâches et les intégrer dans des systèmes plus larges de gestion réseau, de monitoring ou de sécurité.
En maîtrisant ces techniques, vous pouvez construire des solutions robustes pour la gestion de vos infrastructures réseau, qu’il s’agisse de petits réseaux locaux ou de vastes déploiements en entreprise.
À propos de InSkillCoach
Expert en formation et technologies
Coach spécialisé dans les technologies avancées et l'IA, porté par GNeurone Inc.
Certifications:
- AWS Certified Solutions Architect – Professional
- Certifications Google Cloud
- Microsoft Certified: DevOps Engineer Expert
- Certified Kubernetes Administrator (CKA)
- CompTIA Security+
Commentaires
Les commentaires sont alimentés par GitHub Discussions
Connectez-vous avec GitHub pour participer à la discussion