Вопрос или проблема
Встраиваемая система Linux используется для мониторинга сети на интерфейсе lan2 и сохранения результатов локально, чтобы их позже можно было загрузить через интерфейс wwan0.
wwan0 – это сотовый модем на частном APN.
inet 10.250.32.22/30 brd 10.250.32.23 scope global wwan0
lan2 – это порт Ethernet, который получает IPv4-адрес по DHCP от интернет-провайдера.
inet 98.95.117.12/22 brd 98.95.119.255 scope global lan2
Сотовый оператор для wwan0 регулярно отключает wwan0 из-за «нарушений адреса источника IP». IP-пакеты с адресом источника 98.95.117.12 отправляются через wwan0. Между lan2 и wwan0 нет маршрутов.
Я понимаю, что пакет может быть отправлен через интерфейс wwan0 к его шлюзу в зависимости от метрик, но если используется интерфейс wwan0, то адрес источника должен быть адресом интерфейса wwan0.
Какие обстоятельства могут вызвать отправку пакета с интерфейса wwan0 с использованием адреса источника интерфейса lan2?
но если используется интерфейс wwan0, то адрес источника должен быть адресом интерфейса wwan0.
Это гарантировано только в том случае, если у вас есть правила SNAT/MASQUERADE в iptables, явно переопределяющие адрес источника.
Однако в базовой работе IP система не накладывает никаких ограничений на это – маршрут может лишь намекать на предпочтительный адрес источника, если приложение не привязано к одному, но в остальном оба являются независимыми. Таким образом, даже если приложение привязано к локальному адресу интерфейса A, пакеты все равно будут следовать предпочтительному маршруту по умолчанию, даже если он проходит через интерфейс B.
В основном стек сетей Linux не понимает многопрофильные хосты с двумя независимыми подключениями к провайдеру и предполагает, что все интерфейсы подключены к [разным подсетям] одной более широкой сети, где допускается ассиметричная маршрутизация (как если бы он был подключен к внутренней корпоративной сети или, возможно, к ARPANET 1970-х). Для достижения любой формы поддержки многопрофильности требуется ручная настройка (например, политическая маршрутизация).
-
(В качестве общего примера, когда это будет допустимое поведение, хост с двумя интерфейсами может не иметь маршрутов по умолчанию через оба интерфейса. Если он контактируется по адресу интерфейса A, но единственный маршрут для отправки ответа – через интерфейс B, он не может просто выдумать маршрут через интерфейс A вместо этого: он должен ответить через интерфейс B.
Для чуть другого примера, когда ответ через «неправильный» интерфейс является нормальным, маршрутизатор, подключенный к нескольким подсетям одной сети, может иметь маршрутизированный OSPF «loopback» адрес, который назначен ‘lo’, и будет совершенно нормально, если он будет генерировать пакеты с своего ‘loopback’ адреса и отправлять их через eth0 или eth2.)
Тем не менее, стек IPv6 в Linux следует немного более строгой модели хоста и имеет необязательный параметр “use_oif_addrs_only” в sysctl, чтобы ограничить автоматический выбор адреса источника только теми, которые назначены исходящему интерфейсу. Но его стек IPv4 не имеет такого (насколько мне известно; нет, не параметры arp_*) и предполагает, что все адреса просто принадлежат хосту в целом. (И в подобном духе стек IPv6 поддерживает простую маршрутизацию на основе как источника, так и назначения, в то время как для IPv4 это требует более сложной настройки «политической маршрутизации».)
Предложения, которые стоит попробовать:
-
При добавлении маршрутов по умолчанию определите «предпочтительный адрес источника» для каждого (в
ip route
это параметрsrc
, в netlink это RTA_PREFSRC). -
Добавьте маршруты по умолчанию в две отдельные таблицы маршрутов и используйте политическую маршрутизацию через
ip rule
, чтобы обеспечить, что, например, пакеты с источником 98.95.117.12 будут использовать таблицу маршрутов, в которой есть только маршруты черезlan2
.ip route add default via ... table 123 ip route add default via ... table 456 ip rule add from ... lookup 123 ip rule add from ... lookup 456
-
В качестве последнего средства установите правила
masquerade
в iptables/nftables для обоих интерфейсов, как если бы это был маршрутизатор.oifname "wwan0" masquerade
Ответ или решение
Отправка IP-пакетов с использованием адреса источника, отличного от адреса интерфейса, связана с несколькими ключевыми аспектами работы сетевых стеков, особенно в контексте многосетевых систем, таких как рассматриваемая встроенная Linux-система.
Контекст проблемы
Ваша конкретная ситуация состоит в том, что система мониторит сеть через интерфейс lan2 с IP-адресом 98.95.117.12 и через wwan0, который является модемом для сотовой связи с IP-адресом 10.250.32.22. Проблема возникает, когда пакеты с адресом 98.95.117.12 отправляются через wwan0, вызывая нарушения политики мобильного оператора.
Возможные причины
-
Отсутствие четкой привязки интерфейсов к адресам источника:
- В Linux сетевой стек не требует обязательного соответствия IP-адреса источника с интерфейсом, через который происходит отправка пакета. В ряде случаев система может выбрать любой доступный IP-адрес, если на уровне приложений не заданы жесткие требования к исходному адресу.
-
Маршрутизация без явного контроля:
- Если в системе отсутствуют явные правила маршрутизации, пакеты могут использовать маршруты по умолчанию, не учитывающие привязку адреса источника к конкретному интерфейсу. То есть, если пакеты идут через маршруты, которые являются более предпочтительными с точки зрения метрик, они могут быть отправлены с неверным адресом.
-
Программное обеспечение и приложения:
- Если приложения, использующие сетевые функции, не назначают явный IP для отправки пакетов, Linux будет использовать возможность отправки пакетов с любого нигде не привязанного адреса. Это может привести к отправке пакетов с адресом lan2, когда они фактически выходят через wwan0.
-
Ошибки настройки маршрутизации:
- Некорректная настройка маршрутов или статическая маршрутизация, возможно, приведет к тому, что пакеты с одной сети будут отправляться через интерфейс, который предназначен для другой сети. Важно проверить, как настроены маршруты, связанные с двумя интерфейсами.
-
IP-маскирование:
- Если в системе отсутствуют правила NAT (например, SNAT или MASQUERADE), которые бы постоянно переназначали адрес источника, пакеты могут сохранять неправильный адрес источника на этапе отправки.
Рекомендуемые шаги по устранению проблемы
-
Настройка маршрутов с указанием предпочитаемого источника:
- При добавлении маршрутов для обоих интерфейсов укажите параметр "src" для каждого маршрута. Это поможет системе понимать, какой адрес источника использовать для каждого интерфейса.
ip route add default via <gateway_wan0> dev wwan0 src 10.250.32.22 ip route add default via <gateway_lan2> dev lan2 src 98.95.117.12
-
Политическая маршрутизация:
- Рассмотрите возможность создания различных таблиц маршрутизации для каждого интерфейса и используйте правила (ip rule), чтобы обеспечить правильное направление пакетов:
ip route add default via <gateway_lan2> table 1 ip rule add from 98.95.117.12 lookup 1 ip route add default via <gateway_wwan0> table 2 ip rule add from 10.250.32.22 lookup 2
-
Установка правил для NAT:
- В крайних случаях настройте masquerading для обоих интерфейсов, чтобы обеспечить корректное отправление пакетов с соответствующим адресом источника.
iptables -t nat -A POSTROUTING -o wwan0 -j MASQUERADE
Заключение
Эти рекомендации помогут устранить проблему нарушения политики IP-адреса на вашем устройстве. Важно отметить, что необходимо обеспечить четкий контроль за конфигурацией сети и изучить, как приложения обрабатывают сетевые соединения. Применение указанных стратегий может значительно улучшить стабильность работы вашего сетевого решения и минимизировать потенциальные проблемы в будущем.