Рейтинг:2

Доступ к приложению WSL2 Ubuntu в сети размещенной машины

флаг tr

Я запускаю приложение в WSL2, дистрибутивом которого является Ubuntu 20.04. Я могу получить доступ к приложению в браузере Windows с IP-адресом Ubuntu.

Теперь я хочу получить доступ к этому приложению в своей сети (я имею в виду в моей офисной сети на другом компьютере)

Я понимаю, что IP-адрес Ubuntu доступен только для хост-машины. Как я могу сделать его доступным для других в моей сети?

Как мы можем это сделать? Пожалуйста помоги.

флаг hr
WSL или WSL2? процедура кажется другой - см., например, [Перенаправление портов WSL] (https://dev.to/vishnu12/wsl-port-forwarding-2e22)
флаг tr
Это WSL2, но приведенный выше пример предназначен для WSL. Пожалуйста, поправьте меня, если я ошибаюсь
флаг hr
Я *думаю*, что вам не нужно ничего делать для WSL (он должен «просто работать»), тогда как для WSL2 вам нужно настроить переадресацию портов, как описано в связанной статье. Но посмотрим, какие ответы вы получите.
NotTheDr01ds avatar
флаг vn
@steeldriver Вы правы. Я добавлю намного больше деталей в свой ответ. Прошло некоторое время с тех пор, как я сделал это, но у меня есть несколько новых идей, чтобы попробовать с прошлого раза, которые я предложу, если они сработают. Переадресация портов будет работать, но этот пост кажется слишком сложным. Я надеюсь, что смогу предложить что-то более эффективное, но посмотрим.
флаг hr
@ NotTheDr01ds отлично - с нетерпением жду чтения!
NotTheDr01ds avatar
флаг vn
И @Raushan, просто для ясности, документ, на который ссылается steeldriver, предназначен для WSL2. Как указано вверху, WSL1 ничего подобного не требовалось. Но опять же, не следуйте этому документу. Это сработает, но у меня есть решение (которое я уже подтвердил), которое я пишу как ответ, который, как мне кажется, проще.
Рейтинг:3
флаг vn

Краткий ответ для WSL1:

Настройте правила брандмауэра один раз, и все должно «просто работать». Это самый простой способ.

Краткий ответ для WSL2:

После правильной настройки вы можете очень легко инициировать переадресацию портов с помощью одной команды из Ubuntu/WSL2:

ssh -f -N -R 8080:localhost:8080 "$(имя хоста).local"

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


(Намного) подробнее:

Как отмечает Steeldriver в комментариях, WSL1 и WSL2 ведут себя здесь по-разному.

Примечание просто для уточнения терминологии (поскольку в комментариях она немного отличалась): «WSL» относится к самой подсистеме, которая управляет обеими версиями — WSL1 и WSL2.

Примечание 2. Пожалуйста, пусть вас не пугает длина этого поста. я только очень подробный. Принимая во внимание связанная проблема с Github до (в настоящее время) 536 комментариев, я думаю, что я довольно лаконичен по сравнению ;-).


WSL1

WSL1, безусловно, является более простым вариантом использования. Поскольку это «уровень перевода» между системными вызовами Linux и ядром Windows, он фактически использует «настоящие» сетевые интерфейсы Windows. По этой причине вы можете напрямую подключаться с другого устройства в сети к порту в WSL1.

Вы, вероятно, делать однако все еще нужно правило брандмауэра. Я расскажу об этом в ответе WSL2, так как это общее для обоих. См. New-NetFirewallRule в разделе WSL2. Просто запустите эту команду (один раз) для правила брандмауэра.

Однако, если ваше веб-приложение не требует WSL2 (а большинство нет), обычно гораздо проще запустить его из экземпляра WSL1 (по крайней мере, так было раньше). Это то, что делает большинство людей. С другой стороны, с новым (по крайней мере, для меня) методом WSL2/SSH, который я предлагаю ниже, это не так болезненно, как раньше, делать это в WSL2. Я оставлю это вам, какой маршрут выбрать. На данный момент я считаю, что любой из них одинаково действителен.

Если вы решите использовать WSL1, я бы рекомендовал иметь два экземпляра Ubuntu — один с WSL1, а другой с WSL2. Это то, чем я занимаюсь.

Чтобы скопировать существующий экземпляр WSL2 в новый WSL1, выйдите из существующего и в PowerShell:

# Отрегулируйте базовый путь по желанию
$WSL_ROOT = "$env:ПРОФИЛЬ ПОЛЬЗОВАТЕЛЯ\WSL"
$WSL_IMAGE_NAME = "$(get-date -UFormat `"%Y-%m-%d`") Ubuntu Backup.tar"
mkdir -p "$WSL_ROOT\изображения"
mkdir -p "$WSL_ROOT\экземпляры\Ubuntu_WSL1"
компакт-диск $WSL_ROOT
wsl -l -v
# Подтвердите название дистрибутива. Если это не «Ubuntu», при необходимости измените следующую строку
wsl --export Ubuntu "$WSL_ROOT\images\$WSL_IMAGE_NAME"
wsl --import Ubuntu_WSL1 .\instances\Ubuntu_WSL1\ .\images\$WSL_IMAGE_NAME --версия 1
wsl ~ -d Ubuntu_WSL1

На этом этапе вы будете в экземпляре Ubuntu WSL1, но вы будете root, так как WSL не «запоминает» имя пользователя по умолчанию для --импортэкземпляры. Следуйте моему «Способу 1» из этого ответа чтобы установить имя пользователя по умолчанию.

На данный момент у вас есть два экземпляра WSL Ubuntu, один для WSL1 (Ubuntu_WSL1) и еще один для WSL2 (вероятно Убунту или, возможно, Убунту-20.04). Если вы используете Windows Terminal, он обнаружит их обоих и создаст профили для запуска. Или вы всегда можете запустить вручную, используя wsl ~ -d <имя дистрибутива>.

Другим вариантом было бы простое конвертировать на WSL1 и использовать его исключительно. Шаги для этого аналогичны его копированию, поскольку вы, вероятно, все еще хотите сделать резервную копию. Снова выйдите из экземпляра и из PowerShell:

# Отрегулируйте базовый путь по желанию
$WSL_ROOT = "$env:ПРОФИЛЬ ПОЛЬЗОВАТЕЛЯ\WSL"
$WSL_IMAGE_NAME = "$(get-date -UFormat `"%Y-%m-%d`") Ubuntu Backup.tar"
mkdir -p "$WSL_ROOT\изображения"
компакт-диск $WSL_ROOT
wsl -l -v
# Подтвердите название дистрибутива. Если это не «Ubuntu», при необходимости измените следующую строку
wsl --export Ubuntu "$WSL_ROOT\images\$WSL_IMAGE_NAME"
wsl --set-версия Ubuntu 1

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


WSL2

WSL2 становится намного сложнее. Хотя в комментариях есть ссылка на документ о том, как это сделать, я укажу вам на оригинальная проблема Github и комментарий которые действительно начали людей в этом направлении.

Есть две реальные проблемы, которые необходимо решить, чтобы это заработало в WSL2:

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

  • Эта переадресация усложняется тем фактом, что виртуальный сетевой адрес WSL2 меняется при каждой перезагрузке (или wsl --shutdown). Это означает (по крайней мере, с методом, задокументированным в комментариях и этой проблеме Github), что вам нужно повторить процесс:

    • Поиск IP-адреса WSL2
    • Удаление старых правил брандмауэра
    • Удаление старых правил переадресации
    • Создание новых правил брандмауэра
    • Создание новых правил переадресации

... при каждой перезагрузке. Какая боль, правда?!

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

Этот метод использует SSH для обеспечения переадресации портов. Поскольку это инициализируется с конца WSL2, у него есть несколько преимуществ:

  • Во-первых, это можно сделать как часть того же шага, когда вы запускаете свое приложение (веб-сервер). Вы не упоминаете архитектуру/язык приложения, но я предполагаю, что один из наиболее распространенных — Node. Если это так, вы, вероятно, даже можете включить его в свой запуск нпм сценарий. Почти наверняка есть метод, который будет работать для любой архитектуры.

  • Самое главное, ему не нужен IP-адрес WSL2. Это позволяет избежать необходимости выполнять 4 вышеуказанных шага при каждой перезагрузке.

