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

На что на самом деле жалуется парсер

Адрес назначения, записанный как адрес плюс маска, должен описывать сеть, а сеть начинается с обнулённых битов хоста. Когда указанный адрес всё ещё содержит значение в части хоста, пара внутренне противоречива: 172.20.130.0 выглядит аккуратно, потому что оканчивается нулём, но ноль в четвёртом октете — не единственное, что важно. Именно третий октет держит здесь лишние биты.

Инструменты по-разному справляются с этим противоречием. Строгие парсеры отклоняют строку и называют биты хоста. Мягкие парсеры маскируют адрес и устанавливают то, о чём вы не просили, что хуже, потому что конфигурация теперь маршрутизирует диапазон, который вы никогда не имели в виду. Модуль ipaddress в Python предлагает выбор напрямую: строгий разбор сети вызывает ошибку, а strict=False маскирует биты хоста. Ваш клиент может быть строгим, мягким или непоследовательным между версиями, поэтому читайте сообщение, а не доверяйте привычке.

Разберите пример вручную

Возьмите туннель, которому нужно достичь 172.20.130.0 с маской /20. Маска /20 заимствует четыре бита у третьего октета, поэтому этот октет считается только шагами по 16: 0, 16, 32 и далее до 240. Значение 130 попадает между 128 и 143, а значит, охватывающая сеть начинается с 172.20.128.0, а не с 172.20.130.0 с обнулённым последним октетом.

В явном виде блок идёт от 172.20.128.0 до 172.20.143.255 и содержит 4,096 адресов. Передача тех же значений нестрогому парсеру показывает замену, которую он сделал бы от вашего имени:

$ python3 -c "import ipaddress; n=ipaddress.ip_network('172.20.130.0/20', strict=False); print(n, n.num_addresses)"
172.20.128.0/20 4096

Решите, какой адрес назначения вы действительно имели в виду

Отклонённая строка обычно скрывает одно из трёх намерений, и выбрать можете только вы. Если туннелю нужен весь блок, напишите 172.20.128.0/20, канонический сетевой адрес. Если туннелю нужен только сегмент 130, маска была неверной, и 172.20.130.0/24 — честная форма. Если цель — одна машина, маршрут к хосту IPv4 — это /32 и никакая арифметика масок не участвует.

Каждое из них разрешает разный объём трафика, и это настоящая причина не расширять маску, пока жалоба не прекратится. /16 принимает строку почти везде и отправляет трафик к адресам, которые вы никогда не хотели маршрутизировать через туннель. Напишите самый узкий префикс, соответствующий намерению, и подтвердите его по следующему хопу, который ожидаете, а не по молчанию парсера.

Почему пересылка никогда не была решением

Отклонённый маршрут никогда не достигает пути пересылки, поэтому переключение net.ipv4.ip_forward не может изменить результат. Эта настройка важна позже, когда хост должен пропускать пакеты между интерфейсами, и включение её до того, как таблица станет правильной, меняет лишь то, какой этап откажет следующим.

В той же точке часто обвиняют ещё две вещи. Маршрут может быть принят и всё равно проиграть более конкретному маршруту, а правило брандмауэра может отбросить трафик после правильного поиска. Держите этапы раздельно: синтаксис, установка, выбор, фильтрация. Работа на неверном этапе кажется продуктивной, потому что каждое изменение что-то перезапускает.

Проверьте установленный маршрут и путь, который он выигрывает

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

Запросите адрес-член, а также один за пределами блока, чтобы сравнение было осмысленным, а не одной успокаивающей строкой:

ip -4 route show 172.20.128.0/20
ip -4 route get 172.20.140.10
ip -4 route get 172.20.200.10

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

Похожие статьи