Выберите продукт

Debian/Ubuntu: как устранить ARP flux при нескольких IP на одном сервере

Если на Debian или Ubuntu сервере несколько IP-адресов, можно столкнуться с ARP flux: хост отвечает на ARP-запросы не тем интерфейсом, а сеть начинает вести себя непредсказуемо. Разберём, как диагностировать проблему, настроить arp_ignore, arp_announce, rp_filter и policy routing без лишнего риска.
Debian/Ubuntu: как устранить ARP flux при нескольких IP на одном сервере

ARP flux — одна из тех сетевых проблем в Linux, которые долго выглядят как «странная плавающая сеть». Сегодня пинги проходят, завтра часть клиентов не может достучаться до одного из IP, а послезавтра трафик внезапно выходит через другой адрес. Особенно часто это проявляется на серверах с несколькими IPv4-адресами, несколькими интерфейсами, дополнительными алиасами, VRRP, контейнерными сетями или нестандартной маршрутизацией.

На Debian и Ubuntu проблема обычно связана не с «поломкой ARP», а с тем, как ядро Linux по умолчанию обрабатывает ARP-ответы и выбор исходного адреса. Если не ограничить поведение хоста, он может ответить на ARP-запрос для адреса, назначенного на одном интерфейсе, через другой интерфейс. Для соседних устройств в L2-сети это выглядит как путаница: один и тот же IP ассоциируется то с одним MAC, то с другим.

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

В этой статье разберём, что такое arp flux, как он проявляется в Debian/Ubuntu, какие параметры ядра реально влияют на поведение, и как правильно сочетать arp_ignore, arp_announce, rp_filter и policy routing. Покажу практичный путь диагностики и рабочую схему настройки для сервера с несколькими IP. Если вы обкатываете такую схему в отдельной среде, удобнее делать это на изолированном VDS, где можно спокойно проверять маршрутизацию и sysctl-параметры.

Что такое ARP flux простыми словами

ARP нужен для сопоставления IPv4-адреса и MAC-адреса внутри одного L2-сегмента. Когда соседняя машина хочет отправить пакет на ваш IP, она сначала спрашивает: «кто владеет этим IP?» Хост, у которого этот адрес есть, отвечает своим MAC.

Проблема в том, что Linux традиционно смотрит на IP-адрес как на ресурс всего хоста, а не строго конкретного интерфейса. То есть если адрес назначен на сервере, ядро в определённых условиях может ответить на ARP-запрос через интерфейс, на котором этот адрес формально не висит. Это и есть основа ARP flux.

Иными словами: сеть ожидает модель «IP привязан к конкретному порту», а Linux по умолчанию часто ведёт себя по модели «IP принадлежит всему серверу».

Если у вас один интерфейс и один адрес, вы этого почти никогда не заметите. Но как только появляются несколько адресов, несколько интерфейсов в одной подсети, secondary IP, bond, bridge, VRRP или ручные маршруты, поведение становится заметным и иногда разрушительным.

Типичные симптомы на Debian/Ubuntu

Самый частый сценарий: на сервере два интерфейса в одной или близкой сети, либо несколько IP на одном сервере с нестандартным роутингом. Соседние машины начинают получать ARP-ответы с неожиданного MAC-адреса. После этого часть трафика идёт не туда, возвратный путь отличается от входящего, а приложения видят обрывы соединений.

С практической стороны это может выглядеть так:

  • один из дополнительных IP пингуется нестабильно;
  • подключение к сервису на конкретном IP то работает, то нет;
  • на соседнем хосте запись в ARP-кэше для одного IP меняется между двумя MAC;
  • ответы уходят с другого исходного адреса;
  • tcpdump показывает ARP-ответы не с того интерфейса;
  • после включения фильтрации reverse path часть трафика начинает отбрасываться.

Особенно неприятно, что проблема может быть не постоянной. ARP-кэш у соседей живёт ограниченное время, маршруты могут выбираться по метрикам, а некоторые запросы проходят успешно. Поэтому «сеть иногда ломается» — классическое описание ARP flux.

В таких случаях сначала полезно зафиксировать текущее поведение сети, а уже потом менять sysctl и таблицы маршрутизации. Это сильно снижает риск сломать рабочий, но просто неочевидный сценарий.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Когда проблема возникает чаще всего

В реальной эксплуатации я бы в первую очередь проверял ARP flux в следующих сценариях:

  • несколько интерфейсов в одной IPv4-подсети;
  • несколько IP на одном интерфейсе и сервисы, которые должны отвечать строго с конкретного адреса;
  • VRRP, keepalived, floating IP;
  • сетевые namespace, bridge, виртуализация, контейнеры;
  • асимметричный трафик из-за нескольких шлюзов или policy routing;
  • фильтрация пакетов с включённым строгим rp_filter.

