Comment configurer les interfaces réseau en Python

PythonBeginner
Pratiquer maintenant

Introduction

Python offre de puissantes capacités pour travailler avec les interfaces réseau, permettant aux développeurs de récupérer des informations réseau et de configurer les paramètres réseau de manière programmatique. Cette compétence pratique est précieuse pour les administrateurs réseau, les ingénieurs système et les développeurs travaillant sur des applications liées au réseau.

Dans ce lab, vous apprendrez comment utiliser Python pour inspecter et gérer les interfaces réseau sur un système Linux. Vous commencerez par l'identification de base des interfaces, passerez à la récupération d'informations réseau détaillées, et terminerez par la surveillance du trafic réseau. À la fin de ce lab, vous aurez une expérience pratique avec les bibliothèques réseau de Python et serez capable d'appliquer ces compétences à des tâches réseau réelles.

Installation des paquets Python requis

Avant de pouvoir travailler avec les interfaces réseau en Python, nous devons installer les paquets nécessaires. Les deux principaux paquets que nous utiliserons sont :

  • netifaces : Une bibliothèque multiplateforme pour récupérer les informations des interfaces réseau
  • psutil : Une bibliothèque pour récupérer les informations système, y compris les statistiques réseau

Commençons par installer ces paquets en utilisant pip.

Installation des paquets

Ouvrez un terminal et exécutez la commande suivante pour installer les paquets requis :

pip install netifaces psutil

Vous devriez voir une sortie indiquant que les paquets sont en cours de téléchargement et d'installation. Attendez que l'installation soit terminée avant de continuer.

Vérification de l'installation

Vérifions que les paquets ont été installés correctement en créant un script Python simple. Créez un nouveau fichier appelé check_packages.py dans l'éditeur VSCode :

  1. Cliquez sur l'icône "Explorer" dans la barre latérale gauche (ou appuyez sur Ctrl+E)
  2. Cliquez sur le bouton "Nouveau fichier"
  3. Nommez le fichier check_packages.py
  4. Ajoutez le code suivant au fichier :
try:
    import netifaces
    import psutil
    print("Both packages installed successfully!")
    print(f"netifaces version: {netifaces.__version__}")
    print(f"psutil version: {psutil.__version__}")
except ImportError as e:
    print(f"Error importing packages: {e}")

Enregistrez le fichier en appuyant sur Ctrl+S ou en sélectionnant "Fichier > Enregistrer" dans le menu.

Maintenant, exécutez le script en ouvrant un terminal (s'il n'est pas déjà ouvert) et en exécutant :

python3 check_packages.py

Vous devriez voir une sortie similaire à :

Both packages installed successfully!
netifaces version: 0.11.0
psutil version: 5.9.0

Les numéros de version exacts peuvent être différents, mais tant que vous voyez le message "installed successfully", vous êtes prêt à passer à l'étape suivante.

Lister les interfaces réseau

Maintenant que nous avons installé les paquets nécessaires, commençons à explorer les interfaces réseau. La première étape consiste à identifier toutes les interfaces réseau disponibles sur votre système.

Création d'un script pour lister les interfaces réseau

Créez un nouveau fichier nommé list_interfaces.py dans l'éditeur VSCode :

  1. Cliquez sur l'icône "Explorer" dans la barre latérale gauche si elle n'est pas déjà ouverte
  2. Cliquez sur le bouton "Nouveau fichier"
  3. Nommez le fichier list_interfaces.py
  4. Ajoutez le code suivant :
import netifaces

def list_network_interfaces():
    """List all network interfaces available on the system."""
    interfaces = netifaces.interfaces()

    print("Available network interfaces:")
    for index, interface in enumerate(interfaces, 1):
        print(f"{index}. {interface}")

if __name__ == "__main__":
    list_network_interfaces()

Enregistrez le fichier en appuyant sur Ctrl+S.

Exécution du script

Exécutons maintenant le script pour voir la liste des interfaces réseau sur votre système :

python3 list_interfaces.py

Vous devriez voir une sortie similaire à :

Available network interfaces:
1. lo
2. eth0
3. docker0

La liste exacte dépendra de la configuration de votre système. Comprenons ce que ces interfaces représentent généralement :

  • lo : L'interface de bouclage (localhost)
  • eth0 : L'interface Ethernet principale
  • wlan0 : L'interface sans fil principale (si disponible)
  • docker0 : L'interface réseau pont Docker (si Docker est installé)

