Вопрос или проблема
У меня установлена 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:
Краткие ответы:
-
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'
-
Зеркальный режим сетевого соединения 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-сети.
Применение
Способы решения
-
Использование сетевого интерфейса Windows:
Чтобы получить доступ к вашему Windows-серверу из WSL2, необходимо использовать IP-адрес интерфейса Windows. На основании предоставленных данных, Ethernet адаптер с названиемvEthernet (Default Switch)
имеет IP-адрес172.29.192.1
. Используйте этот IP, чтобы установить соединение с Windows:nc -zv 172.29.192.1 8888
Этот подход гарантирует, что вы обращаетесь напрямую к интерфейсу системы Windows, где находится нужный сервер.
-
Использование mDNS (Multicast DNS):
WSL2 поддерживает mDNS, который позволяет разрешать имена хостов. Вы можете обратиться к вашему Windows-хосту с использованием комбинации$(hostname).local
. Пример команды для проверки доступности службы:ping "$(hostname).local"
Однако, если ICMP заблокирован (например, в новых установках Windows 11), проверьте доступность через другие средства, такие как netcat:
nc -zv "$(hostname).local" 8888
-
Использование режима зеркального отображения сети (Mirrored Network Mode):
В Windows 11 версии 23H2 и выше доступен режим зеркалирования сети, который устраняет необходимость в использовании mDNS для доступа к localhost:[wsl2] networkingMode=mirrored
После добавления этого конфигурационного параметра в файл
.wslconfig
и выполнения командыwsl --shutdown
, WSL2 будет зеркально отображать сетевые интерфейсы Windows, что позволит использоватьlocalhost
. -
Правила безопасности и фаерволы:
Убедитесь, что необходимые порты открыты как в сетевом экране Windows, так и в WSL2. Для первого подключения из WSL2 к Windows вы можете увидеть запрос от Windows Defender на разрешение входящих соединений. Убедитесь, что ваше серверное приложение может принимать соединения от внешних подключений, изменив настройки привязки на0.0.0.0
.
Заключение
Эти методы предполагают детальную настройку сетевых соединений и требуют понимания работы сети в виртуализированных средах. С помощью корректных конфигураций и понимания того, как именно взаимодействуют сетевые адаптеры внутри WSL2, вы можете успешно получить доступ к сервисам, работающим на вашем Windows-хосте. Ваше внимание к деталям и понимание архитектуры сети являются ключевыми аспектами для успешного разрешения подобных задач.