Важно понимать: несколько IP на одном Linux-хосте — это нормально. Но если вы хотите предсказуемое поведение, нужно явно описать системе, как отвечать на ARP и как выбирать маршрут обратно.

Проверка ARP-таблицы и сетевых интерфейсов на Linux-сервере

С чего начать диагностику

До изменения sysctl-параметров сначала соберите факты. Иначе легко «починить» не ту проблему или сломать рабочий сценарий с асимметричной маршрутизацией.

Проверяем адреса и интерфейсы

ip addr show
ip -br addr

Посмотрите, где именно назначены адреса, какие интерфейсы активны, нет ли адресов в одной подсети на разных NIC и нет ли неожиданных secondary IP.

Смотрим маршруты

ip route show
ip route show table main
ip rule show

Если на хосте уже используется policy routing, важно понять, какие правила выбираются первыми и как ядро определяет выходной интерфейс для ответа.

Проверяем, как ядро выберет маршрут для конкретного источника

ip route get 192.0.2.10
ip route get 192.0.2.10 from 198.51.100.20

Команда ip route get очень полезна при сетевой диагностике. Она показывает, какой маршрут реально будет использован, какой интерфейс выбран и какой исходный адрес будет подставлен.

Смотрим ARP-трафик

tcpdump -ni any arp
tcpdump -ni eth0 arp
tcpdump -ni eth1 arp

Если видите, что запрос пришёл на один интерфейс, а ответ ушёл с другого, или ответ уходит с MAC другого интерфейса, вы почти наверняка упёрлись в ARP flux.

Проверяем текущие sysctl-параметры

sysctl net.ipv4.conf.all.arp_ignore
sysctl net.ipv4.conf.all.arp_announce
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.default.arp_ignore
sysctl net.ipv4.conf.default.arp_announce
sysctl net.ipv4.conf.default.rp_filter

Дополнительно имеет смысл посмотреть значения по каждому интерфейсу, потому что они могут отличаться:

sysctl net.ipv4.conf.eth0.arp_ignore
sysctl net.ipv4.conf.eth0.arp_announce
sysctl net.ipv4.conf.eth0.rp_filter
sysctl net.ipv4.conf.eth1.arp_ignore
sysctl net.ipv4.conf.eth1.arp_announce
sysctl net.ipv4.conf.eth1.rp_filter

Что делают arp_ignore и arp_announce

Это два ключевых параметра против ARP flux.

Параметр arp_ignore

arp_ignore определяет, насколько охотно система отвечает на ARP-запросы для локальных адресов.

На практике чаще всего используют значение 1. Оно говорит: отвечай на ARP-запрос только если целевой IP назначен на интерфейс, через который этот запрос пришёл. Это уже резко снижает вероятность ARP flux.

Более строгие режимы существуют, но без необходимости их лучше не включать: можно случайно нарушить доступность в специфических сетях.

Параметр arp_announce

arp_announce контролирует, какой локальный адрес ядро использует в ARP-запросах и gratuitous ARP. Для multi-IP-хостов безопаснее обычно ставить 2, чтобы система старалась объявлять наиболее подходящий адрес для данного интерфейса и подсети.

Если кратко, удачная базовая комбинация для большинства случаев — arp_ignore=1 и arp_announce=2.

Эти параметры не заменяют нормальную маршрутизацию, а лишь делают ARP-поведение хоста более предсказуемым.

Практичная базовая настройка sysctl

Для Debian/Ubuntu удобно вынести настройки в отдельный файл, например /etc/sysctl.d/60-arp-flux.conf.

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_announce = 2

Применить изменения можно так:

sysctl --system

Если интерфейсы уже существуют, проверьте, что значения действительно применились и на уровне конкретных интерфейсов. Иногда на живой системе полезно задать их явно:

sysctl -w net.ipv4.conf.eth0.arp_ignore=1
sysctl -w net.ipv4.conf.eth0.arp_announce=2
sysctl -w net.ipv4.conf.eth1.arp_ignore=1
sysctl -w net.ipv4.conf.eth1.arp_announce=2

После этого повторите tcpdump и проверьте таблицу ARP на соседних хостах.

Где здесь роль rp_filter

rp_filter — это reverse path filtering. Он проверяет, соответствует ли обратный маршрут для входящего пакета ожидаемому интерфейсу. Это полезный механизм защиты от спуфинга, но он же часто ломает легитимный асимметричный трафик.

