Escáner de IP LAN
Escáner de IP LAN
Este script de Python escanea una red local en busca de direcciones IP activas. Utiliza el comando ping
para comprobar si un host es accesible y emplea multithreading para acelerar el proceso de escaneo. Un semáforo limita el número de subprocesos concurrentes para evitar sobrecargar el sistema. El script toma una dirección de red (por ejemplo, “192.168.1.0/24”) como entrada e imprime si cada dirección IP de la red está activa o inactiva.
Este script ayuda a identificar dispositivos en la red, como un router mesh TP-LINK que funciona en modo puente cableado, mediante el escaneo de direcciones IP activas.
import subprocess
import ipaddress
import threading
import os
import socket
import argparse
MAX_THREADS = 50 # Número máximo de subprocesos a utilizar
def is_host_up(host, port=None):
"""
Comprueba si un host está activo usando ping o telnet.
Si se especifica el puerto, utiliza telnet para comprobar si el puerto está abierto.
De lo contrario, utiliza ping.
Devuelve True si el host está activo, False en caso contrario.
"""
if port:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex((host, port))
if result == 0:
return True
else:
return False
except socket.error as e:
return False
finally:
sock.close()
else:
try:
# -c 1: Enviar solo 1 paquete
# -W 1: Esperar 1 segundo una respuesta
subprocess.check_output(["ping", "-c", "1", "-W", "1", host], timeout=1)
return True
except subprocess.CalledProcessError:
return False
except subprocess.TimeoutExpired:
return False
def scan_ip(ip_str, up_ips, port=None):
"""
Escanea una sola dirección IP e imprime su estado.
"""
if is_host_up(ip_str, port):
print(f"{ip_str} está activa")
up_ips.append(ip_str)
else:
print(f"{ip_str} está inactiva")
def scan_network(network, port=None):
"""
Escanea una red en busca de hosts activos usando subprocesos, limitando el número de subprocesos concurrentes.
"""
print(f"Escaneando red: {network}")
threads = []
semaphore = threading.Semaphore(MAX_THREADS) # Limita el número de subprocesos concurrentes
up_ips = []
def scan_ip_with_semaphore(ip_str):
semaphore.acquire()
try:
scan_ip(ip_str, up_ips, port)
finally:
semaphore.release()
for ip in ipaddress.IPv4Network(network):
ip_str = str(ip)
thread = threading.Thread(target=scan_ip_with_semaphore, args=(ip_str,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
return up_ips
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Escanea una red en busca de hosts activos.")
parser.add_argument("network", nargs='?', default="192.168.1.0/24", help="La red a escanear (por ejemplo, 192.168.1.0/24)")
parser.add_argument("-p", "--port", type=int, help="El puerto a comprobar (opcional)")
args = parser.parse_args()
network_to_scan = args.network
port_to_scan = args.port
up_ips = scan_network(network_to_scan, port_to_scan)
print("\nIPs activas:")
for ip in up_ips:
print(ip)
Omitiendo IPs locales
El script identifica las direcciones IP activas. Para asegurar una comunicación de red adecuada, verifique que la configuración del proxy esté configurada para omitir estas IPs locales.
192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,127.0.0.1,localhost,*.local,timestamp.apple.com,sequoia.apple.com,seed-sequoia.siri.apple.com, 192.168.1.0/16
Máscaras de subred
Mi segunda máquina suele estar en 192.168.1.16.
Así que funciona usando el siguiente comando.
python scripts/ip_scan.py 192.168.1.0/27 -p 22
porque 32 - 27 = 5, 2^5 = 32, por lo que intentará desde 192.168.1.0
hasta 192.168.1.31
.
Pero no funciona cuando se usa 192.168.1.0/28
, porque 2^4 = 16, por lo que intentará desde 192.168.1.0
hasta 192.168.1.15
, lo que no cubre 192.168.1.16
.