0%
Vérifier si une Adresse IP Appartient à un Réseau en Python

Vérifier si une Adresse IP Appartient à un Réseau en Python

Apprenez à vérifier si une adresse IP appartient à un réseau grâce au module ipaddress. Exemples pratiques pour les pare-feu, listes d'autorisation et filtrage réseau.

I

InSkillCoach

· min

Vérifier si une Adresse IP Appartient à un Réseau en Python

Une tâche courante en administration réseau et en sécurité des applications est de déterminer si une adresse IP donnée appartient à un réseau spécifique. Le module ipaddress de Python offre des outils élégants et robustes pour cette vérification. Que vous implémentiez une liste d’autorisation, un pare-feu applicatif ou une validation d’accès, ce guide vous montrera comment maîtriser cette fonctionnalité.

1. Le Module ipaddress

Le module ipaddress est inclus dans la stdlib Python depuis la version 3.3. Il fournit des classes pour représenter et manipuler des adresses IP et des réseaux.

import ipaddress

# Créer une adresse IP
ip = ipaddress.ip_address("192.168.1.100")
print(ip)                 # 192.168.1.100
print(type(ip))           # <class 'ipaddress.IPv4Address'>

# Créer un réseau
reseau = ipaddress.ip_network("192.168.1.0/24")
print(reseau)             # 192.168.1.0/24
print(type(reseau))       # <class 'ipaddress.IPv4Network'>

2. Vérifier l’Appartenance avec l’opérateur in

L’opérateur in teste si une adresse IP appartient à un réseau.

import ipaddress

reseau = ipaddress.ip_network("192.168.1.0/24")

# Tester si des adresses appartiennent au réseau
print("192.168.1.50" in reseau)      # True
print("192.168.2.50" in reseau)      # False
print("10.0.0.1" in reseau)          # False

# Note : l'adresse réseau et l'adresse broadcast font partie du réseau
print("192.168.1.0" in reseau)       # True  (adresse réseau)
print("192.168.1.255" in reseau)     # True  (adresse broadcast)

Fonction réutilisable

import ipaddress

def is_ip_in_network(ip_string, network_string):
    """
    Vérifie si une adresse IP appartient à un réseau.
    
    Args:
        ip_string (str): Adresse IP à vérifier (ex: "192.168.1.50")
        network_string (str): Réseau CIDR (ex: "192.168.1.0/24")
    
    Returns:
        bool: True si l'IP est dans le réseau, False sinon
    """
    try:
        ip = ipaddress.ip_address(ip_string)
        reseau = ipaddress.ip_network(network_string)
        return ip in reseau
    except ValueError as e:
        print(f"Erreur : {e}")
        return False

# Tests
print(is_ip_in_network("192.168.1.100", "192.168.1.0/24"))   # True
print(is_ip_in_network("192.168.2.100", "192.168.1.0/24"))   # False
print(is_ip_in_network("10.0.0.5", "10.0.0.0/8"))            # True

3. Gestion des Erreurs

L’input utilisateur peut être invalide. Il faut capturer les exceptions.

import ipaddress

def verifier_ip_securisee(ip_string, network_string):
    """Vérification robuste avec gestion d'erreur."""
    try:
        ip = ipaddress.ip_address(ip_string)
        reseau = ipaddress.ip_network(network_string, strict=False)
        return ip in reseau
    except ValueError as e:
        print(f"Entrée invalide : {e}")
        return False

# Tests d'erreur
print(verifier_ip_securisee("999.999.999.999", "192.168.1.0/24"))     # ValueError
print(verifier_ip_securisee("192.168.1.a", "192.168.1.0/24"))         # ValueError
print(verifier_ip_securisee("192.168.1.100", "192.168.1.0/999"))      # ValueError
print(verifier_ip_securisee("192.168.1.100", "invalid"))              # ValueError

# Résultat : tous affichent un message d'erreur et retournent False

Paramètre strict=False

Par défaut, ip_network exige que le réseau soit exactement à la limite du bloc CIDR. Avec strict=False, l’adresse réseau est automatiquement recalculée.

import ipaddress

# Strict (par défaut)
try:
    # 192.168.1.100 n'est pas l'adresse réseau de /24
    reseau = ipaddress.ip_network("192.168.1.100/24")
except ValueError as e:
    print(f"Erreur (strict=True) : {e}")
    # Erreur (strict=True) : 192.168.1.100/24 does not have the correct netmask

# Non-strict
reseau = ipaddress.ip_network("192.168.1.100/24", strict=False)
print(reseau)                      # 192.168.1.0/24 (corrigé automatiquement)

4. Comparaison de Réseaux

Le module offre des fonctions pour comparer les réseaux.

import ipaddress

reseau_grand = ipaddress.ip_network("10.0.0.0/8")
reseau_petit = ipaddress.ip_network("10.1.0.0/16")

# Vérifier si un réseau est contenu dans un autre
print(reseau_petit.subnet_of(reseau_grand))      # True
print(reseau_grand.supernet_of(reseau_petit))    # True

# Vérifier l'égalité
reseau_copy = ipaddress.ip_network("10.0.0.0/8")
print(reseau_grand == reseau_copy)               # True

5. IPv6

Le module gère aussi IPv6. La syntaxe est identique.

import ipaddress

# IPv6
reseau_ipv6 = ipaddress.ip_network("2001:db8::/32")
print(reseau_ipv6)                                        # 2001:db8::/32

# Tester l'appartenance
print("2001:db8::1" in reseau_ipv6)               # True
print("2001:db9::1" in reseau_ipv6)               # False

# Adresse link-local (spéciale)
ip_link_local = ipaddress.ip_address("fe80::1")
print(ip_link_local.is_link_local)                # True

6. Cas d’Usage Pratiques

Liste d’autorisation pour un API

import ipaddress
from flask import Flask, request, abort

app = Flask(__name__)

# IPs autorisées (interne + partenaires)
ALLOWED_NETWORKS = [
    ipaddress.ip_network("192.168.0.0/16"),     # Réseau interne
    ipaddress.ip_network("10.0.0.0/8"),         # Réseau principal
    ipaddress.ip_network("203.0.113.0/24"),     # Partenaire A
]

def is_ip_authorized(ip_string):
    """Vérifie si une IP est autorisée."""
    try:
        ip = ipaddress.ip_address(ip_string)
        return any(ip in network for network in ALLOWED_NETWORKS)
    except ValueError:
        return False

@app.before_request
def check_ip():
    """Middleware : bloquer les IPs non autorisées."""
    client_ip = request.remote_addr
    if not is_ip_authorized(client_ip):
        abort(403)  # Accès refusé

@app.route("/api/data")
def get_data():
    return {"data": "Secret"}

# Résultat : seules les IPs dans ALLOWED_NETWORKS accèdent à l'API

Filtrage dans un pare-feu applicatif

import ipaddress

class SimpleFirewall:
    def __init__(self):
        self.blocked_networks = [
            ipaddress.ip_network("203.0.113.0/24"),     # Pays bloqué
            ipaddress.ip_network("198.51.100.0/24"),    # Spam connu
        ]
    
    def is_blocked(self, ip_string):
        """Vérifie si une IP est bloquée."""
        try:
            ip = ipaddress.ip_address(ip_string)
            return any(ip in network for network in self.blocked_networks)
        except ValueError:
            return False
    
    def log_connection(self, ip_string, allowed):
        status = "ALLOWED" if allowed else "BLOCKED"
        print(f"{ip_string} : {status}")

firewall = SimpleFirewall()

test_ips = [
    "192.168.1.1",        # OK
    "203.0.113.50",       # Bloquée
    "198.51.100.100",     # Bloquée
]

for ip in test_ips:
    allowed = not firewall.is_blocked(ip)
    firewall.log_connection(ip, allowed)

7. Bonnes Pratiques

  • Capturez ValueError : l’input réseau peut toujours être invalide.
  • Utilisez strict=False quand vous acceptez l’input utilisateur et que vous voulez être tolérant.
  • Créez les objets réseau une seule fois et réutilisez-les (c’est peu cher en mémoire).
  • Testez les cas limites : adresse réseau, adresse broadcast, adresses spéciales (localhost, link-local, etc.).
  • Loggez les rejets à des fins d’audit et de sécurité.

Conclusion

Le module ipaddress simplifie grandement la vérification d’appartenance d’une IP à un réseau. Grâce à l’opérateur in, au paramètre strict=False, et à la gestion des erreurs robuste, vous disposez de tous les outils nécessaires pour implémenter des listes d’autorisation, des filtres réseau et des politiques d’accès. Que ce soit pour sécuriser une API, gérer un pare-feu applicatif ou filtrer du trafic, cette compétence est essentielle pour tout développeur Python travaillant avec les réseaux.

InSkillCoach

À 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+
526
337

Commentaires

Les commentaires sont alimentés par GitHub Discussions

Connectez-vous avec GitHub pour participer à la discussion

Lien copié !