Автоудаление ошибочных ARP записей на mikrotik

оборудование микротик

Введение: когда ARP-таблица превращается в помойку

Приветствую, коллеги! За 15 лет работы системным администратором я повидал немало «чудес» в сетевой инфраструктуре. Но особое место в моем сердце (и в списке ночных кошмаров) занимают замусоренные ARP-таблицы на MikroTik. Если вы когда-нибудь наблюдали, как ваш роутер медленно превращается в цифровой аналог накопителя, который не может выбросить старые газеты — эта статья для вас.

Проблема проста: устройства в сети постоянно меняются, получают новые IP-адреса, отключаются, но их ARP-записи продолжают жить своей жизнью, как зомби в плохом фильме категории B. Результат? Конфликты адресов, пакеты, улетающие в никуда, и загадочные проблемы с подключением, которые заставляют пользователей думать, что интернет сломался именно из-за них.

Что такое ARP и почему он может испортить вам день

ARP (Address Resolution Protocol) — это протокол, который связывает IP-адреса с MAC-адресами в локальной сети. Представьте, что это телефонная книга вашей сети: вы знаете имя (IP-адрес), но вам нужен номер телефона (MAC-адрес), чтобы позвонить.

Проблема начинается, когда в этой телефонной книге накапливаются записи типа:

  • Устройства, которых уже нет в сети
  • Дублированные записи с одинаковыми IP, но разными MAC
  • Статические записи, которые кто-то добавил в 2015 году и забыл
  • Записи с истекшим сроком действия, которые почему-то не удалились

На MikroTik эта проблема особенно актуальна в сетях с DHCP, где устройства постоянно подключаются и отключаются. Без автоматической очистки ARP-таблица раздувается быстрее, чем ваша коллекция неиспользуемых Docker-образов.

Скрипт автоматической очистки ARP-таблицы

Хватит теории, переходим к практике. Я разработал скрипт, который автоматически находит и удаляет проблемные ARP-записи. Этот скрипт проверяет доступность устройств и удаляет записи для недоступных хостов.

Базовый скрипт очистки:

# Скрипт удаления неактивных ARP записей
:log info "Запуск очистки ARP-таблицы"

:local arpCount 0
:local removedCount 0

# Получаем все динамические ARP записи
:foreach arpEntry in=[/ip arp find dynamic=yes] do={
  :local arpIP [/ip arp get $arpEntry address]
  :local arpMAC [/ip arp get $arpEntry mac-address]
  :set arpCount ($arpCount + 1)
  
  # Пингуем адрес (1 пакет, таймаут 1 секунда)
  :local pingResult [/ping $arpIP count=1 timeout=1s]
  
  # Если хост не отвечает - удаляем запись
  :if ($pingResult = 0) do={
    :log warning "Удаляем неактивную ARP запись: $arpIP ($arpMAC)"
    /ip arp remove $arpEntry
    :set removedCount ($removedCount + 1)
  }
}

:log info "Проверено записей: $arpCount, удалено: $removedCount"

Пять практических примеров для разных сценариев

Пример 1: Очистка с исключением критичных устройств

В реальной сети у вас есть критичные устройства (серверы, принтеры, камеры), которые могут временно не отвечать на пинг, но их ARP-записи удалять нельзя. Добавим белый список:

# Скрипт с исключениями для критичных устройств
:local excludeIPs {"192.168.1.1"; "192.168.1.10"; "192.168.1.20"}
:local removedCount 0

:foreach arpEntry in=[/ip arp find dynamic=yes] do={
  :local arpIP [/ip arp get $arpEntry address]
  :local skip false
  
  # Проверяем, не в белом ли списке IP
  :foreach excludeIP in=$excludeIPs do={
    :if ($arpIP = $excludeIP) do={
      :set skip true
    }
  }
  
  :if (!$skip) do={
    :local pingResult [/ping $arpIP count=1 timeout=1s]
    :if ($pingResult = 0) do={
      :log warning "Удаляем: $arpIP"
      /ip arp remove $arpEntry
      :set removedCount ($removedCount + 1)
    }
  } else={
    :log info "Пропускаем критичный IP: $arpIP"
  }
}

