Доступ к локальному хосту Windows из WSL2?

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

У меня установлена Windows 11 с WSL2 (Ubuntu).

Я настроил сервер прослушивания gdb на локальном хосте Windows и хочу получить к нему доступ из WSL2, но, похоже, мой компьютер с Windows и WSL используют разные сетевые адаптеры.

>ipconfig

Настройка IP Windows


Адаптер Ethernet vEthernet (Default Switch):

   Суффикс DNS для этого подключения  . :
   IPv6-адрес канала связи . . . . . . : fe80::1114:bb:d0ad:93f8%18
   IPv4-адрес. . . . . . . . . . . . . : 172.29.192.1
   Маска подсети . . . . . . . . . . . : 255.255.240.0
   Основной шлюз . . . . . . . . . . . :

Адаптер Ethernet vEthernet (WSL):

   Суффикс DNS для этого подключения  . :
   IPv6-адрес канала связи . . . . . . : fe80::897:849a:5fed:1c6e%52
   IPv4-адрес. . . . . . . . . . . . . : 172.21.128.1
   Маска подсети . . . . . . . . . . . : 255.255.240.0
   Основной шлюз . . . . . . . . . . . :

Мой сервер активно прослушивает порт 8888 и доступен в Windows, но не в Ubuntu/WSL.

Я открыл порт 8888 как в брандмауэре Windows, так и в брандмауэре Ubuntu

Каково решение?

localhost не работает, потому что WSL2 работает с виртуальной сетью
(vNIC), созданной платформой виртуальных машин Windows (подмножество Hyper-V). Внутри WSL2 localhost – это адрес vNIC.

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

ip route

Адрес “default via” – это адрес, который следует использовать для хоста Windows.

Вы можете извлечь его из вышеуказанного или из /etc/resolv.conf, но WSL
также устанавливает mDNS, домен .local, используя “имя компьютера” Windows, которое также используется как hostname экземпляра WSL.

Для доступа объедините $(hostname) с .local.

Попробуйте:

ping "$(hostname).local"

Или, если ICMP заблокирован (как кажется в новых установках Windows 11),
используйте netcat. Он доступен по умолчанию в установке Ubuntu через WSL,
но может потребоваться его установка в других дистрибутивах, таких как openSUSE:

nc -zv "$(hostname).local" <portnumber>

Ссылка на ответ:
Доступ к localhost, работающему в Windows, изнутри WSL2?
ответ от NotTheDr01ds.

В версии 2.0.0 WSL2 доступны два хороших варианта для этого (и несколько не таких хороших). Копируется из моего ответа на Stack Overflow по этой теме 1:

Краткие ответы:

  1. NAT (по умолчанию) сетевое соединение WSL2 с mDNS

    Объединение вашего hostname WSL2 (или эквивалентной команды/функции в вашей программной/языковой среде) с ".local" (имя хост mDNS) должно 2 сделать вас доступным. Например, в Bash попробуйте:

    ping "$(hostname).local"
    

    Или, допустим, вы пытаетесь получить доступ к MongoDB из Python, как в этом вопросе:

    import socket
    server = f'{socket.gethostname()}.local'
    host = f'mongodb://{socket.gethostname()}.local'
    
  2. Зеркальный режим сетевого соединения WSL2

    Примечание: Требуется Windows 11 23H2 или более поздняя

    В зеркальном режиме localhost должен “сразу работать”. Чтобы включить:

    • Добавьте следующее в ваш <windows_user_profile>/.wslconfig:

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

    • Выполните wsl --shutdown в PowerShell, затем перезапустите WSL

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

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

Более подробное объяснение:

Вариант 1: NAT с mDNS

Режим сети по умолчанию в WSL2 — это NAT за виртуальным коммутатором Hyper-V. До недавнего времени это был единственный режим сетевого подключения для WSL2. В этом режиме WSL2 работает с виртуальной сетью (vNIC), которая создается платформой виртуальных машин Windows (подмножество Hyper-V). Внутри WSL2 localhost — это адрес vNIC, а не хоста Windows.

В этом режиме использование имени mDNS для хоста Windows 3 обычно является самым простым решением.

mDNS был функцией WSL2 уже некоторое время назад. Объединение вашего hostname из WSL2 (или эквивалентной команды/функции в вашей программной/языковой среде) с ".local" должно обеспечить доступ.

Как упоминалось выше, в Bash попробуйте:

ping "$(hostname).local"

Например, если ваш hostname — “MyComputer”, то mDNS будет MyComputer.local.

Если ICMP заблокирован (как кажется в новых установках Windows 11) или если вы хотите протестировать соединение с фактическим портом, используйте netcat вместо ping. Он доступен по умолчанию в установке Ubuntu через WSL, но может потребоваться его установка в других дистрибутивах, таких как openSUSE:

nc -zv "$(hostname).local" <portnumber>

См. также “Другие соображения по NAT/mDNS” 2.

Вариант 2: Зеркальный режим сети

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

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

По этой причине localhost маршрутизируется через зеркальный Windows адаптер loopback.


Сноски:

1 Дублированная (и новая) информация

  • Хотя я не люблю дублировать часть текуще принятого ответа, как отмечалось, текуще принятое решение и так основано на моей версии Stack Overflow. @harrymc действительно спрашивал в комментариях хочу ли я его здесь разместить, но на тот момент я отказался.

  • Однако за эти годы я добавил новую информацию в версию SO, которая не была внесена в этот вопрос SU. Учитывая (сейчас) накопившиеся значительно изменения, считаю, что информация должна быть здесь также.

  • Версия SO технически не по теме и в настоящее время там закрыта. Этот вопрос SU соответствует теме и должен быть каноническим вопросом, где размещается новая информация по теме.


