Comment configurer les interfaces réseau en Python

PythonPythonBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Python offers powerful capabilities for working with network interfaces, allowing developers to programmatically retrieve network information and configure network settings. This practical skill is valuable for network administrators, system engineers, and developers working on network-related applications.

In this lab, you will learn how to use Python to inspect and manage network interfaces on a Linux system. You will start with basic interface identification, move on to retrieving detailed network information, and finish by monitoring network traffic. By the end of this lab, you will have hands-on experience with Python's networking libraries and be able to apply these skills to real-world networking tasks.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/ControlFlowGroup(["Control Flow"]) python(("Python")) -.-> python/ModulesandPackagesGroup(["Modules and Packages"]) python(("Python")) -.-> python/ErrorandExceptionHandlingGroup(["Error and Exception Handling"]) python(("Python")) -.-> python/NetworkingGroup(["Networking"]) python/ControlFlowGroup -.-> python/conditional_statements("Conditional Statements") python/ModulesandPackagesGroup -.-> python/importing_modules("Importing Modules") python/ModulesandPackagesGroup -.-> python/using_packages("Using Packages") python/ErrorandExceptionHandlingGroup -.-> python/catching_exceptions("Catching Exceptions") python/NetworkingGroup -.-> python/http_requests("HTTP Requests") subgraph Lab Skills python/conditional_statements -.-> lab-398157{{"Comment configurer les interfaces réseau en Python"}} python/importing_modules -.-> lab-398157{{"Comment configurer les interfaces réseau en Python"}} python/using_packages -.-> lab-398157{{"Comment configurer les interfaces réseau en Python"}} python/catching_exceptions -.-> lab-398157{{"Comment configurer les interfaces réseau en Python"}} python/http_requests -.-> lab-398157{{"Comment configurer les interfaces réseau en Python"}} end

Installing Required Python Packages

Before we can work with network interfaces in Python, we need to install the necessary packages. The two primary packages we will use are:

  • netifaces: A cross-platform library for retrieving network interface information
  • psutil: A library for retrieving system information, including network statistics

Let's start by installing these packages using pip.

Installing the Packages

Open a terminal and run the following command to install the required packages:

pip install netifaces psutil

You should see output indicating the packages are being downloaded and installed. Wait until the installation completes before proceeding.

Verifying the Installation

Let's verify that the packages were installed correctly by creating a simple Python script. Create a new file called check_packages.py in the VSCode editor:

  1. Click on the "Explorer" icon in the left sidebar (or press Ctrl+E)
  2. Click the "New File" button
  3. Name the file check_packages.py
  4. Add the following code to the file:
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}")

Save the file by pressing Ctrl+S or selecting "File > Save" from the menu.

Now, run the script by opening a terminal (if not already open) and executing:

python3 check_packages.py

You should see output similar to:

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

The exact version numbers might be different, but as long as you see the "installed successfully" message, you're ready to proceed to the next step.

Listing Network Interfaces

Now that we have the necessary packages installed, let's start exploring network interfaces. The first step is to identify all available network interfaces on your system.

Creating a Script to List Network Interfaces

Create a new file named list_interfaces.py in the VSCode editor:

  1. Click on the "Explorer" icon in the left sidebar if it's not already open
  2. Click the "New File" button
  3. Name the file list_interfaces.py
  4. Add the following code:
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()

Save the file by pressing Ctrl+S.

Running the Script

Now let's run the script to see the list of network interfaces on your system:

python3 list_interfaces.py

You should see output similar to:

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

The exact list will depend on your system configuration. Let's understand what these interfaces typically represent:

  • lo: The loopback interface (localhost)
  • eth0: The primary Ethernet interface
  • wlan0: The primary wireless interface (if available)
  • docker0: The Docker bridge network interface (if Docker is installed)

Understanding Network Interface Names

Network interface names can vary depending on the operating system and configuration:

  • On traditional Linux systems, interfaces are named eth0, eth1, etc., for Ethernet
  • On newer systems using predictable network interface names, you might see names like enp0s3 or ens33
  • Virtual interfaces might have names like veth... or br0 for bridges

