Невозможно установить связь с Windows localhost из WSL2.

Вопрос или проблема

У меня есть приложение, работающее на Windows на локальном хосте (127.0.0.1) порт 8545. Моя цель – иметь возможность взаимодействовать с этим приложением из WSL2. Однако каждый раз, когда я пытаюсь получить доступ к адресу из WSL2, возникает ошибка таймаута соединения.

Вот краткое изложение того, что я пытался сделать:

  1. отключил брандмауэр Windows Defender для WSL в соответствии с
    ответом здесь:

    WSL2 подключение к хосту без отключения брандмауэра Windows

  2. узнал, какой у моего хоста (Windows) локальный IP, запустив эту команду в терминале WSL
    (возвращает 172.22.144.1):

    echo $(ip route list default | awk ‘{print $3}’)

  3. пропинговал запущенное приложение Windows из терминала WSL, используя:

    nc -zv 172.22.144.1 8545

После шага 3 ничего не происходит некоторое время, а затем я получаю ошибку таймаута соединения.

Из PowerShell Windows я могу успешно пропинговать то же приложение вот так:

Test-NetConnection 127.0.0.1 -p 8545

Кто-нибудь знает, в чем может быть проблема? Что мне нужно сделать, чтобы разрешить WSL2 взаимодействовать с локальным хостом Windows? Я использую Windows 10 Home и WSL2.

С момента выхода версии 2.0.0 WSL2 появилась новая сеть功能, которая обходит необходимость в почти всех пунктах моего первоначального ответа. Тем не менее, обе техники все еще полезны. Я пересматриваю этот ответ, чтобы сначала перечислить новый режим (“Зеркечная Сеть”).

Зеркечный Режим

Примечание: Доступен только в версии 2.0.0 WSL2 с Windows 11 22H2 или выше.

В этом режиме сетевые интерфейсы Windows зеркалируются в WSL2. Когда вы запускаете ip addr, например, вы увидите (в основном) те же интерфейсы, что и при запуске ipconfig /all из PowerShell/CMD.

В результате это исключает необходимость в трех пунктах, упомянутых в разделе NAT:

  • localhost можно использовать из WSL2 для подключения к обратному адресату для Windows
  • Правила брандмауэра между Windows и WSL2 не нужны 1, поскольку Windows будет считать трафик WSL2 “локальным”
  • Адрес привязки для вашей службы Windows все еще может быть адресом локального хоста, а не 0.0.0.0
Чтобы включить зеркечный режим:
  • Создайте или отредактируйте %UserProfile%\.wslconfig и добавьте следующее:

    [wsl2]
    networkingMode=mirrored
    
  • Выйдите из вашей дистрибуции WSL

  • Запустите wsl --shutdown из PowerShell, затем перезапустите WSL

После этого вы сможете получить доступ к службам, работающим в Windows, через localhost.

Обратите внимание, что при работе в зеркечном режиме mDNS не работает.

Режим NAT (по умолчанию/оригинальный)

Чтобы получить доступ к сетевой службе/приложению, работающему на хосте Windows из WSL2, вам нужно сделать три вещи:

  • *Настроить службу так, чтобы она прослушивала корректный сетевой интерфейс Windows (не localhost), т.е. “адрес привязки”.

  • Открыть необходимые порты брандмауэра

  • Использовать правильный адрес из WSL2 (снова, не localhost)

Для вас, инициатор этого вопроса, похоже, что вы уже правильно сделали 2-й и 3-й пункты, и нужно только изменить первый.

Дополнительные подробности по каждому из этих пунктов приведены ниже:

Адрес привязки

Многие приложения или службы по умолчанию привязываются к localhost, что (очевидно) означает, что вы можете подключаться к ним только с хоста, на котором работает служба. Поскольку WSL2 работает в “отдельной сети”, вы не сможете получить доступ к службе в Windows, которая прослушивает только на localhost. Как упомянул @DanielB, вам, вероятно, нужно будет привязаться к 0.0.0.0 (для IPv4) и/или :: (для IPv6), чтобы слушать на всех интерфейсах.

Метод настройки службы, конечно, будет различаться для различных приложений, но обычно вы найдете настройку с подписью вроде “Адрес привязки”, “Прослушивать на” или что-то подобное.

Не забудьте перезапустить приложение/службу после изменения этой настройки.

Конфигурация брандмауэра

По умолчанию брандмауэр Windows Defender (и другие) будет блокировать входящие соединения на хост с другой сети. Учитывая, что мы уже установили, что WSL2 работает в отдельной сети, вам нужно будет открыть порт брандмауэра для вашей службы.

Инициатор этого вопроса полностью отключил брандмауэр, когда подключался через интерфейс WSL2, что нормально. Вы также можете сделать это из PowerShell (в административной оболочке) с помощью чего-то вроде:

New-NetFirewallRule -DisplayName "Spring App Testing" -InterfaceAlias "vEthernet (WSL)" -Direction Inbound -Protocol TCP -LocalPort 8545 -Action Allow 

Конечно, вы можете опустить либо:

  • адрес InterfaceAlias, в этом случае он откроет 8545 для всех сетей
  • или LocalPort, в этом случае он будет действовать как опция “отключить” выше и всегда принимать входящий трафик с интерфейса WSL.

Поиск корректного адреса Windows для использования из WSL2

Существует несколько методов (и IP-адресов), которые вы можете использовать. Самый простой способ – просто использовать IP-адрес хоста Windows, если вы его знаете. Однако, если он назначается динамически и часто меняется (что, я полагаю, довольно необычно в наши дни), то вам, возможно, придется менять свой код WSL2 при каждой перезагрузке.