Comprendre les noms des interfaces réseau

Les noms des interfaces réseau peuvent varier en fonction du système d'exploitation et de la configuration :

  • Sur les systèmes Linux traditionnels, les interfaces sont nommées eth0, eth1, etc., pour Ethernet
  • Sur les systèmes plus récents utilisant des noms d'interfaces réseau prévisibles, vous pourriez voir des noms comme enp0s3 ou ens33
  • Les interfaces virtuelles peuvent avoir des noms comme veth... ou br0 pour les ponts

Modifions notre script pour fournir plus de détails sur chaque interface. Mettez à jour le fichier list_interfaces.py avec le code suivant :

import netifaces

def list_network_interfaces():
    """List all network interfaces available on the system with details."""
    interfaces = netifaces.interfaces()

    print("Available network interfaces:")
    for index, interface in enumerate(interfaces, 1):
        print(f"{index}. {interface}")

        ## Try to get addresses for this interface
        try:
            if netifaces.AF_INET in netifaces.ifaddresses(interface):
                ip_info = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]
                print(f"   IPv4 Address: {ip_info.get('addr', 'None')}")
        except ValueError:
            print("   No IPv4 address assigned")

if __name__ == "__main__":
    list_network_interfaces()

Enregistrez le fichier et exécutez-le à nouveau :

python3 list_interfaces.py

Vous devriez maintenant voir une sortie plus détaillée qui inclut l'adresse IPv4 pour chaque interface :

Available network interfaces:
1. lo
   IPv4 Address: 127.0.0.1
2. eth0
   IPv4 Address: 172.17.0.2
3. docker0
   IPv4 Address: 172.17.0.1

Cela nous donne une meilleure compréhension des interfaces réseau disponibles sur le système et de leurs adresses IP actuelles.

Récupération d'informations détaillées sur les interfaces réseau

Maintenant que nous pouvons lister les interfaces réseau disponibles, créons un script plus complet pour récupérer des informations détaillées sur une interface réseau spécifique.

Création d'un script de détails d'interface réseau

Créez un nouveau fichier nommé interface_details.py dans l'éditeur VSCode :

  1. Cliquez sur le bouton "Nouveau fichier" dans le volet Explorer
  2. Nommez le fichier interface_details.py
  3. Ajoutez le code suivant :
import netifaces
import sys

def get_interface_details(interface_name):
    """
    Retrieve detailed information about a specific network interface.

    Args:
        interface_name (str): The name of the network interface

    Returns:
        None: Prints interface details to console
    """
    ## Check if the interface exists
    interfaces = netifaces.interfaces()
    if interface_name not in interfaces:
        print(f"Error: Interface '{interface_name}' does not exist.")
        print(f"Available interfaces: {', '.join(interfaces)}")
        return

    print(f"\nDetails for interface '{interface_name}':")
    print("-" * 50)

    ## Get addresses for all protocol families
    try:
        addresses = netifaces.ifaddresses(interface_name)

        ## IPv4 addresses (AF_INET)
        if netifaces.AF_INET in addresses:
            ipv4_info = addresses[netifaces.AF_INET][0]
            print("IPv4 Information:")
            print(f"  Address: {ipv4_info.get('addr', 'Not available')}")
            print(f"  Netmask: {ipv4_info.get('netmask', 'Not available')}")
            print(f"  Broadcast: {ipv4_info.get('broadcast', 'Not available')}")
        else:
            print("IPv4 Information: Not available")

        ## IPv6 addresses (AF_INET6)
        if netifaces.AF_INET6 in addresses:
            ipv6_info = addresses[netifaces.AF_INET6][0]
            print("\nIPv6 Information:")
            print(f"  Address: {ipv6_info.get('addr', 'Not available')}")
            print(f"  Netmask: {ipv6_info.get('netmask', 'Not available')}")
            print(f"  Scope: {ipv6_info.get('scope', 'Not available')}")
        else:
            print("\nIPv6 Information: Not available")

        ## MAC address (AF_LINK)
        if netifaces.AF_LINK in addresses:
            link_info = addresses[netifaces.AF_LINK][0]
            print("\nMAC Address Information:")
            print(f"  Address: {link_info.get('addr', 'Not available')}")
            print(f"  Broadcast: {link_info.get('broadcast', 'Not available')}")
        else:
            print("\nMAC Address Information: Not available")

        ## Gateway information
        gateways = netifaces.gateways()
        print("\nGateway Information:")
        if 'default' in gateways and netifaces.AF_INET in gateways['default']:
            gw_addr, gw_interface = gateways['default'][netifaces.AF_INET]
            if gw_interface == interface_name:
                print(f"  Default Gateway: {gw_addr}")
            else:
                print("  No default gateway for this interface")
        else:
            print("  No default gateway information available")

    except Exception as e:
        print(f"Error retrieving interface details: {e}")