Let's modify our script to provide more details about each interface. Update the list_interfaces.py file with the following code:

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

Save the file and run it again:

python3 list_interfaces.py

Now you should see more detailed output that includes the IPv4 address for each 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

This gives us a better understanding of the network interfaces available on the system and their current IP addresses.

Retrieving Detailed Network Interface Information

Now that we can list the available network interfaces, let's create a more comprehensive script to retrieve detailed information about a specific network interface.

Creating a Network Interface Details Script

Create a new file named interface_details.py in the VSCode editor:

  1. Click the "New File" button in the Explorer pane
  2. Name the file interface_details.py
  3. Add the following code:
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)

Save the file by pressing Ctrl+S.

Running the Script

Now let's run the script to see detailed information about a specific network interface:

python3 interface_details.py eth0

Replace eth0 with one of the interfaces you saw in the previous step if needed.

You should see output similar to:

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

You can also run the script without specifying an interface name, and it will automatically select the first non-loopback interface:

python3 interface_details.py

This script provides a comprehensive view of the network interface's configuration, including:

  1. IPv4 address, netmask, and broadcast address
  2. IPv6 address (if available)
  3. MAC address
  4. Default gateway information

Understanding this detailed information is essential for network troubleshooting and configuration.

Exploring the netifaces Module Constants

The netifaces module uses constants to represent different address families. Let's create a quick script to understand these constants. Create a new file named 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)}")

Save and run this script:

python3 netifaces_constants.py

You should see output like:

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

These constants are used in the netifaces module to identify different types of network addresses. Understanding them is helpful when working with the module's functions.

Monitoring Network Interface Traffic

Now that we understand how to retrieve network interface information, let's take it a step further and create a script to monitor network traffic in real-time. This will allow us to see how much data is being sent and received through a specific interface.

Creating a Network Traffic Monitoring Script

Create a new file named monitor_traffic.py in the VSCode editor:

  1. Click the "New File" button in the Explorer pane
  2. Name the file monitor_traffic.py
  3. Add the following code:
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)

Save the file by pressing Ctrl+S.

Running the Traffic Monitoring Script

Now let's run the script to monitor network traffic on a specific interface:

python3 monitor_traffic.py eth0

Replace eth0 with the appropriate interface name from your system if needed.

The script will display a table showing the amount of data sent and received over the network interface, updating once per second for 10 iterations:

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

You can also specify the number of iterations as a second command-line argument:

python3 monitor_traffic.py eth0 5

This would monitor traffic for 5 iterations instead of the default 10.

Generating Some Network Traffic

To see the monitoring script in action with actual traffic, we can open a second terminal and generate some network traffic. Let's create a simple script to do this:

Create a new file named 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)

You'll need to install the requests library first:

pip install requests

Now run the monitoring script in one terminal:

python3 monitor_traffic.py eth0 15

And in a separate terminal, run the traffic generation script:

python3 generate_traffic.py

You should now see the network activity captured by the monitoring script as the traffic generation script makes HTTP requests.

This exercise demonstrates how you can use Python to monitor network interface activity in real-time, which is useful for diagnosing network issues, monitoring bandwidth usage, and understanding network traffic patterns.

Summary

In this lab, you have gained practical experience with Python's network interface management capabilities. Here's what you accomplished:

  1. Set up the environment: You installed and configured the necessary Python packages (netifaces and psutil) for working with network interfaces.

  2. Listed network interfaces: You created a script to identify all available network interfaces on your system and display basic information about them.

  3. Retrieved detailed interface information: You wrote a comprehensive script to extract detailed configuration information from network interfaces, including IP addresses, MAC addresses, and gateway information.

  4. Monitored network traffic: You implemented a real-time network traffic monitoring tool that tracks data sent and received over a specific interface.

These skills form the foundation for more advanced network management tasks in Python, such as:

  • Automating network configuration changes
  • Building network monitoring dashboards
  • Creating network diagnostics tools
  • Developing network security applications

By understanding how to interact with network interfaces programmatically, you now have the capability to build custom networking tools tailored to your specific requirements. This knowledge is especially valuable for system administrators, network engineers, and developers working on networked applications.