Именно поэтому при нескольких IP, нескольких интерфейсах и policy routing нужно быть очень осторожным. Если включить строгий режим, хост начнёт отбрасывать пакеты, для которых обратный путь, по мнению ядра, должен идти не через тот интерфейс, по которому пакет пришёл.

Чаще всего встречаются такие варианты:

  • 0 — отключено;
  • 1 — строгая проверка;
  • 2 — более мягкая проверка.

Для серверов с несколькими маршрутами и осознанной асимметрией обычно разумнее использовать 2 или точечно настраивать параметры по интерфейсам. Если бездумно поставить 1 глобально, можно получить загадочные потери входящего трафика.

Пример осторожной настройки:

net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2

Но это не универсальная догма. Если у вас простой сервер с одним ожидаемым путём, строгий режим может быть уместен. Если же у вас multi-homed Linux, сначала проектируйте маршрутизацию, потом включайте фильтрацию. Если тема близка, ещё рекомендую материал про управление исходящими адресами через SNAT в nftables: он хорошо дополняет policy routing в multi-IP-сценариях.

Почему одного sysctl часто недостаточно

Очень распространённая ошибка: администратор выставляет arp_ignore и arp_announce, ARP-таблицы действительно стабилизируются, но сервис всё равно отвечает не тем IP или пакеты теряются. Причина в том, что ARP и IP-маршрутизация — разные уровни.

ARP определяет, как вас находят в локальном сегменте. А вот обратный путь пакетов определяет таблица маршрутизации. Если у сервера несколько IP и для каждого адреса ожидается свой выходной путь, нужно настраивать policy routing.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Когда нужен policy routing

Policy routing нужен, когда маршрут должен зависеть не только от адреса назначения, но и от источника, интерфейса или других признаков. Классический кейс: на сервере два IP из разных подсетей или два uplink, и ответы должны уходить через свой шлюз для каждого адреса.

Без этого возможна ситуация, когда пакет пришёл на IP одного интерфейса, а ответ уходит через основной маршрут другого интерфейса. С точки зрения клиента это выглядит как поломанная сеть, а при включённом rp_filter — ещё и как сброс части пакетов самим ядром.

Пример логики policy routing

Допустим, у нас есть:

  • eth0 с адресом 192.0.2.10/24 и шлюзом 192.0.2.1;
  • eth1 с адресом 198.51.100.10/24 и шлюзом 198.51.100.1.

Тогда для корректного поведения нужно сделать отдельные таблицы маршрутизации и правила по исходному адресу.

echo '100 rt_eth0' >> /etc/iproute2/rt_tables
echo '101 rt_eth1' >> /etc/iproute2/rt_tables
ip route add 192.0.2.0/24 dev eth0 scope link table rt_eth0
ip route add default via 192.0.2.1 dev eth0 table rt_eth0
ip route add 198.51.100.0/24 dev eth1 scope link table rt_eth1
ip route add default via 198.51.100.1 dev eth1 table rt_eth1
ip rule add from 192.0.2.10/32 table rt_eth0
ip rule add from 198.51.100.10/32 table rt_eth1

После этого ответы для каждого адреса будут выбираться из своей таблицы. Именно такая схема часто завершает лечение ARP flux и связанных с ним побочных эффектов.

Перед внедрением в продакшене проверьте правила на тестовом узле или в отдельной среде. Для таких экспериментов удобнее использовать отдельный VDS, где не страшно временно менять сетевую логику и отлаживать возвратный маршрут.

Как это увязать с netplan и systemd-networkd

На современных Ubuntu часто используется netplan, а на Debian и Ubuntu серверных установках нередко встречается systemd-networkd или ifupdown. Главное правило тут простое: постоянная конфигурация должна описывать не только адреса, но и правила и таблицы маршрутизации, если они нужны.

Если вы временно добавили маршруты командами ip route и ip rule, а потом перезагрузили сервер, проблема может вернуться сама. Поэтому после отладки обязательно перенесите конфигурацию в штатный механизм вашей системы.

В рамках статьи не буду привязываться к одному сетевому стеку, потому что синтаксис зависит от вашей версии Debian/Ubuntu и текущего менеджера сети. Но принцип неизменен: отдельные таблицы, маршруты в этих таблицах и правила from для конкретных IP.

Настройка policy routing и таблиц маршрутизации на Debian или Ubuntu

