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

Ответ определяют три вопроса: кто подключается, какой адрес он может достичь и должна ли для него работать живая перезагрузка.

Начните с сокета, а не с файла конфигурации

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

ss -ltn '( sport = :8080 )'
ss -ltnp | grep node

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

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

Выберите адрес привязки по тому, кто должен до него добраться

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

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

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

devServer: {
  host: "10.77.0.20",
  port: 8080,
  allowedHosts: ["dev.corp.example"],
}

Адрес в этом фрагменте иллюстративен и обозначает адрес VPN, которым владеет хост. Если проект строит сервер с помощью new WebpackDevServer(options, compiler) передайте параметры через аргумент конструктора, потому что отдельное свойство devServer в конфигурации webpack на этом пути не рассматривается. Это различие между файлом конфигурации и Node API ловит тех, кто копирует фрагмент в проект, который его никогда не читает. Документация dev-server разделяет два стиля запуска и является ориентиром, с которым нужно сверять используемую версию.

Согласуйте проверку имени хоста с именами, которые вы одобряете

Проверка имени хоста существует, чтобы страница, отданная с имени, контролируемого атакующим, не могла через браузер говорить с вашим сервером разработки. Отключение её с помощью allowedHosts: "all" снимает эту защиту, и удобство редко того стоит на машине, которая может достичь внутренних служб. Проверку дёшево удовлетворить правильно, когда вы знаете, какие имена пришлёт браузер.

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

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

Проверьте страницу и сокет живой перезагрузки вместе

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

curl -sS -o /dev/null -w "%{http_code} %{remote_ip}\n" http://dev.corp.example:8080/
curl -sS -i http://10.77.0.20:8080/ | head -n 5

Затем откройте сетевую диагностику браузера и наблюдайте за соединением WebSocket. Страница может загружаться по одному имени хоста, порту и схеме, пока сокет перезагрузки использует другие, поэтому их нужно проверять по отдельности. Настраивайте документированный URL клиента только тогда, когда развёрнутый путь действительно требует другого значения, и предпочитайте исправлять путь, а не учить клиента обходному решению.

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

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