Итак, поехали. Во-первых, есть «одноразовая» установка:

  • Включите сервер Windows OpenSSH. Вы можете следить за Microsoft инструкции, но я подытожу здесь. Начните с открытия приглашения PowerShell от имени администратора, затем:

    Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
    Set-Service -Name sshd -StartupType "Автоматически"
    

    Это должно автоматически создать правила переадресации SSH. Опять же, см. документ если у вас возникнут какие-либо проблемы.

  • Редактировать C:\ProgramData\ssh\sshd_config и убедитесь, что Порты шлюза да не комментируется. Я считаю, что он отключен по умолчанию.

  • Вернувшись в админку PowerShell, запустите:

    Старт-Сервис sshd
    
  • Вы не упомянули номер порта, под которым работает ваше веб-приложение, поэтому я выберу 8080 ради этих примеров. Отрегулируйте по мере необходимости. Все еще в административной оболочке PowerShell запустите:

    New-NetFirewallRule -DisplayName 8080 -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow -Profile Private
    

    Этот:

    • Разрешает входящий TCP-трафик
    • На порту 8080
    • С устройств в частной сети

    Если ваша сеть настроена Общественный, брось -Профиль частный

  • Выйдите из административной оболочки PowerShell

С этим покончено, все на месте. Чтобы начать пересылку на этом этапе, выполните в Ubuntu/WSL2 следующее:

ssh -f -N -R 8080:localhost:8080 "$(имя хоста).local"

Используйте свой Окна имя пользователя и пароль.

На этом этапе у вас должен быть доступ к вашему веб-приложению с другого компьютера (или телефона, или чего-то еще) в той же офисной сети.

Объяснение:

  • Соединяет от Убунту/WSL2
  • К сервер OpenSSH, который мы настроили
  • С использованием "$(имя хоста).local" который (должен) всегда находить правильное DNS-имя через mDNS (пояснение в этот ответ.
  • Он не выделяет терминал () и работает в фоновом режиме (-f) после запроса учетных данных для входа
  • Он сообщает удаленному хосту SSH (Windows) перенаправлять трафик, полученный на его порт 8080, на локальный (WSL2) порт 8080.
  • Потому что мы указали Порты шлюза да в конфигурации сервера это означает, что он расширит эту переадресацию на Другие хосты в сети, а также.
Рейтинг:0
флаг cn

В то время как отвечать предоставлено @NotTheDr01ds правильно и очень информативно, вот еще один обходной путь, который использует PowerShell на базе Bash в Ubuntu на WSL :)

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

Измените значения для wsl_port и win_port в соответствии с вашими потребностями. При желании изменить значение win_ip если вы хотите слушать на определенном сетевом интерфейсе, а не на всех доступных интерфейсах, в чем смысл 0.0.0.0.

wsl_win_proxy () {
    wsl_ip="$(ip route | grep -oP '^.*src \K[0-9\.]+')"
    wsl_port="8080"

    win_ip="0.0.0.0"
    вин_порт = "8080"

    rule_name="Входящий TCP ${win_port}"
    win_get_fw_rule_cmd="Get-NetFirewallRule | Где { \$_.DisplayName -eq '${rule_name}' }"
    win_new_fw_rule_cmd="New-NetFirewallRule -DisplayName '${rule_name}' -Входящее направление -Action Allow -Protocol TCP -LocalPort ${win_port}"

    если ! интерфейс netsh.exe portproxy показать все | grep -q -P "${win_ip}\s+${win_port}\s+${wsl_ip}\s+${wsl_port}"
    тогда
        powershell.exe Start-Process -Verb runAs -FilePath "netsh.exe" \
            -ArgumentList "интерфейс","portproxy","добавить","v4tov4",\
                    "listenport=$win_port","listenaddress=$win_ip",\
                    "connectport=$wsl_port","connectaddress=$wsl_ip"

        если [[$? -экв 0 ]]
        тогда
            echo "Прокси порта '${win_ip}:${win_port} > ${wsl_ip}:${wsl_port}' создан."
        еще
            echo "Прокси порта '${win_ip}:${win_port} > ${wsl_ip}:${wsl_port}' не удалось."
        фи

        если ! powershell.exe ${win_get_fw_rule_cmd} | grep -q "$ имя_правила"
        тогда
            echo "Откройте PowerShell от имени администратора и создайте следующее правило брандмауэра:"
            echo -e '\033[1;33m'"$win_new_fw_rule_cmd"'\033[0m'
        фи
    фи
}
wsl_win_proxy

Теперь, когда вы откроете WSL, функция создаст порт прокси автоматически. Используемая команда PowerShell должна выполняться с правами администратора, поэтому Windows запросит у вас подтверждение. Если порт прокси уже есть ничего не будет.

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

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


Следующие команды PowerShell помогут вам управлять созданным прокси порта.

netsh interface portproxy показать все
сброс прокси-сервера интерфейса netsh

Использованная литература:

Ответить или комментировать

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