:log info "Удалено записей: $removedCount"

Пример 2: Очистка только старых записей

Иногда устройство может быть временно недоступно (перезагрузка, обновление). Этот скрипт удаляет только записи старше определенного времени:

# Удаление записей старше 30 минут
:local maxAge 00:30:00
:local removedCount 0

:foreach arpEntry in=[/ip arp find dynamic=yes] do={
  :local arpIP [/ip arp get $arpEntry address]
  :local arpAge [/ip arp get $arpEntry age]
  
  # Проверяем возраст записи
  :if ($arpAge > $maxAge) do={
    :local pingResult [/ping $arpIP count=2 timeout=2s]
    
    :if ($pingResult = 0) do={
      :log warning "Удаляем старую запись ($arpAge): $arpIP"
      /ip arp remove $arpEntry
      :set removedCount ($removedCount + 1)
    }
  }
}

:log info "Удалено устаревших записей: $removedCount"

Пример 3: Очистка дублированных записей

Настоящий кошмар — когда один IP-адрес имеет несколько MAC-адресов в таблице. Это почти всегда признак проблемы (IP-конфликт, спуфинг, или просто хаос):

# Поиск и удаление дублей IP с разными MAC
:local ipArray [:toarray ""]
:local duplicates 0

:foreach arpEntry in=[/ip arp find dynamic=yes] do={
  :local arpIP [/ip arp get $arpEntry address]
  :local arpMAC [/ip arp get $arpEntry mac-address]
  
  # Ищем другие записи с тем же IP
  :local sameIP [/ip arp find address=$arpIP dynamic=yes]
  
  :if ([:len $sameIP] > 1) do={
    :log error "Дубликат обнаружен! IP: $arpIP имеет несколько MAC"
    
    # Удаляем все записи кроме самой свежей
    :local newestEntry [/ip arp find address=$arpIP dynamic=yes]
    :local newestAge "99:99:99"
    :local keepEntry ""
    
    :foreach entry in=$newestEntry do={
      :local entryAge [/ip arp get $entry age]
      :if ($entryAge < $newestAge) do={
        :set newestAge $entryAge
        :set keepEntry $entry
      }
    }
    
    # Удаляем старые дубликаты
    :foreach entry in=$newestEntry do={
      :if ($entry != $keepEntry) do={
        :log warning "Удаляем дубликат: $arpIP"
        /ip arp remove $entry
        :set duplicates ($duplicates + 1)
      }
    }
  }
}

:log info "Удалено дубликатов: $duplicates"

Пример 4: Очистка по расписанию с уведомлениями

Автоматизация — наше всё. Этот скрипт можно запускать по расписанию и получать отчеты в Telegram или по email:

# Скрипт с детальной статистикой для отчетов
:local startTime [/system clock get time]
:local totalARP 0
:local activeARP 0
:local removedARP 0
:local report ""

:set totalARP [:len [/ip arp find dynamic=yes]]

:foreach arpEntry in=[/ip arp find dynamic=yes] do={
  :local arpIP [/ip arp get $arpEntry address]
  :local arpMAC [/ip arp get $arpEntry mac-address]
  :local pingResult [/ping $arpIP count=1 timeout=1s]
  
  :if ($pingResult > 0) do={
    :set activeARP ($activeARP + 1)
  } else={
    /ip arp remove $arpEntry
    :set removedARP ($removedARP + 1)
    :set report ($report . "$arpIP ($arpMAC)\n")
  }
}

:local endTime [/system clock get time]

# Формируем отчет
:log info "=== Отчет очистки ARP ==="
:log info "Время выполнения: с $startTime до $endTime"
:log info "Всего записей: $totalARP"
:log info "Активных: $activeARP"
:log info "Удалено: $removedARP"

:if ($removedARP > 0) do={
  :log warning "Удаленные записи:\n$report"
}

# Здесь можно добавить отправку в Telegram/Email
# /tool fetch url="https://api.telegram.org/bot<TOKEN>/sendMessage..."

Пример 5: Умная очистка с проверкой DHCP

