<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>mikrotik &amp;mdash; Цифровой дворник</title>
    <link>https://articles.clr58.ru/tag:mikrotik</link>
    <description>Практические заметки о сетях, self-hosting, виртуализации, мониторинге, автоматизации и локальном ИИ.</description>
    <pubDate>Wed, 30 Sep 2026 01:17:22 +0000</pubDate>
    <item>
      <title>OSPF маршрут видит, а абонент — нет: как proxy ARP вернул связность на MikroTik</title>
      <link>https://articles.clr58.ru/mt-ospf-proxy-arp</link>
      <description>&lt;![CDATA[Обложка&#xA;&#xA;Практический разбор операторской сети с IPoE, PPPoE, OSPF и NAT.&#xA;&#xA;  Все названия узлов, интерфейсов и IP-адреса изменены. Для примеров используется документационный диапазон 198.51.100.0/24. Сетевая логика и последовательность диагностики сохранены.&#xA;&#xA;Иногда диагностика выглядит почти издевательски. На MikroTik есть маршрут до нужного адреса. OSPF-соседи в состоянии Full. С самого маршрутизатора цель доступна. Но абонент говорит: «не работает», и он тоже прав.&#xA;&#xA;В нашем случае пакет проигрывал не в OSPF, не в firewall и даже не в NAT. Он вообще не добирался до маршрутизатора: CPE решил, что адрес назначения находится рядом с ним в одном L2-сегменте, отправил ARP-запрос и остался ждать ответа.&#xA;&#xA;Разберём по порядку: как к этому привели общая публичная /24, тысячи изолированных VLAN и arp=reply-only, почему помог proxy-arp, какие побочные эффекты у такого лечения — и уже после разбора кейса пройдёмся по всем режимам ARP в RouterOS как по справочнику.&#xA;&#xA;Исходная схема&#xA;&#xA;В сети было несколько MikroTik-шлюзов. Между ними работал OSPF, через который распространялись абонентские /32 и другие нужные маршруты.&#xA;&#xA;Одновременно на общей uplink-сети использовался публичный блок 198.51.100.0/24. Адреса из него встречались сразу в нескольких ролях:&#xA;&#xA;IPoE-абоненты в отдельных PON/VLAN-сегментах;&#xA;PPPoE-клиенты с адресом peer /32;&#xA;публичные адреса на uplink, используемые для src-nat и dst-nat;&#xA;служебные адреса самих шлюзов.&#xA;&#xA;Упрощённая топология: четыре шлюза, OSPF, IPoE, PPPoE и NAT&#xA;&#xA;IPoE-клиенту DHCP выдавал адрес из этого блока, шлюз и маску /24. Физически соседние адреса могли находиться на разных VLAN и даже на разных маршрутизаторах, но CPE об этом не знал: для него весь 198.51.100.0/24 выглядел одной локальной сетью.&#xA;&#xA;Это и было заложенной миной.&#xA;&#xA;Симптом&#xA;&#xA;Типичная жалоба: IPoE-абонент 198.51.100.70 не пингует 198.51.100.123. На шлюзе при этом виден маршрут 198.51.100.123/32, полученный через OSPF.&#xA;&#xA;Логика инженера понятна:&#xA;&#xA;маршрут есть;&#xA;next hop доступен;&#xA;значит, пакет должен уйти на соседний GW.&#xA;&#xA;Но CPE с маской /24 рассуждает иначе:&#xA;&#xA;адрес назначения входит в мою локальную сеть;&#xA;шлюз мне не нужен;&#xA;сначала узнаю MAC-адрес 198.51.100.123 через ARP.&#xA;&#xA;ARP broadcast остаётся внутри абонентского VLAN. Настоящего владельца адреса там нет. Ответить за него мог бы маршрутизатор, но на интерфейсе был включён arp=reply-only.&#xA;&#xA;До исправления: ARP-запрос остаётся без ответа, а OSPF даже не получает пакет&#xA;&#xA;Именно поэтому хороший маршрут не помогал: маршрутизация начинается только после того, как CPE сформировал Ethernet-кадр. Без MAC-адреса назначения кадра нет, IP-пакет не уходит со стороны клиента, и OSPF в этой сцене просто не получает реплики.&#xA;&#xA;Что именно делал reply-only&#xA;&#xA;Тут важна аккуратная формулировка. reply-only — не режим «отвечать только за адрес шлюза». В RouterOS он отключает динамическое ARP-обучение и опирается на заранее заданные соответствия IP/MAC в /ip arp. Такой режим часто используют вместе с DHCP add-arp=yes, чтобы неизвестное устройство не могло свободно подменить адрес.&#xA;&#xA;Но reply-only не делает маршрутизатор ARP-посредником для адресов за другими интерфейсами. Валидный клиент может обращаться к самому шлюзу, однако на ARP-запрос о чужом 198.51.100.x маршрутизатор своим MAC не ответит.&#xA;&#xA;Короткая памятка:&#xA;&#xA;| Режим | Что происходит | Где уместен |&#xA;|---|---|---|&#xA;| enabled | Обычное динамическое ARP-обучение | Стандартный L2-сегмент |&#xA;| reply-only | Работа по статическим IP/MAC-записям, без динамического обучения | Контролируемый access с DHCP add-arp=yes или ручными ARP-записями |&#xA;| proxy-arp | Роутер отвечает своим MAC за адрес, путь к которому лежит через другой интерфейс | Разнесённые L2-сегменты, которым выдали адреса из общего IP-префикса |&#xA;| local-proxy-arp | Роутер проксирует ARP между узлами на одном и том же интерфейсе | Изоляция клиентов внутри общего интерфейса/сегмента |&#xA;&#xA;В нашем кейсе адрес назначения находился за другим интерфейсом, поэтому нужен был именно proxy-arp, а не local-proxy-arp.&#xA;&#xA;Как сработал proxy-arp&#xA;&#xA;Proxy ARP — приём, описанный ещё в RFC 1027: маршрутизатор отвечает своим MAC-адресом на ARP-запросы о тех IP, которые лежат не в этом сегменте, а за другими его интерфейсами, и до которых у него есть маршрут. Хост получает ответ, считает, что цель находится рядом на канальном уровне, и отправляет кадр маршрутизатору. Тот, ничего не меняя в IP-заголовке, делает обычный L3-forwarding.&#xA;&#xA;Важно, что «склейка» происходит не на канальном уровне, а через таблицу маршрутизации: маршрутизатор отвечает не за всё подряд, а только за адреса с активным маршрутом, и только если маршрут указывает не на тот интерфейс, откуда пришёл запрос.&#xA;&#xA;На выбранных абонентских VLAN режим ARP сменили на proxy-arp, и последовательность стала такой:&#xA;&#xA;CPE спрашивает: «Кто такой 198.51.100.123?»&#xA;MikroTik проверяет таблицу маршрутизации и видит путь к адресу через другой интерфейс.&#xA;Маршрутизатор отвечает собственным MAC.&#xA;CPE отправляет Ethernet-кадр на MikroTik, хотя IP-адрес назначения остаётся прежним.&#xA;После этого начинается обычный L3-forwarding: маршрут /32, OSPF, соседний GW и нужный абонентский интерфейс.&#xA;&#xA;После исправления: MikroTik отвечает своим MAC и передаёт пакет по маршруту&#xA;&#xA;Пример точечной настройки:&#xA;&#xA;/interface vlan print detail where arp=reply-only&#xA;/interface vlan set [find where name=&#34;access-101&#34;] arp=proxy-arp&#xA;/interface vlan print detail where name=&#34;access-101&#34;&#xA;&#xA;Соблазн сразу выполнить что-то вроде set [find arp=reply-only] понятен, особенно когда VLAN несколько тысяч. Но сначала нужно определить, какие интерфейсы действительно относятся к этой модели IPoE: reply-only мог быть включён осознанно как часть защиты IP/MAC, а глобальное переключение изменит поведение всей сети доступа.&#xA;&#xA;Если проксировать нужно буквально несколько адресов, RouterOS позволяет создать точечную опубликованную ARP-запись вместо включения proxy ARP для всего интерфейса:&#xA;&#xA;/ip arp add address=198.51.100.123 interface=access-101 published=yes&#xA;&#xA;Устройство ответит за этот IP только при наличии активного маршрута до него. Для тысяч динамически размещённых абонентов такой способ быстро превращается в отдельную систему учёта, но для единичного сервисного адреса он бывает аккуратнее — и, что важно, не отменяет reply-only для остальных адресов сегмента.&#xA;&#xA;Перед массовой правкой стоит:&#xA;&#xA;сохранить export и список исходных ARP-режимов;&#xA;отобрать интерфейсы по понятным именам, спискам или комментариям;&#xA;проверить один тестовый VLAN;&#xA;убедиться, что фильтры forward по-прежнему обеспечивают нужную изоляцию абонентов;&#xA;подготовить обратное переключение для каждого изменяемого интерфейса.&#xA;&#xA;Что получилось после изменения&#xA;&#xA;| Сценарий | До | После proxy-arp на IPoE-VLAN |&#xA;|---|---|---|&#xA;| IPoE ↔ IPoE, разные VLAN/GW | CPE ждёт ARP, пакет не доходит до GW | CPE отправляет кадр на MAC шлюза, дальше работает L3 |&#xA;| PPPoE ↔ PPPoE | Обычно работало через peer /32 | По сути без изменений |&#xA;| PPPoE ↔ IPoE | Часто ломался обратный путь на стороне IPoE | Работает при корректных маршрутах и firewall |&#xA;| IPoE ↔ публичный NAT IP | Выглядело как поломка связи двух абонентов | ARP-часть исправлена, но результат всё ещё зависит от NAT/firewall |&#xA;&#xA;Последняя строка таблицы — не формальность: именно на ней разбор чуть не увёл в неверную сторону.&#xA;&#xA;Ловушка: адрес выглядит абонентским, но это NAT&#xA;&#xA;Во время разбора попалась пара адресов, которая сначала казалась идеальным тестом:&#xA;&#xA;198.51.100.70 — настоящий IPoE-клиент на одном GW;&#xA;198.51.100.210 — «белый IP», который ожидали увидеть у другого абонента.&#xA;&#xA;Но второй адрес оказался назначен uplink-интерфейсу другого маршрутизатора и использовался как внешний адрес для NAT частного пула. Никакого CPE с адресом .210 не существовало.&#xA;&#xA;Это меняет смысл проверки. Пинг «абонент ↔ абонент» внезапно становится проверкой «IPoE-клиент ↔ адрес самого GW или сервис за dst-nat», а результат зависит уже от правил NAT, firewall и того, есть ли вообще трансляция для ICMP.&#xA;&#xA;Четыре разных сценария, которые снаружи выглядят как связь между адресами одной /24&#xA;&#xA;Поэтому перед выводом «абоненты друг друга не видят» полезно установить владельца каждого IP:&#xA;&#xA;/ip address print detail where address~&#34;198.51.100.210&#34;&#xA;/ip arp print detail where address=198.51.100.210&#xA;/ppp active print detail where address=198.51.100.210&#xA;/ip firewall nat print detail where dst-address~&#34;198.51.100.210&#34;&#xA;&#xA;А затем проверить, есть ли для него host route и где он был получен.&#xA;&#xA;При чём здесь OSPF&#xA;&#xA;OSPF в этой истории не был причиной поломки — он лишь доставлял между шлюзами информацию о том, где находится конкретный абонентский /32. Но чтобы proxy-arp заработал, должны выполняться два условия:&#xA;&#xA;нужный /32 действительно должен присутствовать в RIB/FIB выбранного MikroTik;&#xA;маршрут должен указывать через другой интерфейс, иначе обычный proxy-arp не решит задачу.&#xA;&#xA;Для RouterOS v7 маршрут удобно смотреть так:&#xA;&#xA;/routing route print detail where dst-address=198.51.100.123/32&#xA;/routing ospf neighbor print detail&#xA;&#xA;В RouterOS v6 таблица маршрутов проверяется через:&#xA;&#xA;/ip route print detail where dst-address=198.51.100.123/32&#xA;&#xA;Если /32 не анонсируется, соседство застряло в ExStart/Exchange или маршрут отфильтрован, proxy-arp проблему не исправит: он помогает клиенту передать пакет маршрутизатору, но маршрут до цели всё равно должен существовать. Это прямое следствие механики режима — решение об ARP-ответе принимается по таблице маршрутизации, поэтому пустая FIB означает тишину в ответ на who-has.&#xA;&#xA;Практический порядок диагностики&#xA;&#xA;Из всего этого сложилась рабочая последовательность.&#xA;&#xA;1. Проверить логику CPE&#xA;&#xA;Посмотреть выданную маску. Если клиент получил /24, он будет ARP-ить любой адрес из этой /24, даже если оператор разнёс адреса по разным VLAN.&#xA;&#xA;2. Посмотреть ARP на access-интерфейсе&#xA;&#xA;/interface vlan print detail where name=&#34;access-101&#34;&#xA;/tool sniffer quick interface=access-101 mac-protocol=arp&#xA;&#xA;Характерный симптом: от CPE приходит who-has, но ответа за удалённый адрес нет.&#xA;&#xA;3. Проверить маршрут до точного адреса&#xA;&#xA;Смотреть нужно не только общий connected /24, но и специфичный /32. Иначе трафик может уйти на общий uplink или не к тому GW.&#xA;&#xA;4. Установить реального владельца IP&#xA;&#xA;Адрес может принадлежать IPoE-клиенту, PPP-сессии, интерфейсу маршрутизатора, NAT-пулу или вообще быть свободным. Одинаковая запись в заявке «белый IP» ещё не означает одинаковую сетевую сущность.&#xA;&#xA;5. Проверить OSPF и обратный путь&#xA;&#xA;Соседство должно быть Full, нужный /32 — установлен, а обратный маршрут — симметричен или хотя бы допустим правилами firewall и rp-filter.&#xA;&#xA;6. Только после этого включать proxy-arp&#xA;&#xA;Сначала на одном VLAN, затем на небольшой группе, и лишь потом — массово. После изменения проверяются ARP, ping, TCP-сессия и счётчики firewall в обоих направлениях.&#xA;&#xA;Как устроен proxy ARP: режимы RouterOS&#xA;&#xA;Кейс на этом закрыт. Дальше — справочная часть: что именно RouterOS делает с ARP в каждом режиме и почему в нашей ситуации выбор был безальтернативным.&#xA;&#xA;Начать стоит с логики хоста. Собираясь отправить IP-пакет, он сначала решает, «локальный» адрес назначения или нет: применяет свою маску к своему и к целевому адресу. Если адреса попали в одну подсеть, шлюз не используется вовсе — хост рассылает широковещательный ARP-запрос who-has и ждёт, кто отзовётся своим MAC. Ethernet-кадр без MAC назначения не собирается, поэтому при отсутствии ответа никакого IP-трафика просто не появляется.&#xA;&#xA;Proxy ARP в RFC 1027 прямо называли «ARP-хаком» для подсетей: механизм придумали для стеков, которые не умели работать с подсетями. Живёт он ровно по той же причине, что и в нашем кейсе: адреса одной подсети оказались разнесены по разным линкам, VLAN или тоннелям, а хосты об этом не знают. Побочный эффект хорошо видно в ARP-таблице клиента: десятки разных IP там отображаются на один и тот же MAC шлюза.&#xA;&#xA;Теперь по режимам, которые RouterOS позволяет задать на интерфейсе (подробности — в официальной документации по ARP):&#xA;&#xA;enabled — поведение по умолчанию. Маршрутизатор отвечает на запросы о своих адресах, сам рассылает who-has, когда нужно, и динамически учит соответствия IP/MAC. Подходит для обычного доверенного сегмента: серверная сеть, офисный LAN, транзитный линк.&#xA;disabled — ARP на интерфейсе не работает совсем: ни ответов, ни обучения. Связность возможна только со статическими записями в /ip arp с обеих сторон. Применяется в жёстко зафиксированных схемах и на линках, где ARP не нужен по своей природе (PPP-подобные точка-точка).&#xA;reply-only — компромисс между контролем и удобством: динамического обучения нет, маршрутизатор работает исключительно по статическим и добавленным DHCP-сервером записям. Отсюда и связка с параметром add-arp=yes: клиент получил адрес по DHCP — запись появилась; сменил IP или MAC вручную — не общается ни с кем. Это ровно тот режим, который и стоял на наших access-VLAN.&#xA;proxy-arp — маршрутизатор дополнительно отвечает своим MAC за адреса, достижимые через другие интерфейсы. Именно этот режим нужен, когда хосты одной подсети физически раскиданы по разным сегментам, а переделать маску на всех CPE нельзя.&#xA;local-proxy-arp — маршрутизатор проксирует ARP между узлами того же интерфейса: клиент A спрашивает про клиента B, находящегося в том же VLAN или бридже, и получает MAC шлюза, после чего весь трафик между ними идёт через маршрутизатор. Так делают, когда на L2 включена изоляция портов (bridge horizon, PON client isolation), но соседи всё же должны видеть друг друга — уже под контролем firewall и учёта.&#xA;&#xA;Разница между двумя proxy-режимами — исключительно в том, где находится цель: за другим интерфейсом или в том же сегменте. Подменить один другим не получится, это отдельные значения параметра, и на интерфейсе действует одно из них. Соответственно, включая proxy-arp, вы отказываетесь от строгости reply-only на этом интерфейсе, и защиту от подмены адресов приходится переносить на DHCP snooping, ACL и firewall.&#xA;&#xA;Когда proxy-arp полезен&#xA;&#xA;Несмотря на репутацию «костыля», у режима есть сценарии, где он не просто работает, а является наиболее логичным решением.&#xA;&#xA;Адреса одной /24 разнесены по разным VLAN и интерфейсам, а CPE считает их локальными — наш случай. Клиент никогда не отправит пакет шлюзу, потому что по своей маске он «уже дома»; единственный способ вклиниться в этот диалог — ответить ему на ARP.&#xA;Тоннели и мосты, где удалённая подсеть должна выглядеть локальной. Через EoIP, GRE или IPIP приходят адреса того же префикса, и хостам на одной стороне нужно ARP-разрешать адреса другой; proxy ARP позволяет не растягивать broadcast-домен и не поднимать полноценный L2-мост, оставив стык на маршрутизации.&#xA;Быстрое восстановление связности без миграции адресации. Переразметка сети с /24 на per-subscriber /32 — это проект на недели, с перевыпуском DHCP-опций и правкой профилей; включение proxy-arp на нужных интерфейсах возвращает сервис за минуты и не требует прикасаться к абонентскому оборудованию.&#xA;Единичные «белые» адреса и сервисы для устройств с зашитой маской. Старый принтер, терминал или контроллер с жёстко прописанными адресом и /24 физически не умеет ходить через шлюз к соседнему префиксу; proxy ARP (а лучше — точечная опубликованная ARP-запись) делает такой адрес достижимым, не требуя перенастройки самого устройства.&#xA;Ситуации, где local-proxy-arp не подходит. Если цель находится за другим интерфейсом, а не среди соседей по сегменту, локальный вариант не сработает вообще: он рассчитан на проксирование внутри одного интерфейса и не смотрит на маршруты за его пределы.&#xA;&#xA;Цена решения&#xA;&#xA;proxy-arp оказался рабочим операционным исправлением, но он не превращает исходный дизайн в идеальный. Что приходится учитывать:&#xA;&#xA;маршрутизатор становится обязательным посредником между адресами, которые CPE считает локальными;&#xA;ARP-таблицы и uplink могут стать шумнее;&#xA;при неоднозначной маршрутизации несколько GW способны отвечать за один адрес, поэтому нужны специфичные /32 и аккуратная фильтрация анонсов;&#xA;клиентская изоляция теперь должна явно обеспечиваться firewall, а не случайным отсутствием ARP-ответа;&#xA;широкое включение proxy-arp частично меняет исходную модель защиты reply-only.&#xA;&#xA;«Костылём» этот режим называют вполне обоснованно. Во-первых, он поощряет клиента ARP-ить весь префикс: каждое новое направление добавляет запись в ARP-кэш CPE и порождает широковещательный запрос в сегменте, а на масштабе тысяч VLAN и десятков тысяч устройств это заметная фоновая нагрузка и раздутые таблицы соседств. Во-вторых, он размывает границу между L2 и L3: логически адреса маршрутизируются, но топология в голове хоста остаётся плоской, из-за чего диагностика перестаёт совпадать со схемой — «локальный» по мнению CPE адрес фактически лежит через два хопа и чужой firewall. В-третьих, страдает изоляция: пока ARP-ответа не было, соседи по префиксу физически не могли достучаться друг до друга, а теперь между ними есть исправно работающий посредник, и единственное, что их разделяет, — правила в forward.&#xA;&#xA;Отдельная категория неприятностей — неоднозначность. Если один и тот же префикс присутствует на нескольких шлюзах, за один и тот же адрес потенциально может ответить не тот маршрутизатор, у которого лучший путь, а тот, чей ARP-ответ пришёл первым; клиент закрепит в кэше «случайный» MAC на время жизни записи. Дальше подключается асимметрия: трафик уходит через одного GW, возвращается через другого, и rp-filter вместе с connection tracking начинают отбрасывать вполне легитимные пакеты, а причина выглядит как «иногда работает, иногда нет». Всё это лечится специфичными /32, аккуратной фильтрацией анонсов OSPF и предсказуемой политикой обратного пути.&#xA;&#xA;И всё же в операторских IPoE-сетях proxy-arp регулярно оказывается единственным быстрым фиксом. Абонентские устройства оператору не принадлежат, маску и шлюз в них меняет только DHCP, а массовое переучивание парка CPE на новую адресную модель — это согласования, окна работ и обращения в поддержку. Когда связность нужна сейчас, а адресация исторически плоская, включение прокси на нужных access-интерфейсах даёт результат в пределах одной сессии в терминале и оставляет время на нормальный редизайн.&#xA;&#xA;Стратегически чище выдавать абоненту /32 с маршрутом через gateway либо использовать адресную модель, в которой CPE не считает весь публичный блок своим L2-сегментом. PPPoE изначально ближе к этой логике: у клиента есть peer, и чужой адрес сразу отправляется маршрутизатору.&#xA;&#xA;Но миграция адресации — отдельный проект. Когда сеть уже построена на общей /24, а простоя быть не должно, точечно включённый proxy-arp позволяет восстановить связность без переделки всех CPE за одну ночь.&#xA;&#xA;Вывод&#xA;&#xA;Главный урок этого случая простой: наличие маршрута ещё не доказывает, что пакет дошёл до уровня маршрутизации. При слишком широкой маске CPE сначала ищет удалённый адрес через ARP, и с reply-only этот запрос остаётся без ответа. proxy-arp подставляет MAC шлюза, после чего уже начинают работать OSPF, NAT и привычная L3-диагностика.&#xA;&#xA;В следующий раз, когда OSPF уверенно показывает нужный /32, а абонент всё равно никого не видит, стоит посмотреть не только route print, но и один скромный who-has, который так и не получил ответа.&#xA;&#xA;---&#xA;&#xA;Официальная документация MikroTik: ARP и режимы proxy/reply-only, DHCP и параметр add-arp, OSPF в RouterOS, Packet Sniffer, отличия маршрутизации RouterOS v6 и v7. Термин proxy ARP и исходное описание механизма — RFC 1027.&#xA;&#xA;#network #mikrotik #ospf&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://paste.clr58.ru/post-mt-ospf-proxy-arp-digclean.jpg" alt="Обложка"></p>

<p><em>Практический разбор операторской сети с IPoE, PPPoE, OSPF и NAT.</em></p>

<blockquote><p>Все названия узлов, интерфейсов и IP-адреса изменены. Для примеров используется документационный диапазон <code>198.51.100.0/24</code>. Сетевая логика и последовательность диагностики сохранены.</p></blockquote>

<p>Иногда диагностика выглядит почти издевательски. На MikroTik есть маршрут до нужного адреса. OSPF-соседи в состоянии Full. С самого маршрутизатора цель доступна. Но абонент говорит: «не работает», и он тоже прав.</p>

<p>В нашем случае пакет проигрывал не в OSPF, не в firewall и даже не в NAT. Он вообще не добирался до маршрутизатора: CPE решил, что адрес назначения находится рядом с ним в одном L2-сегменте, отправил ARP-запрос и остался ждать ответа.</p>

<p>Разберём по порядку: как к этому привели общая публичная <code>/24</code>, тысячи изолированных VLAN и <code>arp=reply-only</code>, почему помог <code>proxy-arp</code>, какие побочные эффекты у такого лечения — и уже после разбора кейса пройдёмся по всем режимам ARP в RouterOS как по справочнику.</p>

<h2 id="исходная-схема">Исходная схема</h2>

<p>В сети было несколько MikroTik-шлюзов. Между ними работал OSPF, через который распространялись абонентские <code>/32</code> и другие нужные маршруты.</p>

<p>Одновременно на общей uplink-сети использовался публичный блок <code>198.51.100.0/24</code>. Адреса из него встречались сразу в нескольких ролях:</p>
<ul><li>IPoE-абоненты в отдельных PON/VLAN-сегментах;</li>
<li>PPPoE-клиенты с адресом peer <code>/32</code>;</li>
<li>публичные адреса на uplink, используемые для <code>src-nat</code> и <code>dst-nat</code>;</li>
<li>служебные адреса самих шлюзов.</li></ul>

<p><img src="https://paste.clr58.ru/01-topology.jpg" alt="Упрощённая топология: четыре шлюза, OSPF, IPoE, PPPoE и NAT"></p>

<p>IPoE-клиенту DHCP выдавал адрес из этого блока, шлюз и маску <code>/24</code>. Физически соседние адреса могли находиться на разных VLAN и даже на разных маршрутизаторах, но CPE об этом не знал: для него весь <code>198.51.100.0/24</code> выглядел одной локальной сетью.</p>

<p>Это и было заложенной миной.</p>

<h2 id="симптом">Симптом</h2>

<p>Типичная жалоба: IPoE-абонент <code>198.51.100.70</code> не пингует <code>198.51.100.123</code>. На шлюзе при этом виден маршрут <code>198.51.100.123/32</code>, полученный через OSPF.</p>

<p>Логика инженера понятна:</p>
<ol><li>маршрут есть;</li>
<li>next hop доступен;</li>
<li>значит, пакет должен уйти на соседний GW.</li></ol>

<p>Но CPE с маской <code>/24</code> рассуждает иначе:</p>
<ol><li>адрес назначения входит в мою локальную сеть;</li>
<li>шлюз мне не нужен;</li>
<li>сначала узнаю MAC-адрес <code>198.51.100.123</code> через ARP.</li></ol>

<p>ARP broadcast остаётся внутри абонентского VLAN. Настоящего владельца адреса там нет. Ответить за него мог бы маршрутизатор, но на интерфейсе был включён <code>arp=reply-only</code>.</p>

<p><img src="https://paste.clr58.ru/02-reply-only-problem.jpg" alt="До исправления: ARP-запрос остаётся без ответа, а OSPF даже не получает пакет"></p>

<p>Именно поэтому хороший маршрут не помогал: маршрутизация начинается только после того, как CPE сформировал Ethernet-кадр. Без MAC-адреса назначения кадра нет, IP-пакет не уходит со стороны клиента, и OSPF в этой сцене просто не получает реплики.</p>

<h2 id="что-именно-делал-reply-only">Что именно делал <code>reply-only</code></h2>

<p>Тут важна аккуратная формулировка. <code>reply-only</code> — не режим «отвечать только за адрес шлюза». В RouterOS он отключает динамическое ARP-обучение и опирается на заранее заданные соответствия IP/MAC в <code>/ip arp</code>. Такой режим часто используют вместе с DHCP <code>add-arp=yes</code>, чтобы неизвестное устройство не могло свободно подменить адрес.</p>

<p>Но <code>reply-only</code> <strong>не делает маршрутизатор ARP-посредником для адресов за другими интерфейсами</strong>. Валидный клиент может обращаться к самому шлюзу, однако на ARP-запрос о чужом <code>198.51.100.x</code> маршрутизатор своим MAC не ответит.</p>

<p>Короткая памятка:</p>

<table>
<thead>
<tr>
<th>Режим</th>
<th>Что происходит</th>
<th>Где уместен</th>
</tr>
</thead>

<tbody>
<tr>
<td><code>enabled</code></td>
<td>Обычное динамическое ARP-обучение</td>
<td>Стандартный L2-сегмент</td>
</tr>

<tr>
<td><code>reply-only</code></td>
<td>Работа по статическим IP/MAC-записям, без динамического обучения</td>
<td>Контролируемый access с DHCP <code>add-arp=yes</code> или ручными ARP-записями</td>
</tr>

<tr>
<td><code>proxy-arp</code></td>
<td>Роутер отвечает своим MAC за адрес, путь к которому лежит через другой интерфейс</td>
<td>Разнесённые L2-сегменты, которым выдали адреса из общего IP-префикса</td>
</tr>

<tr>
<td><code>local-proxy-arp</code></td>
<td>Роутер проксирует ARP между узлами на одном и том же интерфейсе</td>
<td>Изоляция клиентов внутри общего интерфейса/сегмента</td>
</tr>
</tbody>
</table>

<p>В нашем кейсе адрес назначения находился <strong>за другим интерфейсом</strong>, поэтому нужен был именно <code>proxy-arp</code>, а не <code>local-proxy-arp</code>.</p>

<h2 id="как-сработал-proxy-arp">Как сработал <code>proxy-arp</code></h2>

<p>Proxy ARP — приём, описанный ещё в <a href="https://datatracker.ietf.org/doc/html/rfc1027">RFC 1027</a>: маршрутизатор отвечает <strong>своим</strong> MAC-адресом на ARP-запросы о тех IP, которые лежат не в этом сегменте, а за другими его интерфейсами, и до которых у него есть маршрут. Хост получает ответ, считает, что цель находится рядом на канальном уровне, и отправляет кадр маршрутизатору. Тот, ничего не меняя в IP-заголовке, делает обычный L3-forwarding.</p>

<p>Важно, что «склейка» происходит не на канальном уровне, а через таблицу маршрутизации: маршрутизатор отвечает не за всё подряд, а только за адреса с активным маршрутом, и только если маршрут указывает не на тот интерфейс, откуда пришёл запрос.</p>

<p>На выбранных абонентских VLAN режим ARP сменили на <code>proxy-arp</code>, и последовательность стала такой:</p>
<ol><li>CPE спрашивает: «Кто такой <code>198.51.100.123</code>?»</li>
<li>MikroTik проверяет таблицу маршрутизации и видит путь к адресу через другой интерфейс.</li>
<li>Маршрутизатор отвечает собственным MAC.</li>
<li>CPE отправляет Ethernet-кадр на MikroTik, хотя IP-адрес назначения остаётся прежним.</li>
<li>После этого начинается обычный L3-forwarding: маршрут <code>/32</code>, OSPF, соседний GW и нужный абонентский интерфейс.</li></ol>

<p><img src="https://paste.clr58.ru/03-proxy-arp-fix.jpg" alt="После исправления: MikroTik отвечает своим MAC и передаёт пакет по маршруту"></p>

<p>Пример точечной настройки:</p>

<pre><code class="language-routeros">/interface vlan print detail where arp=reply-only
/interface vlan set [find where name=&#34;access-101&#34;] arp=proxy-arp
/interface vlan print detail where name=&#34;access-101&#34;
</code></pre>

<p>Соблазн сразу выполнить что-то вроде <code>set [find arp=reply-only]</code> понятен, особенно когда VLAN несколько тысяч. Но сначала нужно определить, какие интерфейсы действительно относятся к этой модели IPoE: <code>reply-only</code> мог быть включён осознанно как часть защиты IP/MAC, а глобальное переключение изменит поведение всей сети доступа.</p>

<p>Если проксировать нужно буквально несколько адресов, RouterOS позволяет создать точечную опубликованную ARP-запись вместо включения proxy ARP для всего интерфейса:</p>

<pre><code class="language-routeros">/ip arp add address=198.51.100.123 interface=access-101 published=yes
</code></pre>

<p>Устройство ответит за этот IP только при наличии активного маршрута до него. Для тысяч динамически размещённых абонентов такой способ быстро превращается в отдельную систему учёта, но для единичного сервисного адреса он бывает аккуратнее — и, что важно, не отменяет <code>reply-only</code> для остальных адресов сегмента.</p>

<p>Перед массовой правкой стоит:</p>
<ul><li>сохранить export и список исходных ARP-режимов;</li>
<li>отобрать интерфейсы по понятным именам, спискам или комментариям;</li>
<li>проверить один тестовый VLAN;</li>
<li>убедиться, что фильтры <code>forward</code> по-прежнему обеспечивают нужную изоляцию абонентов;</li>
<li>подготовить обратное переключение для каждого изменяемого интерфейса.</li></ul>

<h2 id="что-получилось-после-изменения">Что получилось после изменения</h2>

<table>
<thead>
<tr>
<th>Сценарий</th>
<th>До</th>
<th>После <code>proxy-arp</code> на IPoE-VLAN</th>
</tr>
</thead>

<tbody>
<tr>
<td>IPoE ↔ IPoE, разные VLAN/GW</td>
<td>CPE ждёт ARP, пакет не доходит до GW</td>
<td>CPE отправляет кадр на MAC шлюза, дальше работает L3</td>
</tr>

<tr>
<td>PPPoE ↔ PPPoE</td>
<td>Обычно работало через peer <code>/32</code></td>
<td>По сути без изменений</td>
</tr>

<tr>
<td>PPPoE ↔ IPoE</td>
<td>Часто ломался обратный путь на стороне IPoE</td>
<td>Работает при корректных маршрутах и firewall</td>
</tr>

<tr>
<td>IPoE ↔ публичный NAT IP</td>
<td>Выглядело как поломка связи двух абонентов</td>
<td>ARP-часть исправлена, но результат всё ещё зависит от NAT/firewall</td>
</tr>
</tbody>
</table>

<p>Последняя строка таблицы — не формальность: именно на ней разбор чуть не увёл в неверную сторону.</p>

<h2 id="ловушка-адрес-выглядит-абонентским-но-это-nat">Ловушка: адрес выглядит абонентским, но это NAT</h2>

<p>Во время разбора попалась пара адресов, которая сначала казалась идеальным тестом:</p>
<ul><li><code>198.51.100.70</code> — настоящий IPoE-клиент на одном GW;</li>
<li><code>198.51.100.210</code> — «белый IP», который ожидали увидеть у другого абонента.</li></ul>

<p>Но второй адрес оказался назначен uplink-интерфейсу другого маршрутизатора и использовался как внешний адрес для NAT частного пула. Никакого CPE с адресом <code>.210</code> не существовало.</p>

<p>Это меняет смысл проверки. Пинг «абонент ↔ абонент» внезапно становится проверкой «IPoE-клиент ↔ адрес самого GW или сервис за <code>dst-nat</code>», а результат зависит уже от правил NAT, firewall и того, есть ли вообще трансляция для ICMP.</p>

<p><img src="https://paste.clr58.ru/04-scenarios.jpg" alt="Четыре разных сценария, которые снаружи выглядят как связь между адресами одной /24"></p>

<p>Поэтому перед выводом «абоненты друг друга не видят» полезно установить владельца каждого IP:</p>

<pre><code class="language-routeros">/ip address print detail where address~&#34;198.51.100.210&#34;
/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~&#34;198.51.100.210&#34;
</code></pre>

<p>А затем проверить, есть ли для него host route и где он был получен.</p>

<h2 id="при-чём-здесь-ospf">При чём здесь OSPF</h2>

<p>OSPF в этой истории не был причиной поломки — он лишь доставлял между шлюзами информацию о том, где находится конкретный абонентский <code>/32</code>. Но чтобы <code>proxy-arp</code> заработал, должны выполняться два условия:</p>
<ul><li>нужный <code>/32</code> действительно должен присутствовать в RIB/FIB выбранного MikroTik;</li>
<li>маршрут должен указывать через другой интерфейс, иначе обычный <code>proxy-arp</code> не решит задачу.</li></ul>

<p>Для RouterOS v7 маршрут удобно смотреть так:</p>

<pre><code class="language-routeros">/routing route print detail where dst-address=198.51.100.123/32
/routing ospf neighbor print detail
</code></pre>

<p>В RouterOS v6 таблица маршрутов проверяется через:</p>

<pre><code class="language-routeros">/ip route print detail where dst-address=198.51.100.123/32
</code></pre>

<p>Если <code>/32</code> не анонсируется, соседство застряло в <code>ExStart/Exchange</code> или маршрут отфильтрован, <code>proxy-arp</code> проблему не исправит: он помогает клиенту передать пакет маршрутизатору, но маршрут до цели всё равно должен существовать. Это прямое следствие механики режима — решение об ARP-ответе принимается по таблице маршрутизации, поэтому пустая FIB означает тишину в ответ на <code>who-has</code>.</p>

<h2 id="практический-порядок-диагностики">Практический порядок диагностики</h2>

<p>Из всего этого сложилась рабочая последовательность.</p>

<h3 id="1-проверить-логику-cpe">1. Проверить логику CPE</h3>

<p>Посмотреть выданную маску. Если клиент получил <code>/24</code>, он будет ARP-ить любой адрес из этой <code>/24</code>, даже если оператор разнёс адреса по разным VLAN.</p>

<h3 id="2-посмотреть-arp-на-access-интерфейсе">2. Посмотреть ARP на access-интерфейсе</h3>

<pre><code class="language-routeros">/interface vlan print detail where name=&#34;access-101&#34;
/tool sniffer quick interface=access-101 mac-protocol=arp
</code></pre>

<p>Характерный симптом: от CPE приходит <code>who-has</code>, но ответа за удалённый адрес нет.</p>

<h3 id="3-проверить-маршрут-до-точного-адреса">3. Проверить маршрут до точного адреса</h3>

<p>Смотреть нужно не только общий connected <code>/24</code>, но и специфичный <code>/32</code>. Иначе трафик может уйти на общий uplink или не к тому GW.</p>

<h3 id="4-установить-реального-владельца-ip">4. Установить реального владельца IP</h3>

<p>Адрес может принадлежать IPoE-клиенту, PPP-сессии, интерфейсу маршрутизатора, NAT-пулу или вообще быть свободным. Одинаковая запись в заявке «белый IP» ещё не означает одинаковую сетевую сущность.</p>

<h3 id="5-проверить-ospf-и-обратный-путь">5. Проверить OSPF и обратный путь</h3>

<p>Соседство должно быть Full, нужный <code>/32</code> — установлен, а обратный маршрут — симметричен или хотя бы допустим правилами firewall и <code>rp-filter</code>.</p>

<h3 id="6-только-после-этого-включать-proxy-arp">6. Только после этого включать <code>proxy-arp</code></h3>

<p>Сначала на одном VLAN, затем на небольшой группе, и лишь потом — массово. После изменения проверяются ARP, ping, TCP-сессия и счётчики firewall в обоих направлениях.</p>

<h2 id="как-устроен-proxy-arp-режимы-routeros">Как устроен proxy ARP: режимы RouterOS</h2>

<p>Кейс на этом закрыт. Дальше — справочная часть: что именно RouterOS делает с ARP в каждом режиме и почему в нашей ситуации выбор был безальтернативным.</p>

<p>Начать стоит с логики хоста. Собираясь отправить IP-пакет, он сначала решает, «локальный» адрес назначения или нет: применяет свою маску к своему и к целевому адресу. Если адреса попали в одну подсеть, шлюз не используется вовсе — хост рассылает широковещательный ARP-запрос <code>who-has</code> и ждёт, кто отзовётся своим MAC. Ethernet-кадр без MAC назначения не собирается, поэтому при отсутствии ответа никакого IP-трафика просто не появляется.</p>

<p>Proxy ARP в RFC 1027 прямо называли «ARP-хаком» для подсетей: механизм придумали для стеков, которые не умели работать с подсетями. Живёт он ровно по той же причине, что и в нашем кейсе: адреса одной подсети оказались разнесены по разным линкам, VLAN или тоннелям, а хосты об этом не знают. Побочный эффект хорошо видно в ARP-таблице клиента: десятки разных IP там отображаются на один и тот же MAC шлюза.</p>

<p>Теперь по режимам, которые RouterOS позволяет задать на интерфейсе (подробности — в официальной документации по <a href="https://help.mikrotik.com/docs/spaces/ROS/pages/100892687/ARP">ARP</a>):</p>
<ul><li><strong><code>enabled</code></strong> — поведение по умолчанию. Маршрутизатор отвечает на запросы о своих адресах, сам рассылает <code>who-has</code>, когда нужно, и динамически учит соответствия IP/MAC. Подходит для обычного доверенного сегмента: серверная сеть, офисный LAN, транзитный линк.</li>
<li><strong><code>disabled</code></strong> — ARP на интерфейсе не работает совсем: ни ответов, ни обучения. Связность возможна только со статическими записями в <code>/ip arp</code> с обеих сторон. Применяется в жёстко зафиксированных схемах и на линках, где ARP не нужен по своей природе (PPP-подобные точка-точка).</li>
<li><strong><code>reply-only</code></strong> — компромисс между контролем и удобством: динамического обучения нет, маршрутизатор работает исключительно по статическим и добавленным DHCP-сервером записям. Отсюда и связка с параметром <a href="https://help.mikrotik.com/docs/spaces/ROS/pages/24805500/DHCP"><code>add-arp=yes</code></a>: клиент получил адрес по DHCP — запись появилась; сменил IP или MAC вручную — не общается ни с кем. Это ровно тот режим, который и стоял на наших access-VLAN.</li>
<li><strong><code>proxy-arp</code></strong> — маршрутизатор дополнительно отвечает своим MAC за адреса, достижимые через <strong>другие</strong> интерфейсы. Именно этот режим нужен, когда хосты одной подсети физически раскиданы по разным сегментам, а переделать маску на всех CPE нельзя.</li>
<li><strong><code>local-proxy-arp</code></strong> — маршрутизатор проксирует ARP между узлами <strong>того же</strong> интерфейса: клиент A спрашивает про клиента B, находящегося в том же VLAN или бридже, и получает MAC шлюза, после чего весь трафик между ними идёт через маршрутизатор. Так делают, когда на L2 включена изоляция портов (bridge horizon, PON client isolation), но соседи всё же должны видеть друг друга — уже под контролем firewall и учёта.</li></ul>

<p>Разница между двумя proxy-режимами — исключительно в том, где находится цель: за другим интерфейсом или в том же сегменте. Подменить один другим не получится, это отдельные значения параметра, и на интерфейсе действует одно из них. Соответственно, включая <code>proxy-arp</code>, вы отказываетесь от строгости <code>reply-only</code> на этом интерфейсе, и защиту от подмены адресов приходится переносить на DHCP snooping, ACL и firewall.</p>

<h2 id="когда-proxy-arp-полезен">Когда <code>proxy-arp</code> полезен</h2>

<p>Несмотря на репутацию «костыля», у режима есть сценарии, где он не просто работает, а является наиболее логичным решением.</p>
<ul><li><strong>Адреса одной <code>/24</code> разнесены по разным VLAN и интерфейсам, а CPE считает их локальными</strong> — наш случай. Клиент никогда не отправит пакет шлюзу, потому что по своей маске он «уже дома»; единственный способ вклиниться в этот диалог — ответить ему на ARP.</li>
<li><strong>Тоннели и мосты, где удалённая подсеть должна выглядеть локальной.</strong> Через EoIP, GRE или IPIP приходят адреса того же префикса, и хостам на одной стороне нужно ARP-разрешать адреса другой; proxy ARP позволяет не растягивать broadcast-домен и не поднимать полноценный L2-мост, оставив стык на маршрутизации.</li>
<li><strong>Быстрое восстановление связности без миграции адресации.</strong> Переразметка сети с <code>/24</code> на per-subscriber <code>/32</code> — это проект на недели, с перевыпуском DHCP-опций и правкой профилей; включение <code>proxy-arp</code> на нужных интерфейсах возвращает сервис за минуты и не требует прикасаться к абонентскому оборудованию.</li>
<li><strong>Единичные «белые» адреса и сервисы для устройств с зашитой маской.</strong> Старый принтер, терминал или контроллер с жёстко прописанными адресом и <code>/24</code> физически не умеет ходить через шлюз к соседнему префиксу; proxy ARP (а лучше — точечная опубликованная ARP-запись) делает такой адрес достижимым, не требуя перенастройки самого устройства.</li>
<li><strong>Ситуации, где <code>local-proxy-arp</code> не подходит.</strong> Если цель находится за другим интерфейсом, а не среди соседей по сегменту, локальный вариант не сработает вообще: он рассчитан на проксирование внутри одного интерфейса и не смотрит на маршруты за его пределы.</li></ul>

<h2 id="цена-решения">Цена решения</h2>

<p><code>proxy-arp</code> оказался рабочим операционным исправлением, но он не превращает исходный дизайн в идеальный. Что приходится учитывать:</p>
<ul><li>маршрутизатор становится обязательным посредником между адресами, которые CPE считает локальными;</li>
<li>ARP-таблицы и uplink могут стать шумнее;</li>
<li>при неоднозначной маршрутизации несколько GW способны отвечать за один адрес, поэтому нужны специфичные <code>/32</code> и аккуратная фильтрация анонсов;</li>
<li>клиентская изоляция теперь должна явно обеспечиваться firewall, а не случайным отсутствием ARP-ответа;</li>
<li>широкое включение <code>proxy-arp</code> частично меняет исходную модель защиты <code>reply-only</code>.</li></ul>

<p>«Костылём» этот режим называют вполне обоснованно. Во-первых, он поощряет клиента ARP-ить весь префикс: каждое новое направление добавляет запись в ARP-кэш CPE и порождает широковещательный запрос в сегменте, а на масштабе тысяч VLAN и десятков тысяч устройств это заметная фоновая нагрузка и раздутые таблицы соседств. Во-вторых, он размывает границу между L2 и L3: логически адреса маршрутизируются, но топология в голове хоста остаётся плоской, из-за чего диагностика перестаёт совпадать со схемой — «локальный» по мнению CPE адрес фактически лежит через два хопа и чужой firewall. В-третьих, страдает изоляция: пока ARP-ответа не было, соседи по префиксу физически не могли достучаться друг до друга, а теперь между ними есть исправно работающий посредник, и единственное, что их разделяет, — правила в <code>forward</code>.</p>

<p>Отдельная категория неприятностей — неоднозначность. Если один и тот же префикс присутствует на нескольких шлюзах, за один и тот же адрес потенциально может ответить не тот маршрутизатор, у которого лучший путь, а тот, чей ARP-ответ пришёл первым; клиент закрепит в кэше «случайный» MAC на время жизни записи. Дальше подключается асимметрия: трафик уходит через одного GW, возвращается через другого, и <code>rp-filter</code> вместе с connection tracking начинают отбрасывать вполне легитимные пакеты, а причина выглядит как «иногда работает, иногда нет». Всё это лечится специфичными <code>/32</code>, аккуратной фильтрацией анонсов OSPF и предсказуемой политикой обратного пути.</p>

<p>И всё же в операторских IPoE-сетях <code>proxy-arp</code> регулярно оказывается единственным быстрым фиксом. Абонентские устройства оператору не принадлежат, маску и шлюз в них меняет только DHCP, а массовое переучивание парка CPE на новую адресную модель — это согласования, окна работ и обращения в поддержку. Когда связность нужна сейчас, а адресация исторически плоская, включение прокси на нужных access-интерфейсах даёт результат в пределах одной сессии в терминале и оставляет время на нормальный редизайн.</p>

<p>Стратегически чище выдавать абоненту <code>/32</code> с маршрутом через gateway либо использовать адресную модель, в которой CPE не считает весь публичный блок своим L2-сегментом. PPPoE изначально ближе к этой логике: у клиента есть peer, и чужой адрес сразу отправляется маршрутизатору.</p>

<p>Но миграция адресации — отдельный проект. Когда сеть уже построена на общей <code>/24</code>, а простоя быть не должно, точечно включённый <code>proxy-arp</code> позволяет восстановить связность без переделки всех CPE за одну ночь.</p>

<h2 id="вывод">Вывод</h2>

<p>Главный урок этого случая простой: наличие маршрута ещё не доказывает, что пакет дошёл до уровня маршрутизации. При слишком широкой маске CPE сначала ищет удалённый адрес через ARP, и с <code>reply-only</code> этот запрос остаётся без ответа. <code>proxy-arp</code> подставляет MAC шлюза, после чего уже начинают работать OSPF, NAT и привычная L3-диагностика.</p>

<p>В следующий раз, когда OSPF уверенно показывает нужный <code>/32</code>, а абонент всё равно никого не видит, стоит посмотреть не только <code>route print</code>, но и один скромный <code>who-has</code>, который так и не получил ответа.</p>

<hr>

<p>Официальная документация MikroTik: <a href="https://help.mikrotik.com/docs/spaces/ROS/pages/100892687/ARP">ARP и режимы proxy/reply-only</a>, <a href="https://help.mikrotik.com/docs/spaces/ROS/pages/24805500/DHCP">DHCP и параметр add-arp</a>, <a href="https://help.mikrotik.com/docs/spaces/ROS/pages/9863229/OSPF">OSPF в RouterOS</a>, <a href="https://help.mikrotik.com/docs/spaces/ROS/pages/8323088/Packet%2BSniffer">Packet Sniffer</a>, <a href="https://help.mikrotik.com/docs/spaces/ROS/pages/30474256/Moving%2Bfrom%2BROSv6%2Bto%2Bv7%2Bwith%2Bexamples">отличия маршрутизации RouterOS v6 и v7</a>. Термин proxy ARP и исходное описание механизма — <a href="https://datatracker.ietf.org/doc/html/rfc1027">RFC 1027</a>.</p>

<p><a href="https://articles.clr58.ru/tag:network" class="hashtag"><span>#</span><span class="p-category">network</span></a> <a href="https://articles.clr58.ru/tag:mikrotik" class="hashtag"><span>#</span><span class="p-category">mikrotik</span></a> <a href="https://articles.clr58.ru/tag:ospf" class="hashtag"><span>#</span><span class="p-category">ospf</span></a></p>
]]></content:encoded>
      <guid>https://articles.clr58.ru/mt-ospf-proxy-arp</guid>
      <pubDate>Tue, 08 Sep 2026 17:09:36 +0000</pubDate>
    </item>
    <item>
      <title>Свой DNS с блокировкой рекламы: AdGuard Home + MikroTik</title>
      <link>https://articles.clr58.ru/adguard-home-mikrotik</link>
      <description>&lt;![CDATA[Обложка&#xA;&#xA;Реклама на сайтах бесит — это факт. Ставить блокировщик в каждый браузер и на каждый телефон лень, а хочется, чтобы резалось сразу для всей домашней сети: и ноутбук, и телевизор, и гостевой Wi-Fi.&#xA;&#xA;Решение подсмотрел у ребят из Fatmetal — у них есть разбор, как поднять AdGuard Home на VPS с шифрованным DNS. Идея зашла, но я пошёл чуть дальше: вместо «DNS для телефона в любой сети» сделал «DNS для всей домашней сети через роутер». Дальше — что получилось, на какие грабли наступил и почему результат честно не стопроцентный.&#xA;&#xA;Что вообще за AdGuard Home&#xA;&#xA;Это DNS-сервер с фильтрацией. Он принимает запросы от клиентов, сверяет домены со списками блокировки и возвращает 0.0.0.0 для рекламы и трекеров. Всё, что не заблокировано, форвардит наверх — в моём случае на Quad9.&#xA;&#xA;Работает на уровне сети: не нужно ставить приложения на каждое устройство. Телевизор, лампочки, приставка — всё, что ходит через этот DNS, автоматически получает чистый интернет.&#xA;&#xA;Один бинарник на Go, ~43 MiB RAM в простое, конфиг — один YAML. Очень лёгкий.&#xA;&#xA;Схема у меня&#xA;&#xA;LAN-клиенты (192.168.x.x)&#xA;    ↓ DNS по DHCP = роутер&#xA;MikroTik (роутер)&#xA;    ↓ DoH (DNS over HTTPS)&#xA;dns.example (Caddy, валидный TLS)&#xA;    ↓ reverseproxy&#xA;AdGuard Home (LXC, 10.0.0.22)&#xA;    ↓ апстрим DoH&#xA;Quad9 (9.9.9.9)&#xA;&#xA;Клиенты даже не знают, что существует AdGuard: по DHCP они получают адрес роутера, а роутер уже сам ходит на наш DNS через шифрованный DoH. Одна настройка на роутере — и вся сеть фильтруется.&#xA;&#xA;Как ставил&#xA;&#xA;Шаг 1. AdGuard Home в LXC. У меня Proxmox, поэтому поднял отдельный контейнер: Ubuntu 26.04, один бинарник AdGuard Home v0.107.79 в /opt/AdGuardHome, systemd-сервис.&#xA;&#xA;Первая засада: вручную написанный YAML сервис не принял («cannot construct !!seq into home.clientsConfig») — в свежих версиях схема конфига поменялась. Лечится просто: запустил AdGuard без конфига, он сам поднял мастер на порту 3000, я прошёл его через API — и только потом доправил YAML под себя. Урок: не пишите конфиг руками, дайте сервису сгенерить.&#xA;&#xA;Шаг 2. DoH. По задумке у Fatmetal AdGuard сам терминирует TLS (DoH на 443, DoT/DoQ на 853). Я попробовал так же — и упёрся в то, что самоподписанный сертификат AdGuard отвергает («validating certificate pair: empty certificate»). А выпускать Let&#39;s Encrypt на сам AdGuard — лишняя возня, когда у меня уже есть Caddy, который умеет TLS из коробки.&#xA;&#xA;Поэтому схему упростил: TLS терминирует Caddy на поддомене dns.example, а внутри сети гонит plain HTTP на AdGuard (у него есть режим insecure DoH ровно для reverse-proxy). Снаружи клиент видит валидный сертификат, внутри — ничего шифровать не надо.&#xA;&#xA;Шаг 3. MikroTik. На роутере одна команда:&#xA;&#xA;/ip dns set use-doh-server=&#34;https://dns.example/dns-query&#34; servers=&#34;9.9.9.9,149.112.112.112&#34;&#xA;&#xA;servers оставил как фолбек: если наш DNS ляжет — роутер продолжит резолвить через Quad9 напрямую. DNS — критичный сервис, если он умрёт, «пропадёт интернет» на всех устройствах. Поэтому фолбек обязателен.&#xA;&#xA;Грабли, на которые наступил&#xA;&#xA;Грабля №1: роутер не может ходить на свой же внешний IP. MikroTik резолвил dns.example в свой WAN-адрес, шёл на него сам — и ничего не работало (hairpin NAT для собственного трафика не действует). Решение: статическая запись на роутере, которая ведёт dns.example прямо на Caddy через WireGuard-туннель:&#xA;&#xA;/ip dns static add name=&#34;dns.example&#34; address=10.99.0.2 comment=&#34;adguard-doh-via-wg&#34;&#xA;&#xA;Грабля №2: allow-remote-requests=no ломает DNS для всей LAN. Я решил «закрыть порт 53 наружу» этой настройкой — и клиенты в локалке перестали резолвить вообще. На RouterOS 7 эта опция отключает ответы DNS-сервера не только снаружи, но и для локальных сетей. Вернул yes, а снаружи порт 53 закрыл штатно — правилом firewall. Урок: на MikroTik не закрывайте DNS через allow-remote-requests, только через firewall.&#xA;&#xA;Грабля №3: белый список внутри фильтра. Домен www.googleadservices.com (это Google Ads) упорно проходил — в самом списке AdGuard DNS filter оказалось whitelist-правило @@||www.googleadservices.com^|. Обычное правило блокировки его не перебивало. Лечится модификатором $important, который имеет приоритет над whitelist:&#xA;&#xA;||www.googleadservices.com^$important&#xA;&#xA;Грабля №4: кэш. После добавления правил реклама всё равно видна — потому что телефон и браузер закешировали реальные IP рекламных доменов ещё до блокировки. Инкогнито помогает от кэша браузера, но не от DNS-кэша ОС. Лечится временем или перезагрузкой устройства.&#xA;&#xA;Что добавил для отечественной рекламы&#xA;&#xA;Базовый список AdGuard DNS filter (178 тысяч правил) — хорошо, но российские рекламные сети в нём покрыты не полностью. Дописал свои правила в userrules:&#xA;&#xA;ads.adfox.ru, adfox.ru — AdFox, рекламная сеть Яндекса (баннеры на новостных сайтах)&#xA;an.yandex.ru, yabs.yandex.ru — Яндекс.Директ&#xA;24smi.net — виджеты и видео 24СМИ&#xA;top-fwz1.mail.ru — счётчик Mail.ru&#xA;counter.yadro.ru — счётчик Яндекс.Метрики (спорно: это аналитика, но она же трекинг)&#xA;wcm.weborama-tech.ru — Weborama&#xA;ad.adriver.ru — AdRiver&#xA;&#xA;Проверял на живых сайтах: rzn.info, 7info.ru — после правок их рекламные домены резолвятся в 0.0.0.0.&#xA;&#xA;А теперь честно про результат&#xA;&#xA;Работает: вся реклама, которая живёт на отдельных доменах (AdFox, Директ, 24СМИ, Google Ads), режется на уровне DNS для всех устройств в сети разом. Это, кстати, большая часть того, что бесит на новостных сайтах.&#xA;&#xA;Не работает:&#xA;Реклама с CDN самого сайта. Часть баннеров новостники отдают со своих же доменов (cdn1.rzn.info и т.п.). DNS-фильтр не может отличить рекламу от контента на одном домене — иначе сломает весь сайт.&#xA;Яндекс.Директ через yandex.ru/ads. Скрипт грузится с основного домена Яндекса как путь (/ads/system/context.js). Заблокировать весь yandex.ru нельзя — это же сам Яндекс. DNS тут бессилен в принципе.&#xA;Видеореклама на плеерах — если ролик идёт с того же домена, что и само видео, DNS не поможет.&#xA;YouTube — реклама с тех же доменов, что и контент. DNS-фильтр это не берёт, нужен uBlock Origin или подобное.&#xA;&#xA;Итого: DNS-фильтр закрывает, грубо, 70–80% раздражающей рекламы — всю, что на отдельных доменах. Остальное — это либо реклама с контентных CDN, либо встроенная в страницу, где DNS в принципе не может отличить. Для полной чистки в браузере всё равно нужен uBlock Origin.&#xA;&#xA;Вывод&#xA;&#xA;Для домашней сети связка «MikroTik + AdGuard Home через DoH» — это лучший баланс: одна настройка на роутере, вся сеть фильтруется, ничего не надо ставить на устройства. Но честно: это не 100% — DNS-блокировка по определению не режет рекламу с тех же доменов, что и контент.&#xA;&#xA;Подход и первые шаги подсмотрел у Fatmetal — у них хороший разбор, рекомендую. А грабли с MikroTik, whitelist&#39;ом и отечественной рекламой — уже мои, делюсь, чтобы вы не наступали.&#xA;&#xA;А у вас что режет рекламу дома — DNS на роутере, uBlock, или всё вместе?&#xA;&#xA;#selfhosting #network #dns #adguard #mikrotik #privacy&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://paste.clr58.ru/post-adguard-home-digclean.jpg" alt="Обложка"></p>

<p>Реклама на сайтах бесит — это факт. Ставить блокировщик в каждый браузер и на каждый телефон лень, а хочется, чтобы резалось сразу для всей домашней сети: и ноутбук, и телевизор, и гостевой Wi-Fi.</p>

<p>Решение подсмотрел у ребят из <a href="https://fatmetal.ru/knowledge-base/adguard">Fatmetal</a> — у них есть разбор, как поднять AdGuard Home на VPS с шифрованным DNS. Идея зашла, но я пошёл чуть дальше: вместо «DNS для телефона в любой сети» сделал «DNS для всей домашней сети через роутер». Дальше — что получилось, на какие грабли наступил и почему результат честно не стопроцентный.</p>

<h2 id="что-вообще-за-adguard-home">Что вообще за AdGuard Home</h2>

<p>Это DNS-сервер с фильтрацией. Он принимает запросы от клиентов, сверяет домены со списками блокировки и возвращает <code>0.0.0.0</code> для рекламы и трекеров. Всё, что не заблокировано, форвардит наверх — в моём случае на Quad9.</p>

<p>Работает на уровне сети: не нужно ставить приложения на каждое устройство. Телевизор, лампочки, приставка — всё, что ходит через этот DNS, автоматически получает чистый интернет.</p>

<p>Один бинарник на Go, ~43 MiB RAM в простое, конфиг — один YAML. Очень лёгкий.</p>

<h2 id="схема-у-меня">Схема у меня</h2>

<pre><code>LAN-клиенты (192.168.x.x)
    ↓ DNS по DHCP = роутер
MikroTik (роутер)
    ↓ DoH (DNS over HTTPS)
dns.example (Caddy, валидный TLS)
    ↓ reverse_proxy
AdGuard Home (LXC, 10.0.0.22)
    ↓ апстрим DoH
Quad9 (9.9.9.9)
</code></pre>

<p>Клиенты даже не знают, что существует AdGuard: по DHCP они получают адрес роутера, а роутер уже сам ходит на наш DNS через шифрованный DoH. Одна настройка на роутере — и вся сеть фильтруется.</p>

<h2 id="как-ставил">Как ставил</h2>

<p><strong>Шаг 1. AdGuard Home в LXC.</strong> У меня Proxmox, поэтому поднял отдельный контейнер: Ubuntu 26.04, один бинарник AdGuard Home v0.107.79 в <code>/opt/AdGuardHome</code>, systemd-сервис.</p>

<p>Первая засада: вручную написанный YAML сервис не принял («cannot construct !!seq into home.clientsConfig») — в свежих версиях схема конфига поменялась. Лечится просто: запустил AdGuard без конфига, он сам поднял мастер на порту 3000, я прошёл его через API — и только потом доправил YAML под себя. Урок: не пишите конфиг руками, дайте сервису сгенерить.</p>

<p><strong>Шаг 2. DoH.</strong> По задумке у Fatmetal AdGuard сам терминирует TLS (DoH на 443, DoT/DoQ на 853). Я попробовал так же — и упёрся в то, что самоподписанный сертификат AdGuard отвергает («validating certificate pair: empty certificate»). А выпускать Let&#39;s Encrypt на сам AdGuard — лишняя возня, когда у меня уже есть Caddy, который умеет TLS из коробки.</p>

<p>Поэтому схему упростил: <strong>TLS терминирует Caddy</strong> на поддомене <code>dns.example</code>, а внутри сети гонит plain HTTP на AdGuard (у него есть режим <code>insecure</code> DoH ровно для reverse-proxy). Снаружи клиент видит валидный сертификат, внутри — ничего шифровать не надо.</p>

<p><strong>Шаг 3. MikroTik.</strong> На роутере одна команда:</p>

<pre><code>/ip dns set use-doh-server=&#34;https://dns.example/dns-query&#34; servers=&#34;9.9.9.9,149.112.112.112&#34;
</code></pre>

<p><code>servers</code> оставил как фолбек: если наш DNS ляжет — роутер продолжит резолвить через Quad9 напрямую. DNS — критичный сервис, если он умрёт, «пропадёт интернет» на всех устройствах. Поэтому фолбек обязателен.</p>

<h2 id="грабли-на-которые-наступил">Грабли, на которые наступил</h2>

<p><strong>Грабля №1: роутер не может ходить на свой же внешний IP.</strong> MikroTik резолвил <code>dns.example</code> в свой WAN-адрес, шёл на него сам — и ничего не работало (hairpin NAT для собственного трафика не действует). Решение: статическая запись на роутере, которая ведёт <code>dns.example</code> прямо на Caddy через WireGuard-туннель:</p>

<pre><code>/ip dns static add name=&#34;dns.example&#34; address=10.99.0.2 comment=&#34;adguard-doh-via-wg&#34;
</code></pre>

<p><strong>Грабля №2: <code>allow-remote-requests=no</code> ломает DNS для всей LAN.</strong> Я решил «закрыть порт 53 наружу» этой настройкой — и клиенты в локалке перестали резолвить вообще. На RouterOS 7 эта опция отключает ответы DNS-сервера не только снаружи, но и для локальных сетей. Вернул <code>yes</code>, а снаружи порт 53 закрыл штатно — правилом firewall. Урок: на MikroTik не закрывайте DNS через <code>allow-remote-requests</code>, только через firewall.</p>

<p><strong>Грабля №3: белый список внутри фильтра.</strong> Домен <code>www.googleadservices.com</code> (это Google Ads) упорно проходил — в самом списке AdGuard DNS filter оказалось whitelist-правило <code>@@||www.googleadservices.com^|</code>. Обычное правило блокировки его не перебивало. Лечится модификатором <code>$important</code>, который имеет приоритет над whitelist:</p>

<pre><code>||www.googleadservices.com^$important
</code></pre>

<p><strong>Грабля №4: кэш.</strong> После добавления правил реклама всё равно видна — потому что телефон и браузер закешировали реальные IP рекламных доменов ещё до блокировки. Инкогнито помогает от кэша браузера, но не от DNS-кэша ОС. Лечится временем или перезагрузкой устройства.</p>

<h2 id="что-добавил-для-отечественной-рекламы">Что добавил для отечественной рекламы</h2>

<p>Базовый список AdGuard DNS filter (178 тысяч правил) — хорошо, но российские рекламные сети в нём покрыты не полностью. Дописал свои правила в user_rules:</p>
<ul><li><code>ads.adfox.ru</code>, <code>adfox.ru</code> — AdFox, рекламная сеть Яндекса (баннеры на новостных сайтах)</li>
<li><code>an.yandex.ru</code>, <code>yabs.yandex.ru</code> — Яндекс.Директ</li>
<li><code>24smi.net</code> — виджеты и видео 24СМИ</li>
<li><code>top-fwz1.mail.ru</code> — счётчик Mail.ru</li>
<li><code>counter.yadro.ru</code> — счётчик Яндекс.Метрики (спорно: это аналитика, но она же трекинг)</li>
<li><code>wcm.weborama-tech.ru</code> — Weborama</li>
<li><code>ad.adriver.ru</code> — AdRiver</li></ul>

<p>Проверял на живых сайтах: <code>rzn.info</code>, <code>7info.ru</code> — после правок их рекламные домены резолвятся в <code>0.0.0.0</code>.</p>

<h2 id="а-теперь-честно-про-результат">А теперь честно про результат</h2>

<p><strong>Работает:</strong> вся реклама, которая живёт на отдельных доменах (AdFox, Директ, 24СМИ, Google Ads), режется на уровне DNS для всех устройств в сети разом. Это, кстати, большая часть того, что бесит на новостных сайтах.</p>

<p><strong>Не работает:</strong>
– <strong>Реклама с CDN самого сайта.</strong> Часть баннеров новостники отдают со своих же доменов (<code>cdn1.rzn.info</code> и т.п.). DNS-фильтр не может отличить рекламу от контента на одном домене — иначе сломает весь сайт.
– <strong>Яндекс.Директ через <code>yandex.ru/ads</code>.</strong> Скрипт грузится с основного домена Яндекса как путь (<code>/ads/system/context.js</code>). Заблокировать весь <code>yandex.ru</code> нельзя — это же сам Яндекс. DNS тут бессилен в принципе.
– <strong>Видеореклама на плеерах</strong> — если ролик идёт с того же домена, что и само видео, DNS не поможет.
– <strong>YouTube</strong> — реклама с тех же доменов, что и контент. DNS-фильтр это не берёт, нужен uBlock Origin или подобное.</p>

<p>Итого: DNS-фильтр закрывает, грубо, <strong>70–80%</strong> раздражающей рекламы — всю, что на отдельных доменах. Остальное — это либо реклама с контентных CDN, либо встроенная в страницу, где DNS в принципе не может отличить. Для полной чистки в браузере всё равно нужен uBlock Origin.</p>

<h2 id="вывод">Вывод</h2>

<p>Для домашней сети связка «MikroTik + AdGuard Home через DoH» — это лучший баланс: одна настройка на роутере, вся сеть фильтруется, ничего не надо ставить на устройства. Но честно: <strong>это не 100%</strong> — DNS-блокировка по определению не режет рекламу с тех же доменов, что и контент.</p>

<p>Подход и первые шаги подсмотрел у <a href="https://fatmetal.ru/knowledge-base/adguard">Fatmetal</a> — у них хороший разбор, рекомендую. А грабли с MikroTik, whitelist&#39;ом и отечественной рекламой — уже мои, делюсь, чтобы вы не наступали.</p>

<p>А у вас что режет рекламу дома — DNS на роутере, uBlock, или всё вместе?</p>

<p><a href="https://articles.clr58.ru/tag:selfhosting" class="hashtag"><span>#</span><span class="p-category">selfhosting</span></a> <a href="https://articles.clr58.ru/tag:network" class="hashtag"><span>#</span><span class="p-category">network</span></a> <a href="https://articles.clr58.ru/tag:dns" class="hashtag"><span>#</span><span class="p-category">dns</span></a> <a href="https://articles.clr58.ru/tag:adguard" class="hashtag"><span>#</span><span class="p-category">adguard</span></a> <a href="https://articles.clr58.ru/tag:mikrotik" class="hashtag"><span>#</span><span class="p-category">mikrotik</span></a> <a href="https://articles.clr58.ru/tag:privacy" class="hashtag"><span>#</span><span class="p-category">privacy</span></a></p>
]]></content:encoded>
      <guid>https://articles.clr58.ru/adguard-home-mikrotik</guid>
      <pubDate>Sat, 29 Aug 2026 04:00:39 +0000</pubDate>
    </item>
    <item>
      <title>Firewall без магии: закрыть всё и открыть ровно нужное</title>
      <link>https://articles.clr58.ru/nsl-v2-1</link>
      <description>&lt;![CDATA[Цикл «Не светим лишнего». Выпуск 2.&#xA;&#xA;Firewall часто воспринимают как стену с кучей дырок-портов. На практике полезнее думать о нём как о списке решений: этот пакет относится к такой-то сессии, пришёл отсюда, идёт туда, значит его пропускаем или выбрасываем.&#xA;&#xA;Начальная позиция для защищаемого контура простая: если разрешающего правила нет, соединение не должно пройти. Это и есть default deny. Не «мы запретили несколько плохих адресов», а «мы разрешили только то, что понимаем».&#xA;&#xA;Сначала не перепутаем input и forward&#xA;&#xA;На MikroTik и большинстве других маршрутизаторов есть принципиальная разница.&#xA;&#xA;Input — трафик к самому маршрутизатору. WinBox, SSH RouterOS, API, DNS на роутере, ICMP к его адресу. Если мы защищаем управление MikroTik, работаем здесь.&#xA;&#xA;Forward — трафик, проходящий через маршрутизатор. Например, внешний клиент идёт через DNAT на RDP-сервер или внутреннюю веб-панель. Пакет адресован не самому MikroTik, он только проходит через него.&#xA;&#xA;Типовая ошибка выглядит так: администратор добавляет красивое правило в input, проверяет, что WinBox закрыт, и считает, что опубликованный сервер тоже защищён. А DNAT спокойно продолжает работать через forward.&#xA;&#xA;NAT не является разрешением сам по себе&#xA;&#xA;DNAT отвечает на вопрос «куда переписать адрес назначения». Firewall отвечает на вопрос «пустить ли пакет дальше». Лучше держать эту логику раздельно.&#xA;&#xA;Допустим, внешний 203.0.113.10:10443 переводится на внутренний 10.20.30.15:443. Это ещё не значит, что доступ должен быть разрешён всем. В forward можно потребовать одновременно:&#xA;&#xA;вход с WAN;&#xA;состояние нового соединения;&#xA;нужный внутренний адрес и порт после DNAT;&#xA;наличие источника в группе access-monitoring;&#xA;логирование начала соединения.&#xA;&#xA;Тогда NAT остаётся постоянным, но без членства в разрешённой группе ресурс выглядит закрытым.&#xA;&#xA;Группы лучше отдельных исключений&#xA;&#xA;Если ресурсов больше двух, не стоит строить правила вокруг фамилий и разовых адресов. Удобнее завести сущности по смыслу:&#xA;&#xA;назначения protected-monitoring, protected-dev, protected-cctv;&#xA;источники access-admin, access-developer, access-contractor;&#xA;отдельные цепочки или правила для HTTP, SSH, RDP и управления.&#xA;&#xA;Тогда пользователь или портал добавляет адрес в готовую группу. Он не получает возможность придумать себе произвольный destination. Это сильно снижает шанс, что ошибка административной панели превратится в «открыли человеку всю серверную сеть».&#xA;&#xA;Плюсы обычного firewall&#xA;&#xA;работает с любыми IP-протоколами и не зависит от приложения;&#xA;почти везде уже есть;&#xA;поведение можно увидеть счётчиками и логами;&#xA;хорошо масштабируется через группы адресов;&#xA;не требует установки чего-либо на клиент.&#xA;&#xA;Минусы&#xA;&#xA;Главный минус — firewall обычно не знает человека. Он знает IP-адрес, иногда интерфейс, VLAN, сертификат туннеля или метку соединения. Если два пользователя выходят через один NAT, для обычного L3/L4-фильтра они выглядят одинаково.&#xA;&#xA;Вторая проблема — правила статичны, пока кто-то или что-то их не изменит. Человеческие исключения имеют свойство оставаться навсегда.&#xA;&#xA;Где можно больно ошибиться&#xA;&#xA;Порядок правил. Firewall идёт сверху вниз. Широкий accept раньше точного drop делает точный drop декоративным.&#xA;&#xA;Established, related. Состояние соединений удобно: не приходится заново проверять каждый ответный пакет. Но если правило accept established,related стоит выше проверки актуального access-list, уже открытый SSH или RDP может продолжить работу после удаления адреса из списка.&#xA;&#xA;FastTrack. Он ускоряет обработку established-соединений, пропуская часть обычного пути firewall. Для трафика, который должен отключаться немедленно при отзыве разрешения, FastTrack нужно либо обходить, либо продумывать очистку connection tracking.&#xA;&#xA;IPv6. Можно идеально закрыть IPv4 и оставить тот же сервер доступным по глобальному IPv6. Проверяем оба стека или сознательно отключаем неиспользуемый.&#xA;&#xA;Управление самим маршрутизатором. REST API, WinBox и SSH не должны торчать в Интернет просто потому, что «там сложный пароль». Управление лучше вынести в отдельный адрес/VRF/VLAN и ограничить источники.&#xA;&#xA;Слишком широкая группа назначения. Открывать /16, потому что нужный сервер находится где-то внутри, — плохая экономия строк конфигурации.&#xA;&#xA;Когда этого достаточно&#xA;&#xA;Обычный firewall отлично решает задачу, если источники стабильны и хорошо известны: офисы, площадки, внешние сервисы, собственный VPN-шлюз. Для людей с динамическими адресами ему нужен ещё один слой: временный список, портал, knocking или другая система, которая будет решать, кого и на сколько добавлять.&#xA;&#xA;Ранее в цикле&#xA;&#xA;1. Зачем прятать то, что всё равно должно быть доступно снаружи&#xA;&#xA;Документация и источники&#xA;&#xA;MikroTik: Firewall&#xA;MikroTik: Connection tracking и FastTrack&#xA;&#xA;#network #mikrotik&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><em>Цикл «Не светим лишнего». Выпуск 2.</em></p>

<p><img src="https://paste.clr58.ru/ffc736404f-sukycg.png" alt=""></p>

<p>Firewall часто воспринимают как стену с кучей дырок-портов. На практике полезнее думать о нём как о списке решений: этот пакет относится к такой-то сессии, пришёл отсюда, идёт туда, значит его пропускаем или выбрасываем.</p>

<p>Начальная позиция для защищаемого контура простая: <strong>если разрешающего правила нет, соединение не должно пройти</strong>. Это и есть default deny. Не «мы запретили несколько плохих адресов», а «мы разрешили только то, что понимаем».</p>

<h3 id="сначала-не-перепутаем-input-и-forward">Сначала не перепутаем input и forward</h3>

<p>На MikroTik и большинстве других маршрутизаторов есть принципиальная разница.</p>

<p><strong>Input</strong> — трафик к самому маршрутизатору. WinBox, SSH RouterOS, API, DNS на роутере, ICMP к его адресу. Если мы защищаем управление MikroTik, работаем здесь.</p>

<p><strong>Forward</strong> — трафик, проходящий через маршрутизатор. Например, внешний клиент идёт через DNAT на RDP-сервер или внутреннюю веб-панель. Пакет адресован не самому MikroTik, он только проходит через него.</p>

<p>Типовая ошибка выглядит так: администратор добавляет красивое правило в input, проверяет, что WinBox закрыт, и считает, что опубликованный сервер тоже защищён. А DNAT спокойно продолжает работать через forward.</p>

<h3 id="nat-не-является-разрешением-сам-по-себе">NAT не является разрешением сам по себе</h3>

<p>DNAT отвечает на вопрос «куда переписать адрес назначения». Firewall отвечает на вопрос «пустить ли пакет дальше». Лучше держать эту логику раздельно.</p>

<p>Допустим, внешний <code>203.0.113.10:10443</code> переводится на внутренний <code>10.20.30.15:443</code>. Это ещё не значит, что доступ должен быть разрешён всем. В forward можно потребовать одновременно:</p>
<ul><li>вход с WAN;</li>
<li>состояние нового соединения;</li>
<li>нужный внутренний адрес и порт после DNAT;</li>
<li>наличие источника в группе <code>access-monitoring</code>;</li>
<li>логирование начала соединения.</li></ul>

<p>Тогда NAT остаётся постоянным, но без членства в разрешённой группе ресурс выглядит закрытым.</p>

<h3 id="группы-лучше-отдельных-исключений">Группы лучше отдельных исключений</h3>

<p>Если ресурсов больше двух, не стоит строить правила вокруг фамилий и разовых адресов. Удобнее завести сущности по смыслу:</p>
<ul><li>назначения <code>protected-monitoring</code>, <code>protected-dev</code>, <code>protected-cctv</code>;</li>
<li>источники <code>access-admin</code>, <code>access-developer</code>, <code>access-contractor</code>;</li>
<li>отдельные цепочки или правила для HTTP, SSH, RDP и управления.</li></ul>

<p>Тогда пользователь или портал добавляет адрес в готовую группу. Он не получает возможность придумать себе произвольный destination. Это сильно снижает шанс, что ошибка административной панели превратится в «открыли человеку всю серверную сеть».</p>

<h3 id="плюсы-обычного-firewall">Плюсы обычного firewall</h3>
<ul><li>работает с любыми IP-протоколами и не зависит от приложения;</li>
<li>почти везде уже есть;</li>
<li>поведение можно увидеть счётчиками и логами;</li>
<li>хорошо масштабируется через группы адресов;</li>
<li>не требует установки чего-либо на клиент.</li></ul>

<h3 id="минусы">Минусы</h3>

<p>Главный минус — firewall обычно не знает человека. Он знает IP-адрес, иногда интерфейс, VLAN, сертификат туннеля или метку соединения. Если два пользователя выходят через один NAT, для обычного L3/L4-фильтра они выглядят одинаково.</p>

<p>Вторая проблема — правила статичны, пока кто-то или что-то их не изменит. Человеческие исключения имеют свойство оставаться навсегда.</p>

<h3 id="где-можно-больно-ошибиться">Где можно больно ошибиться</h3>

<p><strong>Порядок правил.</strong> Firewall идёт сверху вниз. Широкий accept раньше точного drop делает точный drop декоративным.</p>

<p><strong>Established, related.</strong> Состояние соединений удобно: не приходится заново проверять каждый ответный пакет. Но если правило <code>accept established,related</code> стоит выше проверки актуального access-list, уже открытый SSH или RDP может продолжить работу после удаления адреса из списка.</p>

<p><strong>FastTrack.</strong> Он ускоряет обработку established-соединений, пропуская часть обычного пути firewall. Для трафика, который должен отключаться немедленно при отзыве разрешения, FastTrack нужно либо обходить, либо продумывать очистку connection tracking.</p>

<p><strong>IPv6.</strong> Можно идеально закрыть IPv4 и оставить тот же сервер доступным по глобальному IPv6. Проверяем оба стека или сознательно отключаем неиспользуемый.</p>

<p><strong>Управление самим маршрутизатором.</strong> REST API, WinBox и SSH не должны торчать в Интернет просто потому, что «там сложный пароль». Управление лучше вынести в отдельный адрес/VRF/VLAN и ограничить источники.</p>

<p><strong>Слишком широкая группа назначения.</strong> Открывать <code>/16</code>, потому что нужный сервер находится где-то внутри, — плохая экономия строк конфигурации.</p>

<h3 id="когда-этого-достаточно">Когда этого достаточно</h3>

<p>Обычный firewall отлично решает задачу, если источники стабильны и хорошо известны: офисы, площадки, внешние сервисы, собственный VPN-шлюз. Для людей с динамическими адресами ему нужен ещё один слой: временный список, портал, knocking или другая система, которая будет решать, кого и на сколько добавлять.</p>

<h3 id="ранее-в-цикле">Ранее в цикле</h3>
<ul><li><a href="https://articles.clr58.ru/nsl-v1">1. Зачем прятать то, что всё равно должно быть доступно снаружи</a></li></ul>

<h3 id="документация-и-источники">Документация и источники</h3>
<ul><li><a href="https://help.mikrotik.com/docs/spaces/ROS/pages/250708066/Firewall">MikroTik: Firewall</a></li>
<li><a href="https://help.mikrotik.com/docs/spaces/ROS/pages/130220087/Connection%2Btracking">MikroTik: Connection tracking и FastTrack</a></li></ul>

<p><a href="https://articles.clr58.ru/tag:network" class="hashtag"><span>#</span><span class="p-category">network</span></a> <a href="https://articles.clr58.ru/tag:mikrotik" class="hashtag"><span>#</span><span class="p-category">mikrotik</span></a></p>
]]></content:encoded>
      <guid>https://articles.clr58.ru/nsl-v2-1</guid>
      <pubDate>Fri, 14 Aug 2026 13:19:17 +0000</pubDate>
    </item>
  </channel>
</rss>