Рукопожатие WireGuard работает, а служба — нет
Успешное рукопожатие доказывает только туннель. Службе на VPN-хосте по-прежнему нужны слушающий сокет, правило ввода и собственные проверки прав.
Рукопожатие завершается, клиент показывает свежий счётчик передачи, и всё же запрос к службе на том же сервере не проходит. Такое сочетание сбивает с толку, ведь туннель заведомо работает. Не доказана локальная доставка: пакет дошёл до хоста, и хосту ещё нужно принять его на нужном сокете и передать процессу с правом ответить. Пройдите эти три контрольные точки по порядку.
Остановитесь на первой, которая не выполняется, и не добавляйте правила для остальных.
Рукопожатие доказывает только туннель
Рукопожатие WireGuard устанавливает ключи между узлами и разрешает трафик для диапазонов, которые перечислил каждый узел. Оно ничего не говорит о том, какие процессы слушают на сервере, и ничего о том, принимает ли межсетевой экран хоста пакеты, адресованные одному из его собственных адресов.
Именно это последнее различие чаще всего упускают: трафик к самому хосту — это локальный ввод, а трафик, проходящий через хост в другое место, — это пересылка. Их обрабатывают разные цепочки межсетевого экрана и разные настройки. Проверка не той цепочки стоит половины дня и возвращает счётчики, которые выглядят безобидно.
Прочитайте слушатель и маршрут
На клиенте убедитесь, что адрес туннеля сервера маршрутизируется в туннель. На сервере убедитесь, что сокет существует на адресе, который использует клиент, и что процесс за ним — тот, который вы задумали.
wg show ip route get 10.66.0.1 ss -lntup | grep -E ':80|:443' nft list ruleset | grep -A6 'chain input' curl -vk --max-time 5 https://10.66.0.1/
Слушатель на 127.0.0.1 никогда не ответит на запрос, адресованный 10.66.0.1, что бы ни разрешал межсетевой экран. Слушатель на общем адресе ответит, если правило его не блокирует. Поэтому список сокетов решает половину случаев ещё до просмотра любого правила. Порт и адрес вместе определяют, может ли запрос дойти.
Сравните адрес, который использует клиент, с адресом, который сервер на самом деле имеет на интерфейсе туннеля. Устаревшая конфигурация с любой стороны создаёт запрос, правильно маршрутизированный к узлу, у которого такого адреса нет.
Применяйте правила для локального ввода, а не для пересылки
Если пакет пришёл и сокет существует, оставшейся границей остаётся политика ввода. Правило, разрешающее пересылку, не разрешает локальную доставку, а правило, ограниченное одним интерфейсом, может не совпасть с ожидаемым именем интерфейса туннеля.
Проверяйте одним разрешённым портом к нужной службе, вместо того чтобы открывать хост. Затем проверьте собственную авторизацию приложения: список разрешённых, требование учётной записи или привязка к конкретному имени хоста могут отклонить запрос, который сеть доставила успешно.
Оставьте проверки сертификатов включёнными. Неожиданная личность сертификата — это сведения о том, какой хост ответил, а не препятствие, которое нужно обойти. Проход через предупреждение скрывает единственную подсказку, указывающую на не ту службу.
Разделяйте отказы по имени, размеру и личности
Служба, которая работает по адресу, но не работает по имени, — это проблема DNS, и исправление относится к конфигурации резолвера, передаваемой клиенту, а не к межсетевому экрану. Служба, которая отвечает на маленькие запросы, но застревает на больших ответах, указывает на размер пакета и MTU, а это совсем другое расследование.
Ошибка HTTPS с неверным именем хоста обычно означает, что запрос дошёл до другой службы, часто потому, что этот порт занят прокси или другим слушателем. Прочитайте субъект сертификата и сравните его с хостом, к которому вы хотели попасть. Это сравнение ничего не стоит и часто завершает расследование.
Запишите, какая контрольная точка не сработала: сокет, правило ввода или политика приложения. Эта одна строка отличает сетевой сбой от решения об авторизации. Она же мешает следующему человеку открывать порты, которые никогда не были проблемой.