Пошаговый план исправления без лишнего риска

  1. Соберите текущее состояние: ip addr, ip route, ip rule, значения sysctl.
  2. Запустите tcpdump на проблемных интерфейсах и подтвердите ARP flux фактами.
  3. Включите базовые настройки arp_ignore=1 и arp_announce=2.
  4. Проверьте, исчезла ли путаница в ARP-ответах.
  5. Если трафик всё ещё идёт асимметрично, спроектируйте policy routing.
  6. Только после этого настраивайте rp_filter в подходящий режим.
  7. Закрепите конфигурацию в постоянных файлах системы.
  8. После изменений очистите ARP-кэш на соседях или дождитесь его обновления.

Последний пункт важен. Иногда вы уже всё исправили, но клиентская машина продолжает использовать старую ARP-запись и создаёт иллюзию, что ничего не поменялось.

Частые ошибки при борьбе с ARP flux

Первая ошибка — менять только один параметр наугад. Например, включить arp_ignore и не проверить маршрутизацию. Вторая — включить строгий rp_filter на multi-homed сервере и потом долго искать, почему часть соединений теряется только в одном направлении.

Третья ошибка — не смотреть трафик. Без tcpdump и без проверки ip route get очень легко принять последствия policy routing за проблему ARP и наоборот.

Четвёртая ошибка — забыть о порядке применения настроек. Значения all, default и параметры конкретного интерфейса взаимодействуют не всегда так, как ожидает администратор. После применения проверяйте итоговое состояние именно на нужных интерфейсах.

Минимальный рабочий шаблон для большинства случаев

Если нужен короткий и практичный стартовый вариант для Debian/Ubuntu сервера с несколькими IP, я бы рекомендовал такой подход:

  • поставить net.ipv4.conf.all.arp_ignore = 1;
  • поставить net.ipv4.conf.all.arp_announce = 2;
  • дублировать эти значения в default;
  • проверить, не мешает ли rp_filter;
  • при разных uplink или ожидаемом раздельном обратном пути — добавить policy routing.

Это не серебряная пуля, но для большинства сценариев с несколькими IP в Linux даёт предсказуемое поведение и снимает самую неприятную часть проблемы.

Как проверить, что всё действительно исправилось

После настройки убедитесь не только в отсутствии жалоб, но и в сетевой консистентности:

  • ARP-запрос к IP на eth0 получает ответ только от eth0;
  • ARP-запрос к IP на eth1 получает ответ только от eth1;
  • ip route get для каждого источника показывает ожидаемый интерфейс;
  • при реальном подключении сервис отвечает с правильного IP;
  • на соседних устройствах ARP-кэш больше не скачет между MAC-адресами.

Если хотя бы один из этих пунктов не выполняется, проблема, скорее всего, не закрыта полностью. Чаще всего остаётся недонастроенный маршрут, правило ip rule или конфликтующая конфигурация менеджера сети.

Итог

ARP flux в Debian и Ubuntu — это не экзотика и не баг сломанного сервера, а следствие стандартного поведения Linux в среде, где у хоста несколько IP и сеть ожидает более жёсткой привязки адреса к интерфейсу. Поэтому лечится проблема тоже системно: сначала корректируем ARP-поведение через arp_ignore и arp_announce, затем проверяем влияние rp_filter, а при необходимости строим нормальный policy routing.

Если подходить к задаче именно в таком порядке, можно довольно быстро превратить магические сетевые отказы в понятную и воспроизводимую схему. А это уже половина успеха в любой сетевой диагностике. Если вы регулярно поднимаете такие конфигурации для проектов и сервисов, имеет смысл сразу выбирать инфраструктуру, где удобно управлять сетями, адресами и маршрутами — от виртуального хостинга для простых задач до отдельных VDS для сложных multi-IP-сценариев.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: как исправить exec format error и bad ELF interpreter OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить exec format error и bad ELF interpreter

В Debian и Ubuntu ошибки exec format error, bad ELF interpreter и cannot execute binary file обычно связаны не с правами, а с несо ...
Debian/Ubuntu: как исправить Permission denied (publickey) из-за ~/.ssh, authorized_keys и прав на home directory OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Permission denied (publickey) из-за ~/.ssh, authorized_keys и прав на home directory

Если SSH-ключи в Debian или Ubuntu перестали работать и сервер отвечает Permission denied (publickey), причина часто не в ключе, а ...
Debian/Ubuntu: как исправить inotify limits, max_user_watches и Too many open files OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить inotify limits, max_user_watches и Too many open files

Если webpack, Vite, VS Code, systemd path units или CI runner перестают следить за файлами в Debian/Ubuntu, причина часто в лимита ...