if __name__ == "__main__":
    ## If an interface name is provided as a command-line argument, use it
    ## Otherwise, use the first interface from the list (excluding 'lo')
    if len(sys.argv) > 1:
        interface_name = sys.argv[1]
    else:
        interfaces = [i for i in netifaces.interfaces() if i != 'lo']
        if interfaces:
            interface_name = interfaces[0]
            print(f"No interface specified, using {interface_name}")
        else:
            print("No network interfaces available")
            sys.exit(1)

    get_interface_details(interface_name)

Enregistrez le fichier en appuyant sur Ctrl+S.

Exécution du script

Exécutons maintenant le script pour voir des informations détaillées sur une interface réseau spécifique :

python3 interface_details.py eth0

Remplacez eth0 par l'une des interfaces que vous avez vues à l'étape précédente si nécessaire.

Vous devriez voir une sortie similaire à :

Details for interface 'eth0':
--------------------------------------------------
IPv4 Information:
  Address: 172.17.0.2
  Netmask: 255.255.0.0
  Broadcast: 172.17.255.255

IPv6 Information: Not available

MAC Address Information:
  Address: 02:42:ac:11:00:02
  Broadcast: ff:ff:ff:ff:ff:ff

Gateway Information:
  Default Gateway: 172.17.0.1

Vous pouvez également exécuter le script sans spécifier de nom d'interface, et il sélectionnera automatiquement la première interface non-bouclage :

python3 interface_details.py

Ce script fournit une vue complète de la configuration de l'interface réseau, notamment :

  1. Adresse IPv4, masque de sous-réseau et adresse de diffusion (broadcast)
  2. Adresse IPv6 (si disponible)
  3. Adresse MAC
  4. Informations sur la passerelle par défaut

Comprendre ces informations détaillées est essentiel pour le dépannage et la configuration du réseau.

Exploration des constantes du module netifaces

Le module netifaces utilise des constantes pour représenter différentes familles d'adresses. Créons un script rapide pour comprendre ces constantes. Créez un nouveau fichier nommé netifaces_constants.py :

import netifaces

## Print all address family constants
print("Address Family Constants in netifaces module:")
print(f"AF_INET (IPv4): {netifaces.AF_INET}")
print(f"AF_INET6 (IPv6): {netifaces.AF_INET6}")
print(f"AF_LINK (MAC/Hardware): {netifaces.AF_LINK}")

## Additional constants that might be available
for name in dir(netifaces):
    if name.startswith('AF_'):
        print(f"{name}: {getattr(netifaces, name)}")

Enregistrez et exécutez ce script :

python3 netifaces_constants.py

Vous devriez voir une sortie comme :

Address Family Constants in netifaces module:
AF_INET (IPv4): 2
AF_INET6 (IPv6): 10
AF_LINK (MAC/Hardware): 17
AF_APPLETALK: 5
AF_INET: 2
AF_INET6: 10
AF_IPX: 4
AF_LINK: 17
AF_UNIX: 1

Ces constantes sont utilisées dans le module netifaces pour identifier différents types d'adresses réseau. Les comprendre est utile lorsque vous travaillez avec les fonctions du module.

Surveillance du trafic de l'interface réseau

Maintenant que nous comprenons comment récupérer les informations de l'interface réseau, allons plus loin et créons un script pour surveiller le trafic réseau en temps réel. Cela nous permettra de voir la quantité de données envoyées et reçues via une interface spécifique.

Création d'un script de surveillance du trafic réseau

Créez un nouveau fichier nommé monitor_traffic.py dans l'éditeur VSCode :

  1. Cliquez sur le bouton "Nouveau fichier" dans le volet Explorer
  2. Nommez le fichier monitor_traffic.py
  3. Ajoutez le code suivant :
import psutil
import time
import sys
import netifaces

