0%
Verificar se um Endereço IP Pertence a uma Rede em Python

Verificar se um Endereço IP Pertence a uma Rede em Python

Aprenda a verificar se um endereço IP pertence a uma rede usando o módulo ipaddress. Exemplos práticos para firewalls, listas de permissão e filtragem de rede.

I

InSkillCoach

· min

Verificar se um Endereço IP Pertence a uma Rede em Python

Uma tarefa comum em administração de redes e em segurança de aplicações é determinar se um determinado endereço IP pertence a uma rede específica. O módulo ipaddress do Python oferece ferramentas elegantes e robustas para essa verificação. Seja para implementar uma lista de permissão, um firewall de aplicação ou uma validação de acesso, este guia mostrará como dominar essa funcionalidade.

1. O Módulo ipaddress

O módulo ipaddress está incluído na stdlib do Python desde a versão 3.3. Ele fornece classes para representar e manipular endereços IP e redes.

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. Verificar a Pertinência com o operador in

O operador in testa se um endereço IP pertence a uma rede.

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)

Função reutilizável

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. Tratamento de Erros

A entrada do usuário pode ser inválida. É preciso capturar as exceções.

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

Parâmetro strict=False

Por padrão, ip_network exige que a rede esteja exatamente no limite do bloco CIDR. Com strict=False, o endereço de rede é recalculado automaticamente.

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. Comparação de Redes

O módulo oferece funções para comparar redes.

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

O módulo também lida com IPv6. A sintaxe é idêntica.

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. Casos de Uso Práticos

Lista de permissão para uma 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

Filtragem em um firewall de aplicação

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. Boas Práticas

  • Capture ValueError: a entrada de rede pode sempre ser inválida.
  • Use strict=False quando você aceita entrada do usuário e quer ser tolerante.
  • Crie os objetos de rede uma única vez e reutilize-os (o custo em memória é baixo).
  • Teste os casos extremos: endereço de rede, endereço de broadcast, endereços especiais (localhost, link-local etc.).
  • Registre em log as rejeições para fins de auditoria e segurança.

Conclusão

O módulo ipaddress simplifica enormemente a verificação de pertinência de um IP a uma rede. Com o operador in, o parâmetro strict=False e um tratamento de erros robusto, você dispõe de todas as ferramentas necessárias para implementar listas de permissão, filtros de rede e políticas de acesso. Seja para proteger uma API, gerenciar um firewall de aplicação ou filtrar tráfego, essa habilidade é essencial para qualquer desenvolvedor Python que trabalhe com redes.

InSkillCoach

Sobre InSkillCoach

Especialista em treinamento e tecnologias

Coach especializado em tecnologias avançadas e IA, apoiado pela GNeurone Inc.

Certificações:

  • AWS Certified Solutions Architect – Professional
  • Certificações Google Cloud
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
665
159

Comentários

Os comentários são alimentados pelo GitHub Discussions

Conecte-se com o GitHub para participar da discussão

Link copiado!