Самый продвинутый вариант: проверяем, есть ли у IP-адреса активная DHCP-аренда. Если нет и хост не отвечает — записи точно нужно удалить:

# Очистка с проверкой DHCP-аренд
:local removedCount 0
:local dhcpMismatch 0

:foreach arpEntry in=[/ip arp find dynamic=yes] do={
  :local arpIP [/ip arp get $arpEntry address]
  :local arpMAC [/ip arp get $arpEntry mac-address]
  :local hasLease false
  
  # Проверяем наличие активной DHCP-аренды
  :foreach lease in=[/ip dhcp-server lease find address=$arpIP] do={
    :local leaseMAC [/ip dhcp-server lease get $lease mac-address]
    :if ($leaseMAC = $arpMAC) do={
      :set hasLease true
    } else={
      :log error "MAC не совпадает! ARP: $arpMAC, DHCP: $leaseMAC для IP $arpIP"
      :set dhcpMismatch ($dhcpMismatch + 1)
    }
  }
  
  # Если нет аренды - проверяем доступность
  :if (!$hasLease) do={
    :local pingResult [/ping $arpIP count=2 timeout=2s]
    
    :if ($pingResult = 0) do={
      :log warning "Нет DHCP-аренды и хост не отвечает: $arpIP ($arpMAC)"
      /ip arp remove $arpEntry
      :set removedCount ($removedCount + 1)
    } else={
      :log info "Хост $arpIP активен, но без DHCP-аренды (статический IP?)"
    }
  }
}

:log info "Удалено: $removedCount | Несоответствий MAC: $dhcpMismatch"

Настройка автоматического запуска

Создаем скрипт в System → Scripts и добавляем расписание:

# Создание задачи в планировщике
/system scheduler add \
  name="arp-cleanup" \
  start-time=03:00:00 \
  interval=24h \
  on-event="/system script run arp-cleanup-script"

Я рекомендую запускать очистку ночью (3-4 часа утра), когда сетевая активность минимальна. Частота зависит от размера сети:

  • Маленькая сеть (до 50 устройств) — раз в неделю
  • Средняя сеть (50-200 устройств) — каждые 2-3 дня
  • Большая сеть (200+ устройств) — ежедневно

Мониторинг и отладка

Чтобы понять, работает ли скрипт правильно, используйте логи:

# Просмотр логов выполнения скрипта
/log print where topics~"script"

# Просмотр текущего состояния ARP-таблицы
/ip arp print where dynamic=yes

# Статистика по возрасту записей
/ip arp print stats

Типичные ошибки и как их избежать

Ошибка 1: Слишком агрессивная очистка. Если таймаут пинга слишком короткий (менее 1 секунды), можно удалить записи нормально работающих, но медленно отвечающих устройств.

Решение: Используйте count=2 и timeout=2s для более надежной проверки.

Ошибка 2: Удаление статических записей. Некоторые устройства требуют статических ARP-записей для безопасности.

Решение: Всегда фильтруйте по dynamic=yes в скрипте.

Ошибка 3: Запуск скрипта в часы пик. Массовый пинг всей сети может создать дополнительную нагрузку.

Решение: Планируйте выполнение на ночные часы или выходные.

Заключение: спокойная сеть — счастливый админ

За годы работы я понял одну простую истину: лучшие решения — это те, о которых не нужно помнить. Настроив автоматическую очистку ARP-таблицы, вы забудете о целом классе проблем. Пользователи перестанут жаловаться на «странные глюки с сетью», а вы сможете спокойно пить кофе, вместо того чтобы вручную разбираться с конфликтами адресов.

Помните: сеть, как и код, требует регулярной гигиены. Неочищенная ARP-таблица — это техдолг, который рано или поздно потребует оплаты. И лучше заплатить сейчас временем на настройку автоматизации, чем потом — нервными клетками во время аврала.

Используйте эти скрипты, адаптируйте под свои нужды, и пусть ваши MikroTik‘и работают как швейцарские часы. А если что-то пойдет не так — всегда можно откатиться к бэкапу. У вас же есть бэкапы, правда? Правда?

 

Поделитесь:

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх