Два префикса /1 покрывают ровно те же адреса IPv4, что и один /0, и это равенство действует только внутри списка разрешённых префиксов партнёра. Оно перестаёт действовать в тот момент, когда инструмент настройки решает, как маршрутизировать, потому что Linux wg-quick обрабатывает префикс по умолчанию как особый случай, а не как арифметику. Особая ветка устанавливает отдельную таблицу, два правила политики, метку сокета и настройки обратного пути, которых пара половинных маршрутов никогда не получает. Поэтому, когда после правки перестаёт работать прокси или браузер, префиксы — наименее интересная часть изменения.

Список префиксов — не вся конфигурация

AllowedIPs выполняет две задачи сразу, и только одна из них касается покрытия. Для самого WireGuard список — это криптоключевая маршрутизация: он определяет, какие назначения шифруются в сторону партнёра и какие адреса источника этому партнёру разрешено использовать. Для wg-quick тот же список служит ещё и спецификацией маршрутов, и создаваемый маршрут зависит от того, в какую ветку список случайно попадает. Поэтому одинаковое покрытие при двух разных формах списка ничего не говорит об одинаковом состоянии хоста.

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

Что особая ветка добавляет сверх маршрута

Запись /0 отправляет wg-quick по пути маршрута по умолчанию: отдельная таблица маршрутизации получает маршрут по умолчанию, одно правило политики направляет туда немаркированный трафик, второе правило сохраняет более конкретные маршруты основной таблицы как главенствующие, а интерфейс получает метку брандмауэра на собственный сокет. Эта метка — страж петли. Зашифрованные датаграммы, несущие трафик туннеля, уходят с установленной меткой, чтобы правило, направляющее всё остальное в туннель, не проглотило собственные транспортные пакеты туннеля.

Пара записей /1 вместо этого идёт обычным путём маршрута. Два маршрута попадают в настроенную таблицу, и ни один из окружающих механизмов не появляется — не потому, что он не нужен, а потому, что в этот путь кода никогда не входили.

Где два уклада расходятся

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

Во-вторых, всё, что рассуждает о метках, меняет поведение. Прозрачный прокси, перенаправляющий соединения локально, создаёт новые сокеты, чьи метки и источники отличаются от исходного потока клиента, и правила политики, порождаемые особой веткой, были частью того, что разделило эти потоки. Читать собственное исходящее соединение прокси — другое упражнение, чем проверять, доступно ли исходное назначение.

Прочитайте правила и метки перед правкой

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

ip rule show
ip -4 route show table all | grep -E 'default|wg1'
wg show wg1 fwmark
wg show wg1 endpoints

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

Отрепетируйте потерю туннеля перед выпуском

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

sudo ip -4 route add 198.51.100.20/32 via 192.0.2.1 dev eth0
ip -4 route get 198.51.100.20
sudo wg-quick down wg1

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

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