0%
استخراج عناوين الشبكة الفرعية باستخدام Python

استخراج عناوين الشبكة الفرعية باستخدام Python

تعلّم كيفية استخراج جميع عناوين IP في شبكة فرعية وتحليلها باستخدام Python. تقنيات محسّنة لمراقبة الشبكات وتدقيق الأمان.

I

InSkillCoach

· دقيقة

استخراج عناوين الشبكة الفرعية باستخدام Python

يُعدّ استخراج عناوين IP الخاصة بشبكة فرعية وتحليلها من المهام الأساسية لمسؤولي الشبكات ومتخصصي الأمن ومطوّري أدوات المراقبة. في هذا الدليل سنستعرض كيفية استخدام Python لاستخراج جميع عناوين شبكة فرعية بكفاءة، وتصفيتها وفق معايير مختلفة، وتحليلها لتطبيقات عملية متنوعة.

لماذا نستخرج عناوين الشبكة الفرعية؟

يفيد استخراج عناوين IP الخاصة بشبكة فرعية في:

  • جرد الشبكة: فهرسة جميع العناوين المتاحة
  • تدقيق الأمان: التحقق من العناوين النشطة أو المستخدمة
  • تخطيط السعة: تقييم مدى استخدام الشبكة الفرعية
  • مراقبة الشبكة: مراقبة جميع العناوين بشكل منهجي
  • إعداد المعدات: تجهيز سكربتات الإعداد لمعدات الشبكة

وحدة ipaddress إلى الإنقاذ

توفّر Python وحدة قوية تُسمى ipaddress تبسّط كثيرًا التعامل مع عناوين IP والشبكات الفرعية. لنستورِدها للبدء:

import ipaddress

استخراج جميع عناوين شبكة فرعية

التقنية الأساسية

أبسط طريقة لاستخراج جميع عناوين شبكة فرعية هي التكرار على كائن الشبكة:

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}")

الناتج:

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

التحسين للشبكات الفرعية الكبيرة

بالنسبة إلى الشبكات الفرعية الكبيرة، من الأفضل تجنّب تخزين جميع العناوين في الذاكرة دفعة واحدة. لنستخدم المولّدات (generators):

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("...")

استخراج مجموعات فرعية من العناوين

العناوين في بداية الشبكة الفرعية ونهايتها

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}")

استخراج العناوين حسب نطاق

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}")

تحليل العناوين وتصفيتها

التصفية حسب نمط العنوان

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}")

تحديد العناوين الزوجية والفردية

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'])}")

تطبيقات عملية

فحص شبكة فرعية بحثًا عن المضيفين النشطين

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)}")

توليد ملفات إعداد لمعدات الشبكة

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)

التعامل مع IPv6

تعمل وحدة ipaddress مع IPv6 بالكفاءة نفسها التي تعمل بها مع 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")

تحسين الأداء

بالنسبة إلى الشبكات الفرعية الكبيرة جدًا (مثل /16 أو أكبر في IPv4، أو معظم الشبكات الفرعية في IPv6)، قد يكون التعداد الكامل غير فعّال أو مستحيلًا. إليك بعض الأساليب المحسّنة:

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}")

أهم النقاط الواجب تذكّرها

  • تُعدّ وحدة ipaddress أساسية للتعامل بكفاءة مع عناوين IP في Python
  • بالنسبة إلى الشبكات الفرعية الصغيرة، يكون التعداد الكامل بسيطًا وفعّالًا
  • بالنسبة إلى الشبكات الفرعية الكبيرة، يُفضَّل استخدام المولّدات وأخذ العيّنات
  • يمكن تكييف تقنيات الاستخراج لتناسب IPv4 وIPv6
  • تشمل التطبيقات العملية فحص الشبكات، وإعداد المعدات، وجرد العناوين

الخاتمة

يُعدّ استخراج عناوين IP من شبكة فرعية مهارة أساسية لكل مسؤول شبكات أو مطوّر يعمل على تطبيقات الشبكات. وتوفّر Python، بفضل وحدة ipaddress، أدوات قوية لأتمتة هذه المهام ودمجها في أنظمة أوسع لإدارة الشبكات أو مراقبتها أو تأمينها.

وبإتقان هذه التقنيات، يمكنك بناء حلول متينة لإدارة بنيتك التحتية للشبكات، سواء كانت شبكات محلية صغيرة أو عمليات نشر واسعة في المؤسسات.

InSkillCoach

نبذة عن InSkillCoach

خبير في التدريب والتقنيات

مدرّب متخصص في التقنيات المتقدمة والذكاء الاصطناعي، تدعمه شركة GNeurone Inc.

الشهادات:

  • AWS Certified Solutions Architect – Professional
  • شهادات Google Cloud
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
1.3k
80

التعليقات

التعليقات مدعومة عبر GitHub Discussions

سجّل الدخول باستخدام GitHub للمشاركة في النقاش

تم نسخ الرابط!