OSPF маршрут видит, а абонент — нет: как proxy ARP вернул связность на MikroTik

Практический разбор операторской сети с IPoE, PPPoE, OSPF и NAT.
Все названия узлов, интерфейсов и IP-адреса изменены. Для примеров используется документационный диапазон
198.51.100.0/24. Сетевая логика и последовательность диагностики сохранены.
Иногда диагностика выглядит почти издевательски. На MikroTik есть маршрут до нужного адреса. OSPF-соседи в состоянии Full. С самого маршрутизатора цель доступна. Но абонент говорит: «не работает», и он тоже прав.
В нашем случае пакет проигрывал не в OSPF, не в firewall и даже не в NAT. Он вообще не добирался до маршрутизатора: CPE решил, что адрес назначения находится рядом с ним в одном L2-сегменте, отправил ARP-запрос и остался ждать ответа.
Разберём по порядку: как к этому привели общая публичная /24, тысячи изолированных VLAN и arp=reply-only, почему помог proxy-arp, какие побочные эффекты у такого лечения — и уже после разбора кейса пройдёмся по всем режимам ARP в RouterOS как по справочнику.
Исходная схема
В сети было несколько MikroTik-шлюзов. Между ними работал OSPF, через который распространялись абонентские /32 и другие нужные маршруты.
Одновременно на общей uplink-сети использовался публичный блок 198.51.100.0/24. Адреса из него встречались сразу в нескольких ролях:
- IPoE-абоненты в отдельных PON/VLAN-сегментах;
- PPPoE-клиенты с адресом peer
/32; - публичные адреса на uplink, используемые для
src-natиdst-nat; - служебные адреса самих шлюзов.

IPoE-клиенту DHCP выдавал адрес из этого блока, шлюз и маску /24. Физически соседние адреса могли находиться на разных VLAN и даже на разных маршрутизаторах, но CPE об этом не знал: для него весь 198.51.100.0/24 выглядел одной локальной сетью.
Это и было заложенной миной.
Симптом
Типичная жалоба: IPoE-абонент 198.51.100.70 не пингует 198.51.100.123. На шлюзе при этом виден маршрут 198.51.100.123/32, полученный через OSPF.
Логика инженера понятна:
- маршрут есть;
- next hop доступен;
- значит, пакет должен уйти на соседний GW.
Но CPE с маской /24 рассуждает иначе:
- адрес назначения входит в мою локальную сеть;
- шлюз мне не нужен;
- сначала узнаю MAC-адрес
198.51.100.123через ARP.
ARP broadcast остаётся внутри абонентского VLAN. Настоящего владельца адреса там нет. Ответить за него мог бы маршрутизатор, но на интерфейсе был включён arp=reply-only.

Именно поэтому хороший маршрут не помогал: маршрутизация начинается только после того, как CPE сформировал Ethernet-кадр. Без MAC-адреса назначения кадра нет, IP-пакет не уходит со стороны клиента, и OSPF в этой сцене просто не получает реплики.
Что именно делал reply-only
Тут важна аккуратная формулировка. reply-only — не режим «отвечать только за адрес шлюза». В RouterOS он отключает динамическое ARP-обучение и опирается на заранее заданные соответствия IP/MAC в /ip arp. Такой режим часто используют вместе с DHCP add-arp=yes, чтобы неизвестное устройство не могло свободно подменить адрес.
Но reply-only не делает маршрутизатор ARP-посредником для адресов за другими интерфейсами. Валидный клиент может обращаться к самому шлюзу, однако на ARP-запрос о чужом 198.51.100.x маршрутизатор своим MAC не ответит.
Короткая памятка:
| Режим | Что происходит | Где уместен |
|---|---|---|
enabled |
Обычное динамическое ARP-обучение | Стандартный L2-сегмент |
reply-only |
Работа по статическим IP/MAC-записям, без динамического обучения | Контролируемый access с DHCP add-arp=yes или ручными ARP-записями |
proxy-arp |
Роутер отвечает своим MAC за адрес, путь к которому лежит через другой интерфейс | Разнесённые L2-сегменты, которым выдали адреса из общего IP-префикса |
local-proxy-arp |
Роутер проксирует ARP между узлами на одном и том же интерфейсе | Изоляция клиентов внутри общего интерфейса/сегмента |
В нашем кейсе адрес назначения находился за другим интерфейсом, поэтому нужен был именно proxy-arp, а не local-proxy-arp.
Как сработал proxy-arp
Proxy ARP — приём, описанный ещё в RFC 1027: маршрутизатор отвечает своим MAC-адресом на ARP-запросы о тех IP, которые лежат не в этом сегменте, а за другими его интерфейсами, и до которых у него есть маршрут. Хост получает ответ, считает, что цель находится рядом на канальном уровне, и отправляет кадр маршрутизатору. Тот, ничего не меняя в IP-заголовке, делает обычный L3-forwarding.
Важно, что «склейка» происходит не на канальном уровне, а через таблицу маршрутизации: маршрутизатор отвечает не за всё подряд, а только за адреса с активным маршрутом, и только если маршрут указывает не на тот интерфейс, откуда пришёл запрос.
На выбранных абонентских VLAN режим ARP сменили на proxy-arp, и последовательность стала такой:
- CPE спрашивает: «Кто такой
198.51.100.123?» - MikroTik проверяет таблицу маршрутизации и видит путь к адресу через другой интерфейс.
- Маршрутизатор отвечает собственным MAC.
- CPE отправляет Ethernet-кадр на MikroTik, хотя IP-адрес назначения остаётся прежним.
- После этого начинается обычный L3-forwarding: маршрут
/32, OSPF, соседний GW и нужный абонентский интерфейс.

Пример точечной настройки:
/interface vlan print detail where arp=reply-only
/interface vlan set [find where name="access-101"] arp=proxy-arp
/interface vlan print detail where name="access-101"
Соблазн сразу выполнить что-то вроде set [find arp=reply-only] понятен, особенно когда VLAN несколько тысяч. Но сначала нужно определить, какие интерфейсы действительно относятся к этой модели IPoE: reply-only мог быть включён осознанно как часть защиты IP/MAC, а глобальное переключение изменит поведение всей сети доступа.
Если проксировать нужно буквально несколько адресов, RouterOS позволяет создать точечную опубликованную ARP-запись вместо включения proxy ARP для всего интерфейса:
/ip arp add address=198.51.100.123 interface=access-101 published=yes
Устройство ответит за этот IP только при наличии активного маршрута до него. Для тысяч динамически размещённых абонентов такой способ быстро превращается в отдельную систему учёта, но для единичного сервисного адреса он бывает аккуратнее — и, что важно, не отменяет reply-only для остальных адресов сегмента.
Перед массовой правкой стоит:
- сохранить export и список исходных ARP-режимов;
- отобрать интерфейсы по понятным именам, спискам или комментариям;
- проверить один тестовый VLAN;
- убедиться, что фильтры
forwardпо-прежнему обеспечивают нужную изоляцию абонентов; - подготовить обратное переключение для каждого изменяемого интерфейса.
Что получилось после изменения
| Сценарий | До | После proxy-arp на IPoE-VLAN |
|---|---|---|
| IPoE ↔ IPoE, разные VLAN/GW | CPE ждёт ARP, пакет не доходит до GW | CPE отправляет кадр на MAC шлюза, дальше работает L3 |
| PPPoE ↔ PPPoE | Обычно работало через peer /32 |
По сути без изменений |
| PPPoE ↔ IPoE | Часто ломался обратный путь на стороне IPoE | Работает при корректных маршрутах и firewall |
| IPoE ↔ публичный NAT IP | Выглядело как поломка связи двух абонентов | ARP-часть исправлена, но результат всё ещё зависит от NAT/firewall |
Последняя строка таблицы — не формальность: именно на ней разбор чуть не увёл в неверную сторону.
Ловушка: адрес выглядит абонентским, но это NAT
Во время разбора попалась пара адресов, которая сначала казалась идеальным тестом:
198.51.100.70— настоящий IPoE-клиент на одном GW;198.51.100.210— «белый IP», который ожидали увидеть у другого абонента.
Но второй адрес оказался назначен uplink-интерфейсу другого маршрутизатора и использовался как внешний адрес для NAT частного пула. Никакого CPE с адресом .210 не существовало.
Это меняет смысл проверки. Пинг «абонент ↔ абонент» внезапно становится проверкой «IPoE-клиент ↔ адрес самого GW или сервис за dst-nat», а результат зависит уже от правил NAT, firewall и того, есть ли вообще трансляция для ICMP.

Поэтому перед выводом «абоненты друг друга не видят» полезно установить владельца каждого IP:
/ip address print detail where address~"198.51.100.210"
/ip arp print detail where address=198.51.100.210
/ppp active print detail where address=198.51.100.210
/ip firewall nat print detail where dst-address~"198.51.100.210"
А затем проверить, есть ли для него host route и где он был получен.
При чём здесь OSPF
OSPF в этой истории не был причиной поломки — он лишь доставлял между шлюзами информацию о том, где находится конкретный абонентский /32. Но чтобы proxy-arp заработал, должны выполняться два условия:
- нужный
/32действительно должен присутствовать в RIB/FIB выбранного MikroTik; - маршрут должен указывать через другой интерфейс, иначе обычный
proxy-arpне решит задачу.
Для RouterOS v7 маршрут удобно смотреть так:
/routing route print detail where dst-address=198.51.100.123/32
/routing ospf neighbor print detail
В RouterOS v6 таблица маршрутов проверяется через:
/ip route print detail where dst-address=198.51.100.123/32
Если /32 не анонсируется, соседство застряло в ExStart/Exchange или маршрут отфильтрован, proxy-arp проблему не исправит: он помогает клиенту передать пакет маршрутизатору, но маршрут до цели всё равно должен существовать. Это прямое следствие механики режима — решение об ARP-ответе принимается по таблице маршрутизации, поэтому пустая FIB означает тишину в ответ на who-has.
Практический порядок диагностики
Из всего этого сложилась рабочая последовательность.
1. Проверить логику CPE
Посмотреть выданную маску. Если клиент получил /24, он будет ARP-ить любой адрес из этой /24, даже если оператор разнёс адреса по разным VLAN.
2. Посмотреть ARP на access-интерфейсе
/interface vlan print detail where name="access-101"
/tool sniffer quick interface=access-101 mac-protocol=arp
Характерный симптом: от CPE приходит who-has, но ответа за удалённый адрес нет.
3. Проверить маршрут до точного адреса
Смотреть нужно не только общий connected /24, но и специфичный /32. Иначе трафик может уйти на общий uplink или не к тому GW.
4. Установить реального владельца IP
Адрес может принадлежать IPoE-клиенту, PPP-сессии, интерфейсу маршрутизатора, NAT-пулу или вообще быть свободным. Одинаковая запись в заявке «белый IP» ещё не означает одинаковую сетевую сущность.
5. Проверить OSPF и обратный путь
Соседство должно быть Full, нужный /32 — установлен, а обратный маршрут — симметричен или хотя бы допустим правилами firewall и rp-filter.
6. Только после этого включать proxy-arp
Сначала на одном VLAN, затем на небольшой группе, и лишь потом — массово. После изменения проверяются ARP, ping, TCP-сессия и счётчики firewall в обоих направлениях.
Как устроен proxy ARP: режимы RouterOS
Кейс на этом закрыт. Дальше — справочная часть: что именно RouterOS делает с ARP в каждом режиме и почему в нашей ситуации выбор был безальтернативным.
Начать стоит с логики хоста. Собираясь отправить IP-пакет, он сначала решает, «локальный» адрес назначения или нет: применяет свою маску к своему и к целевому адресу. Если адреса попали в одну подсеть, шлюз не используется вовсе — хост рассылает широковещательный ARP-запрос who-has и ждёт, кто отзовётся своим MAC. Ethernet-кадр без MAC назначения не собирается, поэтому при отсутствии ответа никакого IP-трафика просто не появляется.
Proxy ARP в RFC 1027 прямо называли «ARP-хаком» для подсетей: механизм придумали для стеков, которые не умели работать с подсетями. Живёт он ровно по той же причине, что и в нашем кейсе: адреса одной подсети оказались разнесены по разным линкам, VLAN или тоннелям, а хосты об этом не знают. Побочный эффект хорошо видно в ARP-таблице клиента: десятки разных IP там отображаются на один и тот же MAC шлюза.
Теперь по режимам, которые RouterOS позволяет задать на интерфейсе (подробности — в официальной документации по ARP):
enabled— поведение по умолчанию. Маршрутизатор отвечает на запросы о своих адресах, сам рассылаетwho-has, когда нужно, и динамически учит соответствия IP/MAC. Подходит для обычного доверенного сегмента: серверная сеть, офисный LAN, транзитный линк.disabled— ARP на интерфейсе не работает совсем: ни ответов, ни обучения. Связность возможна только со статическими записями в/ip arpс обеих сторон. Применяется в жёстко зафиксированных схемах и на линках, где ARP не нужен по своей природе (PPP-подобные точка-точка).reply-only— компромисс между контролем и удобством: динамического обучения нет, маршрутизатор работает исключительно по статическим и добавленным DHCP-сервером записям. Отсюда и связка с параметромadd-arp=yes: клиент получил адрес по DHCP — запись появилась; сменил IP или MAC вручную — не общается ни с кем. Это ровно тот режим, который и стоял на наших access-VLAN.proxy-arp— маршрутизатор дополнительно отвечает своим MAC за адреса, достижимые через другие интерфейсы. Именно этот режим нужен, когда хосты одной подсети физически раскиданы по разным сегментам, а переделать маску на всех CPE нельзя.local-proxy-arp— маршрутизатор проксирует ARP между узлами того же интерфейса: клиент A спрашивает про клиента B, находящегося в том же VLAN или бридже, и получает MAC шлюза, после чего весь трафик между ними идёт через маршрутизатор. Так делают, когда на L2 включена изоляция портов (bridge horizon, PON client isolation), но соседи всё же должны видеть друг друга — уже под контролем firewall и учёта.
Разница между двумя proxy-режимами — исключительно в том, где находится цель: за другим интерфейсом или в том же сегменте. Подменить один другим не получится, это отдельные значения параметра, и на интерфейсе действует одно из них. Соответственно, включая proxy-arp, вы отказываетесь от строгости reply-only на этом интерфейсе, и защиту от подмены адресов приходится переносить на DHCP snooping, ACL и firewall.
Когда proxy-arp полезен
Несмотря на репутацию «костыля», у режима есть сценарии, где он не просто работает, а является наиболее логичным решением.
- Адреса одной
/24разнесены по разным VLAN и интерфейсам, а CPE считает их локальными — наш случай. Клиент никогда не отправит пакет шлюзу, потому что по своей маске он «уже дома»; единственный способ вклиниться в этот диалог — ответить ему на ARP. - Тоннели и мосты, где удалённая подсеть должна выглядеть локальной. Через EoIP, GRE или IPIP приходят адреса того же префикса, и хостам на одной стороне нужно ARP-разрешать адреса другой; proxy ARP позволяет не растягивать broadcast-домен и не поднимать полноценный L2-мост, оставив стык на маршрутизации.
- Быстрое восстановление связности без миграции адресации. Переразметка сети с
/24на per-subscriber/32— это проект на недели, с перевыпуском DHCP-опций и правкой профилей; включениеproxy-arpна нужных интерфейсах возвращает сервис за минуты и не требует прикасаться к абонентскому оборудованию. - Единичные «белые» адреса и сервисы для устройств с зашитой маской. Старый принтер, терминал или контроллер с жёстко прописанными адресом и
/24физически не умеет ходить через шлюз к соседнему префиксу; proxy ARP (а лучше — точечная опубликованная ARP-запись) делает такой адрес достижимым, не требуя перенастройки самого устройства. - Ситуации, где
local-proxy-arpне подходит. Если цель находится за другим интерфейсом, а не среди соседей по сегменту, локальный вариант не сработает вообще: он рассчитан на проксирование внутри одного интерфейса и не смотрит на маршруты за его пределы.
Цена решения
proxy-arp оказался рабочим операционным исправлением, но он не превращает исходный дизайн в идеальный. Что приходится учитывать:
- маршрутизатор становится обязательным посредником между адресами, которые CPE считает локальными;
- ARP-таблицы и uplink могут стать шумнее;
- при неоднозначной маршрутизации несколько GW способны отвечать за один адрес, поэтому нужны специфичные
/32и аккуратная фильтрация анонсов; - клиентская изоляция теперь должна явно обеспечиваться firewall, а не случайным отсутствием ARP-ответа;
- широкое включение
proxy-arpчастично меняет исходную модель защитыreply-only.
«Костылём» этот режим называют вполне обоснованно. Во-первых, он поощряет клиента ARP-ить весь префикс: каждое новое направление добавляет запись в ARP-кэш CPE и порождает широковещательный запрос в сегменте, а на масштабе тысяч VLAN и десятков тысяч устройств это заметная фоновая нагрузка и раздутые таблицы соседств. Во-вторых, он размывает границу между L2 и L3: логически адреса маршрутизируются, но топология в голове хоста остаётся плоской, из-за чего диагностика перестаёт совпадать со схемой — «локальный» по мнению CPE адрес фактически лежит через два хопа и чужой firewall. В-третьих, страдает изоляция: пока ARP-ответа не было, соседи по префиксу физически не могли достучаться друг до друга, а теперь между ними есть исправно работающий посредник, и единственное, что их разделяет, — правила в forward.
Отдельная категория неприятностей — неоднозначность. Если один и тот же префикс присутствует на нескольких шлюзах, за один и тот же адрес потенциально может ответить не тот маршрутизатор, у которого лучший путь, а тот, чей ARP-ответ пришёл первым; клиент закрепит в кэше «случайный» MAC на время жизни записи. Дальше подключается асимметрия: трафик уходит через одного GW, возвращается через другого, и rp-filter вместе с connection tracking начинают отбрасывать вполне легитимные пакеты, а причина выглядит как «иногда работает, иногда нет». Всё это лечится специфичными /32, аккуратной фильтрацией анонсов OSPF и предсказуемой политикой обратного пути.
И всё же в операторских IPoE-сетях proxy-arp регулярно оказывается единственным быстрым фиксом. Абонентские устройства оператору не принадлежат, маску и шлюз в них меняет только DHCP, а массовое переучивание парка CPE на новую адресную модель — это согласования, окна работ и обращения в поддержку. Когда связность нужна сейчас, а адресация исторически плоская, включение прокси на нужных access-интерфейсах даёт результат в пределах одной сессии в терминале и оставляет время на нормальный редизайн.
Стратегически чище выдавать абоненту /32 с маршрутом через gateway либо использовать адресную модель, в которой CPE не считает весь публичный блок своим L2-сегментом. PPPoE изначально ближе к этой логике: у клиента есть peer, и чужой адрес сразу отправляется маршрутизатору.
Но миграция адресации — отдельный проект. Когда сеть уже построена на общей /24, а простоя быть не должно, точечно включённый proxy-arp позволяет восстановить связность без переделки всех CPE за одну ночь.
Вывод
Главный урок этого случая простой: наличие маршрута ещё не доказывает, что пакет дошёл до уровня маршрутизации. При слишком широкой маске CPE сначала ищет удалённый адрес через ARP, и с reply-only этот запрос остаётся без ответа. proxy-arp подставляет MAC шлюза, после чего уже начинают работать OSPF, NAT и привычная L3-диагностика.
В следующий раз, когда OSPF уверенно показывает нужный /32, а абонент всё равно никого не видит, стоит посмотреть не только route print, но и один скромный who-has, который так и не получил ответа.
Официальная документация MikroTik: ARP и режимы proxy/reply-only, DHCP и параметр add-arp, OSPF в RouterOS, Packet Sniffer, отличия маршрутизации RouterOS v6 и v7. Термин proxy ARP и исходное описание механизма — RFC 1027.