2 Другие соображения по NAT/mDNS

  • mDNS полагается на хост Windows для разрешения имени. Если вы изменили /etc/resolv.conf в WSL, это, вероятно, не сработает.

  • Не забывайте открывать все необходимые порты брандмауэра. WSL2 считается отдельной сетью от сети хоста Windows. Windows будет считать сетевые подключения от WSL2 входящими из внешнего источника. (Благодаря @RamilGilfanov за комментарий, указывающий на это)

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

  • Не забывайте, что ваша служба Windows допускает подключения от удаленных хостов.

    Многие серверы по умолчанию настроены на привязку к localhost/127.0.0.1. Поскольку WSL2 представляет собой удалённую сеть для Windows, вам обычно нужно будет обновить конфигурацию, чтобы связаться с 0.0.0.0 или определённым адресом.

    Обратите внимание, что так как адрес для WSL2 меняется после каждой перезагрузки, может быть трудно обновить вашу конфигурацию каждый раз. Если это вообще возможно, используйте 0.0.0.0, если нет проблем с безопасностью. Так как WSL предназначен для разработки, а не для производства, это не должно стать проблемой.


3 Технически это IP-адрес виртуального коммутатора, который WSL2 использует для взаимодействия с Windows и внешним миром.

Вы можете увидеть это через:

ip route

Это адрес, который необходимо использовать для хоста Windows.

Вы могли бы, конечно, извлечь его из маршрута (или, как в предыдущем ответе, из /etc/resolv.conf), но так как WSL устанавливает удобный mDNS (домен .local), легче использовать его.

Далее, расширяя ответ от @harrymc и @NotTheDr01ds:

Как правило, вы можете обратиться к службам Windows из командной строки WSL2, используя "$(hostname).local" в качестве имени хоста. Если такие соединения кажутся заблокированными, попробуйте следующее:

  • Проверьте, не блокирует ли брандмауэр Windows трафик. Легкий способ проверить — отключить его на несколько секунд и повторить тест. Если это сработает, добавьте нужные правила в брандмауэр.

  • Выполните команду nslookup "$(hostname).local". Это даст вам много IP-адресов. По умолчанию будет использоваться первый, но он может не подходить. Попробуйте также другие. Если вы найдете подходящий, вы можете настроить короткий скрипт для вашей системы, который всегда будет возвращать правильный IP.

“localhost” всегда относится к самой системе. Когда вы запускаете основную ОС и виртуализированную ОС, вы запускаете 2 системы, каждая из которых ссылается на себя как “localhost”. Так что вы никогда не сможете получить доступ к “localhost” другой системы, вам нужно использовать её внешний IP.

В вашем случае, если вы хотите получить доступ из системы Ubuntu к службе, работающей на вашем хосте Windows и прослушивающей порт 8888, вам нужно получить доступ к 172.29.192.1:8888. Только система, фактически предлагающая услугу, должна прослушивать порт и разрешать новые входящие соединения через этот порт.

Поскольку Ubuntu является отдельной системой, у вас не будет ничего, что слушает порт 8888, если вы не установите службу, которая будет его прослушивать.

Другие ответы решили это, используя "$(hostname).local".

Однако, по крайней мере в моем случае (Ubuntu 23.10 на WSL 2), при выполнении команды ping "$(hostname).local" произошла ошибка:

ping: <myhostname.local: Имя или услуга не известны

Мне удалось это исправить, установив libnss-mdns, что позволило команде ping выполняться нормально. (Установите sudo apt install libnss-mdns, чтобы установить на Ubuntu)

Источник исправления: https://github.com/microsoft/WSL/issues/10077#issuecomment-1736181588

.

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

Доступ к localhost Windows из среды WSL2 может вызвать определенные трудности из-за особенностей сетевой архитектуры этих систем. Понимание того, как правильно настраивать сетевые соединения между Windows и WSL2, особенно важно при взаимодействии с сервисами, которые работают на Windows и должны быть доступны из Ubuntu, установленного в WSL2.

Теория

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

Пример

Предположим, вы настроили сервер прослушивания gdb, который активирует порт 8888 на вашей системе Windows. Несмотря на то, что сервер работает и доступен с локального интерфейса Windows, попытки получить доступ к нему из WSL2 могут не увенчаться успехом, так как localhost в данном случае ссылается на другую сеть, отличающуюся от вашей Windows-сети.

Применение

Способы решения

  1. Использование сетевого интерфейса Windows:
    Чтобы получить доступ к вашему Windows-серверу из WSL2, необходимо использовать IP-адрес интерфейса Windows. На основании предоставленных данных, Ethernet адаптер с названием vEthernet (Default Switch) имеет IP-адрес 172.29.192.1. Используйте этот IP, чтобы установить соединение с Windows:

    nc -zv 172.29.192.1 8888

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

  2. Использование mDNS (Multicast DNS):
    WSL2 поддерживает mDNS, который позволяет разрешать имена хостов. Вы можете обратиться к вашему Windows-хосту с использованием комбинации $(hostname).local. Пример команды для проверки доступности службы:

    ping "$(hostname).local"

    Однако, если ICMP заблокирован (например, в новых установках Windows 11), проверьте доступность через другие средства, такие как netcat:

    nc -zv "$(hostname).local" 8888
  3. Использование режима зеркального отображения сети (Mirrored Network Mode):
    В Windows 11 версии 23H2 и выше доступен режим зеркалирования сети, который устраняет необходимость в использовании mDNS для доступа к localhost:

    [wsl2]
    networkingMode=mirrored

    После добавления этого конфигурационного параметра в файл .wslconfig и выполнения команды wsl --shutdown, WSL2 будет зеркально отображать сетевые интерфейсы Windows, что позволит использовать localhost.

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

Заключение

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

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

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