Адрес peer в PPP или конечная точка VPN: что писать в via
Сравните чтение PPP-интерфейса как подсети с чтением его inet и peer как двух концов канала и посмотрите, какой следующий переход может принять таблица политик.
Одна строка на PPP-интерфейсе решает большую часть спора о маршрутизации на машине VPN: внутренний адрес и peer, напечатанный рядом. Прочитайте эту пару как крошечную подсеть, и вы будете искать шлюз, которого не существует. Прочитайте её как два конца одного канала, и следующий переход станет очевидным. Сравнение здесь идёт между этими двумя чтениями, потому что каждая таблица, построенная после, наследует выбранное. Ничего о внешней конечной точке VPN не решает ни одно из них.
Два чтения одной строки интерфейса
Возьмите сеанс, в котором интерфейс сообщает inet 10.64.3.9 peer 10.64.3.1/32. Чтение как подсети обращается с 10.64.3.9 как с одиноким хостом на острове /32, а затем ищет маршрутизатор, чтобы достичь чего-либо за его пределами. Поскольку единственный другой адрес на канале — это peer, такое чтение в итоге предлагает сам 10.64.3.9 в качестве шлюза, что является замкнутым кругом.
Чтение как конечной точки — документированное. На интерфейсе «точка-точка» peer называет удалённый конец этого единственного канала, поэтому 10.64.3.1 является пригодным следующим переходом, а 10.64.3.9 всегда только адрес источника.
Эта разница определяет, что может стоять в via. Запись туда локального адреса даёт маршрут, который ядро не может сопоставить с соседом, поэтому запись либо не проходит проверку, либо проглатывает трафик, выглядя при этом в списке совершенно здоровой. Peer работает потому, что это реальный пункт назначения на канале. Оба чтения согласны насчёт внешней конечной точки VPN, которая является совершенно отдельной сущностью: до неё добираются через underlay, а не через туннель, который она завершает.
Что сеанс уже установил
Прежде чем писать собственную таблицу, выведите то, что пришло вместе с каналом. Поддерживаемая интеграция PPP обычно устанавливает маршрут устройства и маршрут к peer при настройке сеанса, и эти две записи уже содержат правильное чтение.
ip -4 addr show dev ppp0
ip route show dev ppp0
ip route show table main | head -n 5
Маршрут устройства вида 10.64.3.1 dev ppp0 proto kernel scope link src 10.64.3.9 не несёт шлюза, потому что сам интерфейс является путём. Маршрут, называющий peer через via, — это другой объект с другим временем жизни, и он исчезает при падении сеанса. Копирование любой из двух форм в постоянную таблицу без проверки того, как она переустанавливается, — обычная причина, по которой работающий туннель теряет маршрут после переподключения.
Сравните два списка, а не полагайтесь на память. Если маршрут к peer есть в main, а ваша дополнительная таблица пуста, вы узнали то, чего строка адреса вам никогда не говорила.
Правило и таблица — отдельные решения
Выбор таблицы и её заполнение — независимые шаги, и сравнение здесь важно, потому что при отладке эти два часто путают. Правило, отправляющее помеченный трафик в таблицу 100, ничего не делает, если в таблице 100 нет подходящего маршрута, а хорошо заполненная таблица недостижима, если на неё не указывает ни одно правило.
Половина маршрута по умолчанию — не маршрут по умолчанию. Один 0.0.0.0/1 покрывает нижнюю половину пространства IPv4, поэтому политике, которая намерена захватить всё, нужен и соответствующий 128.0.0.0/1, или настоящий default. Прочитать рабочую конфигурацию и скопировать одну из двух половин — так люди и получают петлю маршрутизации, которая ломается только на определённых адресах.
Оставьте намеренные исключения для адресов, которые должны остаться в LAN, и решите, что происходит, когда поиск ничего не находит в выбранной таблице. Явный резервный маршрут проще осмыслить, чем пустая таблица, которая возвращает недостижимый результат и заставляет приложение выглядеть сломанным, а не направленным не туда.
Задайте поиску тот вопрос, который задаёт ваше приложение
ip route get разрешает путь; ip route show выводит сохранённые записи, и эти двое могут расходиться, при том что ни один не ошибочен. Укажите контекст источника, потому что правила на основе источника совпадают только тогда, когда поиск несёт источник.
ip route get 198.51.100.23 from 10.64.3.9
ip route get 198.51.100.23 from 10.64.3.9 iif ppp0
ip -4 rule show
Первая команда задаёт вопрос со стороны хоста. Вторая добавляет входной интерфейс, что ближе к тому, что переживает перенаправляемый трафик, и ответ часто указывает на другую таблицу. Ни один из адресов не является живым тестовым сервисом; 198.51.100.23 — это адрес для документации, поэтому замените его на хост, который вам разрешено проверять.
Даже правильный поиск доказывает лишь то, что путь был выбран. Он ничего не говорит о том, принимает ли противоположная сторона трафик или может ли ответ вернуться по тем же рассуждениям.
Где сравнение переворачивается
Трафик хоста и перенаправляемый трафик выбирают не только разные поиски; на обратном пути они встречают разные фильтры. Linux применяет проверку обратного пути по более строгому из значений для всех интерфейсов и для принимающего интерфейса, поэтому изменение значения одного интерфейса может не дать видимого эффекта. Маршрутизация по метке добавляет отношение src_valid_mark, в котором метка должна совпадать, чтобы источник считался допустимым.
Если ответы исчезают, а исходящая маршрутизация выглядит правильно, прочитайте действующие значения, прежде чем их трогать, и меняйте их только с заявленной причиной политики.
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.ppp0.rp_filter
sysctl net.ipv4.conf.all.src_valid_mark
Выбирайте между двумя схемами на основании доказательств: если приложение привязано к адресу PPP, достаточно правила источника и таблицы с маршрутом к peer. Если машина перенаправляет трафик для LAN позади себя, нужно ещё, чтобы входной контекст и обратный путь совпадали. Когда они не совпадают, исправьте принадлежность маршрута, а не ослабляйте проверку для всей машины.