def bytes_to_readable(bytes_count):
    """Convert bytes to a human-readable format (KB, MB, GB)"""
    units = ['B', 'KB', 'MB', 'GB', 'TB']
    unit_index = 0
    converted_value = float(bytes_count)

    while converted_value >= 1024 and unit_index < len(units) - 1:
        converted_value /= 1024
        unit_index += 1

    return f"{converted_value:.2f} {units[unit_index]}"

def monitor_network_traffic(interface_name, interval=1, iterations=10):
    """
    Monitor network traffic on a specific interface for a given number of iterations.

    Args:
        interface_name (str): Name of the network interface to monitor
        interval (int): Time interval between measurements in seconds
        iterations (int): Number of measurements to take
    """
    ## Verify interface exists
    if interface_name not in netifaces.interfaces():
        print(f"Error: Interface '{interface_name}' does not exist.")
        print(f"Available interfaces: {', '.join(netifaces.interfaces())}")
        return

    print(f"Monitoring network traffic on {interface_name} (Ctrl+C to stop)")
    print("-" * 80)
    print(f"{'Time':<12} {'Bytes Sent':<15} {'Bytes Received':<15} {'Packets Sent':<15} {'Packets Received':<15}")
    print("-" * 80)

    try:
        ## Get initial stats
        net_io_counters = psutil.net_io_counters(pernic=True)
        if interface_name not in net_io_counters:
            print(f"Error: Cannot get stats for interface '{interface_name}'")
            return

        prev_stats = net_io_counters[interface_name]
        prev_bytes_sent = prev_stats.bytes_sent
        prev_bytes_recv = prev_stats.bytes_recv
        prev_packets_sent = prev_stats.packets_sent
        prev_packets_recv = prev_stats.packets_recv

        ## Monitor for the specified number of iterations
        for i in range(iterations):
            ## Wait for the specified interval
            time.sleep(interval)

            ## Get new stats
            net_io_counters = psutil.net_io_counters(pernic=True)
            new_stats = net_io_counters[interface_name]

            ## Calculate differences
            bytes_sent_diff = new_stats.bytes_sent - prev_bytes_sent
            bytes_recv_diff = new_stats.bytes_recv - prev_bytes_recv
            packets_sent_diff = new_stats.packets_sent - prev_packets_sent
            packets_recv_diff = new_stats.packets_recv - prev_packets_recv

            ## Update previous values
            prev_bytes_sent = new_stats.bytes_sent
            prev_bytes_recv = new_stats.bytes_recv
            prev_packets_sent = new_stats.packets_sent
            prev_packets_recv = new_stats.packets_recv

            ## Print the current stats
            current_time = time.strftime("%H:%M:%S")
            print(f"{current_time:<12} {bytes_to_readable(bytes_sent_diff):<15} "
                  f"{bytes_to_readable(bytes_recv_diff):<15} {packets_sent_diff:<15} "
                  f"{packets_recv_diff:<15}")

    except KeyboardInterrupt:
        print("\nMonitoring stopped by user")
    except Exception as e:
        print(f"Error during monitoring: {e}")

    print("\nTraffic summary for this session:")
    print(f"Total monitored time: {iterations * interval} seconds")

if __name__ == "__main__":
    ## Get the interface name from command line arguments or use a default
    if len(sys.argv) > 1:
        interface_name = sys.argv[1]
    else:
        ## Try to find a non-loopback interface
        interfaces = [i for i in netifaces.interfaces() if i != 'lo']
        if interfaces:
            interface_name = interfaces[0]
            print(f"No interface specified, using {interface_name}")
        else:
            print("No network interfaces available")
            sys.exit(1)

    ## Get number of iterations from command line (default: 10)
    iterations = 10
    if len(sys.argv) > 2:
        try:
            iterations = int(sys.argv[2])
        except ValueError:
            print(f"Invalid iterations value: {sys.argv[2]}. Using default: 10")

    ## Monitor the network traffic
    monitor_network_traffic(interface_name, iterations=iterations)

Enregistrez le fichier en appuyant sur Ctrl+S.

Exécution du script de surveillance du trafic

Exécutons maintenant le script pour surveiller le trafic réseau sur une interface spécifique :

python3 monitor_traffic.py eth0

Remplacez eth0 par le nom d'interface approprié de votre système si nécessaire.

Le script affichera un tableau montrant la quantité de données envoyées et reçues via l'interface réseau, se mettant à jour une fois par seconde pendant 10 itérations :

Monitoring network traffic on eth0 (Ctrl+C to stop)
--------------------------------------------------------------------------------
Time         Bytes Sent      Bytes Received  Packets Sent    Packets Received
--------------------------------------------------------------------------------
14:25:30     0.00 B          156.00 B        0               2
14:25:31     0.00 B          0.00 B          0               0
14:25:32     0.00 B          0.00 B          0               0
14:25:33     456.00 B        1.24 KB         3               5
14:25:34     0.00 B          0.00 B          0               0
14:25:35     0.00 B          0.00 B          0               0
14:25:36     66.00 B         102.00 B        1               1
14:25:37     0.00 B          0.00 B          0               0
14:25:38     0.00 B          0.00 B          0               0
14:25:39     0.00 B          0.00 B          0               0

Traffic summary for this session:
Total monitored time: 10 seconds

Vous pouvez également spécifier le nombre d'itérations comme deuxième argument de ligne de commande :

python3 monitor_traffic.py eth0 5

Cela surveillerait le trafic pendant 5 itérations au lieu des 10 par défaut.

Génération de trafic réseau

Pour voir le script de surveillance en action avec du trafic réel, nous pouvons ouvrir un deuxième terminal et générer du trafic réseau. Créons un script simple pour le faire :

Créez un nouveau fichier nommé generate_traffic.py :

import requests
import time
import sys

def generate_traffic(iterations=5, delay=1):
    """Generate some network traffic by making HTTP requests"""
    print(f"Generating network traffic over {iterations} iterations...")

    for i in range(iterations):
        try:
            ## Make a GET request to a public API
            response = requests.get("https://httpbin.org/get")
            print(f"Request {i+1}/{iterations}: Status {response.status_code}, "
                  f"Size {len(response.content)} bytes")

            ## Wait before the next request
            if i < iterations - 1:
                time.sleep(delay)

        except Exception as e:
            print(f"Error making request: {e}")

    print("Traffic generation complete")

if __name__ == "__main__":
    ## Get number of iterations from command line (default: 5)
    iterations = 5
    if len(sys.argv) > 1:
        try:
            iterations = int(sys.argv[1])
        except ValueError:
            print(f"Invalid iterations value: {sys.argv[1]}. Using default: 5")

    generate_traffic(iterations)

Vous devrez d'abord installer la bibliothèque requests :

pip install requests

Maintenant, exécutez le script de surveillance dans un terminal :

python3 monitor_traffic.py eth0 15

Et dans un terminal séparé, exécutez le script de génération de trafic :

python3 generate_traffic.py

Vous devriez maintenant voir l'activité réseau capturée par le script de surveillance lorsque le script de génération de trafic effectue des requêtes HTTP.

Cet exercice démontre comment vous pouvez utiliser Python pour surveiller l'activité de l'interface réseau en temps réel, ce qui est utile pour diagnostiquer les problèmes de réseau, surveiller l'utilisation de la bande passante et comprendre les modèles de trafic réseau.

Résumé

Dans ce laboratoire, vous avez acquis une expérience pratique des capacités de gestion des interfaces réseau de Python. Voici ce que vous avez accompli :

  1. Configuration de l'environnement : Vous avez installé et configuré les packages Python nécessaires (netifaces et psutil) pour travailler avec les interfaces réseau.

  2. Listage des interfaces réseau : Vous avez créé un script pour identifier toutes les interfaces réseau disponibles sur votre système et afficher des informations de base à leur sujet.

  3. Récupération d'informations détaillées sur les interfaces : Vous avez écrit un script complet pour extraire des informations de configuration détaillées des interfaces réseau, notamment les adresses IP, les adresses MAC et les informations de passerelle.

  4. Surveillance du trafic réseau : Vous avez implémenté un outil de surveillance du trafic réseau en temps réel qui suit les données envoyées et reçues via une interface spécifique.

Ces compétences constituent la base de tâches de gestion de réseau plus avancées en Python, telles que :

  • Automatisation des modifications de configuration réseau
  • Construction de tableaux de bord de surveillance réseau
  • Création d'outils de diagnostic réseau
  • Développement d'applications de sécurité réseau

En comprenant comment interagir avec les interfaces réseau par programmation, vous avez désormais la capacité de créer des outils de mise en réseau personnalisés adaptés à vos besoins spécifiques. Ces connaissances sont particulièrement précieuses pour les administrateurs système, les ingénieurs réseau et les développeurs travaillant sur des applications en réseau.