Тем не менее, вероятно, лучше использовать имя mDNS, которое будет (обычно) разрешаться правильно.

Предполагая, что вы не переопределили /etc/resolv.conf, который генерирует WSL, это можно сделать, взяв имя компьютера Windows и просто добавив .local. Например, если имя вашего компьютера bubblegum, то bubblegum.local должно быть правильным адресом.

Вы должны обнаружить, что это тот же адрес, что и при выполнении:

echo $(ip route list default | awk '{print $3}')

Если же вы переопределили /etc/resolv.conf (необходимые в некоторых случаях из-за VPN или других сетевых настроек), то вам может потребоваться что-то более сложное, например:

echo $(host `hostname --long` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r')

(Кредит @ChaiAng’s answer on Ask Ubuntu за этот метод).

Однако обратите внимание, что это существенно медленнее, чем mDNS.


1 Обратите внимание, что зеркечный режим также делает вашу WSL2-экземпляр доступным для других устройств в вашей сети, и по этой причине также существует новая функция брандмауэра WSL2/Hyper-V, которая по умолчанию блокирует этот трафик. Включение трафика между местной сетью и WSL2 это отдельная тема.

Этот ответ устарел. Для последних версий Windows и WSL обратитесь к другой записи от NotTheDr01ds, которая охватывает новый режим Зеркечного Режима.


localhost/127.0.0.1/::1 сети являются специальными. Каждый компьютер имеет свой собственный localhost. Вы не можете подключиться к localhost других компьютеров через сеть.

Виртуальные машины (такие как WSL 2) считаются разными компьютерами. Существуют также сетевые пространства имен, которые также работают как разные компьютеры в данном вопросе.

Если вы хотите получить доступ к вашей службе, работающей на Windows из WSL 2, вы не должны позволять ей привязываться к localhost. “Следующий лучший” способ – привязаться к виртуальному сетевому адаптеру Hyper-V для WSL, но его IP-адрес динамический. Вы также можете привязаться к 0.0.0.0/::, но это делает вашу службу доступной на всех интерфейсах (правила брандмауэра по-прежнему применяются).

Из WSL 2 вы можете подключиться, используя $(hostname).local (или любой другой способ, который вы уже нашли, чтобы получить IP-адрес хоста).


Существует одно специальное исключение при попытке подключиться к службам, работающим в WSL 2 из Windows (то есть в обратном направлении): Microsoft реализовала программное решение, которое делает localhost слушатели WSL 2 доступными из Windows (также по localhost). Это относительно ненадежно.

Ответ или решение

Невозможность связи с локальным хостом Windows из WSL2: Варианты решения проблемы

Проблема связи с локальным хостом Windows из среды Windows Subsystem for Linux 2 (WSL2) является распространенной среди разработчиков и администраторов. Она часто возникает, когда приложения слушают только на localhost (127.0.0.1) и не могут быть доступны из WSL2, поскольку WSL2 функционирует в отдельном сетевом пространстве. В данной статье мы подробно рассмотрим возможные причины данной проблемы и предоставим несколько вариантов её решения.

1. Понимание архитектуры WSL2

WSL2 работает на базе Hyper-V, создавая виртуальную машину с отдельной сетевой подсистемой. Это означает, что обращения к localhost из WSL2 не перехватываются вашим приложением, работающим на Windows, так как для WSL2 localhost – это другой адрес. Это отличает WSL2 от WSL1, который использовал тот же сетевой стек, что и Windows.

2. Использование режима «Mirrored Networking»

С выходом Windows 11 (версия 22H2) в WSL2 добавлен режим «Mirrored Networking», который позволяет использовать localhost для подключения к сервисам Windows прямо из WSL2. Чтобы активировать этот режим, выполните следующие шаги:

  1. Создайте или отредактируйте файл конфигурации %UserProfile%\.wslconfig и добавьте следующую секцию:

    [wsl2]
    networkingMode=mirrored
  2. Закройте все интерактивные оболочки WSL.

  3. Запустите команду wsl --shutdown в PowerShell, а затем перезапустите WSL.

Теперь вы сможете обращаться к сервисам Windows через localhost из WSL2.

3. Варианты для старых версий WSL2 и Windows

Если ваш компьютер не поддерживает новый режим, используйте следующие шаги для настройки связи между WSL2 и Windows:

a. Изменение адреса привязки

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

Пример конфигурации может выглядеть так:

  • Если это веб-сервер, убедитесь, что он слушает на всех интерфейсах, а не только на localhost.

b. Настройка брандмауэра Windows

Убедитесь, что брандмауэр Windows позволяет подключения на необходимый порт (в вашем случае 8545). Для этого выполните команду в PowerShell с правами администратора:

New-NetFirewallRule -DisplayName "WSL2 Access" -Direction Inbound -Protocol TCP -LocalPort 8545 -Action Allow

Это создаст правило для безопасного управления входящими соединениями.

c. Определение IP-адреса Windows

Чтобы подключиться к приложению, работающему на Windows, вам необходимо знать подключаемый IP-адрес. В WSL2 можно определить IP-адрес с помощью следующей команды:

echo $(ip route list default | awk '{print $3}')

4. Заключение

Если у вас возникли трудности с подключением к сервисам Windows из WSL2, проверьте настройки привязки адреса, условия брандмауэра и используйте правильный IP-адрес. Новая функция «Mirrored Networking» существенно упрощает этот процесс для пользователей Windows 11. Обязательно следите за обновлениями Windows и WSL, так как Microsoft активно улучшает интеграцию между Windows и WSL, что открывает новые возможности для разработчиков и администраторов.

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

Оцените материал
Добавить комментарий

Капча загружается...