Ping-sweep сети на Python: простой автоматизированный сканер IP
TL;DR
Ниже показано, как автоматизировать ping-sweep (проверку активных IP) в локальной сети на Python. Сначала приведён исторический пример скрипта, затем — улучшенные и безопасные варианты для Python 3 с параллельным запуском и рекомендациями по безопасности и тестированию.
Ключевая идея
Ping-sweep — это последовательная (или параллельная) отправка ICMP-эхо (ping) на диапазон IP-адресов, чтобы определить, какие хосты включены и отвечают. Скрипт реализует цикл по последнему октету подсети /24 и выполняет команду ping для каждого адреса.
Зачем использовать Python
Python присутствует почти на всех дистрибутивах Linux и позволяет автоматизировать системные команды, управлять процессами и обрабатывать вывод. Для сетевого ping‑sweep удобно использовать встроенный модуль subprocess, а для удобства — argparse и concurrent.futures.
Оригинальный (исторический) пример
Ниже — исходный пример из статьи. Это код в стиле Python 2; он демонстрирует идею, но содержит устаревшие приёмы (оператор <> и print без скобок):
import sys, subprocess
if len(sys.argv)<>2:
print "networkmonitor 10.0.0."
else:
cmdping ="ping -c1 "+sys.argv[1]
for x in range(99,110):
p = subprocess.Popen(cmdping+str(x), shell=True, stderr=subprocess.PIPE)
while True:
out = p.stderr.read(1)
if out == '' and p.poll() != None:
break
if out != '':
sys.stdout.write(out)
sys.stdout.flush()Примечание: этот код работал в окружениях, где был Python 2 и разрешалось shell=True. В современных системах лучше использовать Python 3 и более безопасные приёмы.
Почему оригинальный код ограничен и когда он не сработает
- Многие хосты запрещают ICMP: устройство может быть онлайн, но не отвечать на ping.
- Использование shell=True — риск произвольного исполнения команд при ненадёжном вводе.
- Чтение stderr по одному байту и ожидание poll() — сложный способ; проще использовать communicate() или проверять returncode.
- Последовательная проверка больших диапазонов медленная; лучше параллелить.
- На Windows синтаксис ping и ключи отличаются (-n вместо -c).
Рекомендованный современный подход (Python 3)
Ниже — безопасный и портируемый пример для Linux, который:
- использует argparse для аргументов,
- запускает ping через список аргументов (без shell=True),
- параллелит проверки с ThreadPoolExecutor,
- корректно обрабатывает таймауты.
#!/usr/bin/env python3
import argparse
import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed
parser = argparse.ArgumentParser(description='Ping-sweep подсети /24')
parser.add_argument('prefix', help='Первые три октета, например 10.0.0.')
parser.add_argument('--start', type=int, default=1, help='Начальный последний октет')
parser.add_argument('--end', type=int, default=254, help='Конечный последний октет')
parser.add_argument('--workers', type=int, default=50, help='Число потоков')
args = parser.parse_args()
PING_CMD = ['ping', '-c', '1', '-W', '1'] # -W 1: timeout 1 секунда (Linux)
def ping_ip(prefix, last_octet):
ip = f"{prefix}{last_octet}"
try:
proc = subprocess.run(PING_CMD + [ip], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return (ip, proc.returncode == 0)
except Exception:
return (ip, False)
if __name__ == '__main__':
active = []
with ThreadPoolExecutor(max_workers=args.workers) as ex:
futures = {ex.submit(ping_ip, args.prefix, i): i for i in range(args.start, args.end+1)}
for fut in as_completed(futures):
ip, alive = fut.result()
if alive:
print(f"Ответ: {ip}")
active.append(ip)
print(f"Найдено активных хостов: {len(active)}")Советы:
- На Windows замените ключи ping и таймауты (-n и -w).
- Для больших сетей используйте более низкий timeout и больше потоков; следите за нагрузкой.
Альтернативные подходы и инструменты
- nmap — сканер портов с функцией ping-scan (-sn); даёт больше информации, но может не быть установлен.
- zmap — быстрый однодоменный сканер для больших диапазонов; требует привилегий и осторожности.
- Системный arp-scan — полезен для обнаружения соседей в локальной сети без ICMP.
- SNMP/NetBIOS/MDNS — альтернативы для обнаружения устройств, когда ICMP блокирован.
Мини‑методология для безопасного сканирования сети (шаги)
- Убедитесь в праве проводить сканирование (политика организации).
- Запишите диапазон адресов и цель (диагностика/инвентаризация).
- Начните с малого диапазона и короткого таймаута; проверьте нагрузку.
- Параллелизуйте аккуратно — контролируйте число потоков/пакетов в секунду.
- Логируйте результаты и храните их безопасно.
Роль‑ориентированные чек‑листы
- Системный администратор:
- Проверил разрешения на сканирование.
- Запланировал окно с низкой нагрузкой.
- Собрал список известных управляющих хостов, чтобы исключить их.
- Сетевой инженер:
- Контролирует маршрутизацию и VLAN.
- Сравнивает ответы с ARP/таблицами коммутатора.
- Разработчик скрипта:
- Использует безопасные вызовы subprocess.
- Добавляет unit‑тесты и тестовые сценарии.
Тесты и критерии приёмки
Критерии приёмки:
- Скрипт корректно парсит аргумент с префиксом (первые три октета).
- Для контролируемых IP (виртуальные машины) скрипт должен фиксировать ответ.
- Скрипт не падает при недоступности отдельных хостов.
- При увеличении числа workers время работы уменьшается по сравнению с последовательным запуском.
Примеры тестов:
- Тест 1: Локальный интерфейс 127.0.0.1 -> должен ответить.
- Тест 2: Несуществующий адрес в диапазоне -> не должен быть отмечен как живой.
- Тест 3: Блокированный ICMP -> подтвердить поведение через альтернативы (arp-scan).
Безопасность и конфиденциальность
Important: даже внутри корпоративной сети сканирование может нарушать политики или триггерить систему обнаружения угроз. Перед запуском согласуйте действие с командой безопасности. Логи содержат информацию о сети — храните их согласно правилам конфиденциальности.
Миграция и совместимость
- Если у вас Python 2 в системе, настоятельно рекомендуется перейти на Python 3.
- На разных платформах ключи ping различаются; учитывайте это в коде (можно определять platform.system()).
Примеры отказов и способы обхода
- Если ICMP заблокирован: используйте arp-scan, nmap с SYN-пиннинг или опрос сервисов (SNMP, HTTP).
- Если сканирование занимает много времени: уменьшите таймаут, увеличьте количество рабочих потоков, используйте пакетную обработку или специализированный zmap.
Сниппеты и подсказки
- Безопасный запуск subprocess: передайте список аргументов вместо строки, чтобы избежать shell-инъекций.
- Таймауты: явное указание таймаута делает поведение предсказуемым и снижает задержки.
- Лимит параллелизма: не превышайте разумного числа потоков, чтобы не перегрузить сеть.
Скриншот вывода

Скриншот демонстрирует последовательные ответы ping: утилита отправляет один пакет и фиксирует, ответил ли хост.
Краткое резюме
- Python удобен для автоматизации ping-sweep, но используйте современные подходы (argparse, subprocess.run, ThreadPoolExecutor).
- Избегайте shell=True и устаревшего синтаксиса; учитывайте платформозависимые параметры ping.
- Помните про политику безопасности и альтернативные способы обнаружения хостов.
Ключевые выводы:
- Используйте Python 3 и безопасные вызовы subprocess.
- Параллелизация ускорит проверку, но требует контроля.
- При блокировке ICMP применяйте альтернативы (arp-scan, nmap, SNMP).
Авторские права и благодарности Я не претендую на авторство оригинального кода — цель статьи — объяснить идею и показать более современные, безопасные подходы.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента