Что OpenVPN route-nopull на самом деле не даёт серверу протолкнуть
route-nopull отбрасывает проталкиваемые маршруты и параметры DHCP, а не рукопожатие. Выберите между ним, pull-filter и ничем, затем добавьте маршруты сами.
Вы добавили route-nopull в профиль клиента, чтобы туннель не поглотил ваш маршрут по умолчанию, и теперь подсеть офиса недоступна, хотя клиент по-прежнему говорит, что соединён. Оба наблюдения верны, и ничего не сломалось. Флаг велит клиенту пропускать маршруты и записи DHCP, которые проталкивает сервер, — инструкция более узкая, чем ожидают большинство, добавляя его. Остаётся работающий туннель, не имеющий мнения о том, какие адресаты должны им пользоваться.
Этот разрыв и есть всё решение, о котором эта статья. Либо сервер описывает сеть, либо клиент, и флаг передаёт эту работу клиенту, ничего из неё за вас не делая.
Что флаг отключает при подключении
Клиент OpenVPN, который тянет, обычно после аутентификации принимает от сервера пакет: маршруты, перенаправление шлюза по умолчанию, серверы DNS и несколько директив настройки. Когда route-nopull действует, клиент по-прежнему принимает сеанс, по-прежнему проверяет сертификаты, по-прежнему согласует шифры и keepalive и по-прежнему поднимает интерфейс. Отбрасывает он применение протолкнутых строк route и протолкнутых строк dhcp-option, включая DNS.
Путаница возникает из-за зелёного индикатора рядом с мёртвым приложением. Туннель существует; сопоставление адресатов с этим туннелем — нет. Ничто на панели состояния клиента не отличает «подключён и маршрутизирует» от «подключён и бездействует», потому что с точки зрения туннеля это одно и то же состояние.
Почему живой туннель всё равно может ничего не маршрутизировать
Интерфейс появляется со своим адресом, и на соединении точка-точка часто нет ничего конкретнее маршрута к узлу в сторону партнёра. Частная подсеть становится доступной только тогда, когда какой-то маршрут указывает на этот интерфейс с правильным префиксом, а при отключённом проталкивании такой маршрут никогда не приходит. Скачанный профиль тоже обычно не помогает, потому что он написан в предположении, что сервер предоставит именно эти сведения. Поэтому интерфейс может выглядеть здоровым, пока подсеть остаётся тёмной.
Чтение профиля поэтому доказывает очень мало. Читайте текущее состояние на подключённой машине:
ip addr show tun0
ip route show dev tun0
ip route get 10.20.5.10
Адрес без маршрута подсети во второй команде — подпись этой проблемы. Третья команда затем отвечает на вопрос, который действительно важен пользователям, потому что сообщает интерфейс, который ядро выбрало бы для конкретного адресата, а не список, на который вы надеялись. Если она отвечает через ваше физическое соединение, туннеля в пути вообще нет.
Разрешение имён не удаётся по связанной причине, а не по отдельной. Протолкнутые записи dhcp-option DNS пропускаются тем же флагом, поэтому запросы о внутренних узлах идут к тому распознавателю, который предоставила локальная сеть. У этого распознавателя нет зоны для офиса, поэтому запрос не удаётся или возвращает публичный ответ, и сбой выглядит как проблема сервера, хотя это проблема конфигурации клиента. Проверка адреса до имени — то, что разделяет эти две вещи.
Выбор между флагом и фильтром префиксов
Оба варианта решают разные формы одной жалобы, и именно плохой выбор создаёт состояние «подключён, но бесполезен». Один целиком заменяет проталкиваемую политику, другой редактирует её по префиксу. Таблица даёт короткую версию, а абзац после неё охватывает часть, которая застаёт людей врасплох.
| Setting | What the client keeps | Reasonable when |
|---|---|---|
| no option | every pushed route and DHCP entry | the server's view of the network is correct |
route-nopull | the session, none of the pushed routing or DNS | you will write the full local policy yourself |
pull-filter | everything except lines matching your prefixes | the push is nearly right and one or two lines are wrong |
pull-filter — сопоставитель префиксов с тремя глаголами, поэтому он может принимать семейство строк, молча их игнорировать или полностью отклонять соединение, когда появляется префикс. Именно последнее поведение стоит знать: правило отказа превращает расхождение в политике в неудавшееся рукопожатие, а не в тихое опущение. Руководство OpenVPN 2.6 перечисляет принимаемые префиксы и точную семантику каждого глагола.
Частый средний путь — отклонить только redirect-gateway и позволить маршрутам офиса и DNS прийти как задумано. Это сохраняет проталкивание работающим для тех частей, которые сервер понимает лучше вас, и одновременно предотвращает ту единственную строку, которая заняла бы ваш маршрут по умолчанию.
Добавление маршрутов и распознавателя вручную
Если вы оставляете флаг, профиль должен сказать то, что сказал бы сервер. Клиентские директивы route применяются после установления соединения, поэтому работают рядом с флагом, а не блокируются им. Поместите их в профиль, а не в интерактивную командную строку, иначе следующее переподключение не воспроизведёт рабочее состояние.
route-nopull
route 10.20.0.0 255.255.0.0
dhcp-option DNS 10.20.0.53
Строка DNS находится в неудобном положении: это клиентская директива, но некоторые клиенты применяют её только через интеграцию DNS платформы, которая может перезаписать её при смене соединения. На хосте с systemd задать распознаватель прямо на интерфейсе туннеля предсказуемее, чем надеяться, что клиент выиграет состязание приоритетов:
resolvectl dns tun0 10.20.0.53
resolvectl domain tun0 ~corp.example.com
Домен маршрутизации важен не меньше адреса. Без него запросы о публичных именах тоже могут уходить внутреннему распознавателю, и любой внутренний распознаватель, отказывающий в рекурсии, сломает просмотр, оставив частную зону работающей. С ним к распознавателю туннеля направляются только имена под этим суффиксом, а всё остальное идёт по физическому соединению.
Проверка результата: адрес, имя и внешний путь
Три теста разделяют возможные сбои. Получите частный адрес по IP, затем тот же узел по имени, затем обычный публичный сайт. Работающий IP с неработающим именем указывает на распознаватель; неработающий IP с работающим именем указывает на маршрутизацию; если не работают оба, обычно туннеля нет в пути.
Затем смотрите наружу, а не внутрь. Собственный маршрут конечной точки туннеля должен пережить изменение, и любая блокирующая неисправность должна быть ограничена туннелем, не захватывая конечную точку. Клиент, который продолжает просмотр после падения туннеля, — это проблема политики, а не маршрутизации, и она не проявится ни в одном из трёх тестов выше.
Запишите итоговый список в документацию профиля: маршруты, распознаватель, домены и причину существования каждого. Переподключение, воспроизводящее ту же таблицу, — единственное доказательство того, что локальная политика полна. Если приложения всё ещё сбоят при поднятом туннеле и всех трёх пройденных тестах, следующее место для взгляда — класс проблем «подключён, но офлайн», а не уже проверенные сертификаты.