Доброго времени суток, дорогие пользователи хабра. Недавно столкнулся со следующей проблемой: при попытке подключения по ssh к серверу на Ubuntu на моем VirtualBox через WSL (я пользователь windows и тестировал работу Ansible, поэтому мне необходимо было подключаться из-под WSL) обнаружил, что WSL вообще не видит мою виртуалку. После некоторых поисков выяснилось, что необходимо произвести несколько махинаций и танцев с бубном, чтобы WSL мог увидеть мой сервер и подключиться к нему. Сегодня и хочу поделиться тем, как это сделать и предоставить пошаговую инструкцию по решению этой проблемы.

Общая схема

Для начала хочу объяснить, как все у нас будет работать и что мы должны сделать. У нас есть WSL (простыми словами, это оболочка Linux для пользователей Windows, чтобы можно было использовать Linux команды), есть наша хостовая машина (это и есть наша система Windows), и есть наш сервер Ubuntu на виртуальной машине. Напрямую подключиться мы не можем через WSL к виртуальной машине, он ее не увидит. Но зато мы можем сделать это через нашу хостовую машину (систему Windoows). Выглядеть это будет так

То есть, наша система Windows будет являться посредником между WSL и VirtualBox. Мы сделаем так, что при подключении к Windows мы автоматически подключимся к нашей виртуалке. Итого, что нам для этого нужно сделать:

  1. Настроить проброс портов.

  2. Скопировать публичный ssh ключ с WSL на виртуалку.

Проброс портов

Для начала поймем, зачем это нужно: Все просто:для того, чтобы мы имели к ней доступ с нашей хостовой машины. Если бы мы не пробрасывали порты, ты наша хостовая машина вообще не имела бы доступ к нашей виртуальной машине по ssh. Итак, вот что мы должны сделать: (я опущу в статье создание сервера на виртуальной машине, так как это не является темой данного поста).

  1. Заходим в настройки нашего сервера на виртуальной машине и выбираем пункт "Сеть":

  1. Далее выбираем дополнительно и нажимаем "Проброс портов":

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

    Проброс порта для нашей виртуальной машины
    Проброс порта для нашей виртуальной машины

    127.0.0.1 это так называемый localhost. То есть, что мы сделали: при обращении через ssh по порту 2222 и адресу 127.0.0.1 (команда будет выглядеть ssh username@127.0.0.1 -p 2222, где username - это имя пользователя в вашей виртуальной машине (важно, что мы сможем это сделать ТОЛЬКО через windows, через WSL это сделать не получится)) нас перебросит на порт 22 внутрь нашей виртуалки.

  2. Далее нам нужно пробросить порты от нашей WSL внутрь нашей виртуалки. Как нам узнать ip адрес WSL (если с localhost все просто, там 127.0.0.1, то у WSL придется адрес узнавать)? Тут тоже несложно: заходим в WSL и прописываем следующую команду:

    ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

    Он выдаст адрес нашего WSL:

    ip адрес нашего WSL
    ip адрес нашего WSL

    Далее прописываем новое правило проброса портов:

    Проброс портов от WSL.
    Проброс портов от WSL.

    Нам осталось совсем немного.

  3. Как я и говорил выше, мы будем подключаться от WSL не к нашей виртуалке напрямую (127.0.0.1), а к нашему компьютеру (системе Windows). Для этого нужно знать ip адрес на нашем компьютере. Заходим в терминал или командную строку и вводим команду ipconfig:

    Ip адрес нашего компьютера
    Ip адрес нашего компьютера

    Нам нужен именно IPv4 адрес. Если вы используется Ethernet кабель, то это будет в разделе Адаптер Ethernet, если через Wifi, то есть беспорводная сеть.

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

    Теперь все наши пробросы портов готовы и нам осталось скопировать публичный ssh ключ с WSL на виртуалку, чтобы мы могли подключиться по ssh.

Копирование публичного ssh ключа

Если вы еще не создавали ssh ключ на WSL, давайте это сделаем. Зайдем в WSL и напишем следующую команду:

ssh-keygen -t rsa -C "name@server_name"

В нашем случае name@example.org будет таким:

name - имя пользователя виртуальной машины;

server_name - название нашего сервера на виртуальной машине.

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

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

После того, как команда выполнится и ключ будет сгенерирован,мы можем увидеть, что создалать директория .ssh, в которой и будет лежать данный ключ. Воспользуемся командой ls -la и посмотрим на список всех директорий:

Вот как раз тут и есть наша директория.ssh. Зайдем в данную директорию при помощи команды cd .ssh.

Напишем здесь снова ls -la и увидим, что здесь есть несколько файлов:

Нам нужен файл id_rsa.pub. В нем и хранится наш публичный ключ. Вводим команду cat id_rsa.pub, чтобы консполь вывела нам содержимое файла и мы могли его скопировать:

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

ssh username@127.0.0.1 -p 2222, где username - имя пользователя на нашей виртуалке.

Затем нам надо вписать пароль (его мы задавали при установке системы Ubuntu). После того, как мы зайдем в систему, нам надо также, как и в WSL, зайди в папку .ssh (или, если ее нет, создать ее при помощи команды mkdir .ssh), создать и открыть файл Id_rsa.pub при помощи команды nano id_rsa.pub и вставить туда наш скопированный ключ. После того, как вставили ключ, нажимаем ctrl + O, чтобы сохранить изменения, нажимаем Enter и затем ctrl + X, чтобы выйти из редактора.

Вот и все, теперь мы можем подключиться через WSL к нашей виртуальной машине. Пишем
ssh username@ipaddress -p 2222, где ipaddress - адрес нашего компьютера, в моем случае это 192.168.100.9 и... Вуаля! Мы подключаемся к нашей виртуальной машине через WSL.

Заключение

Надеюсь, данная статья была для вас полезной. Я поделился своим опытом, чтобы другие, когда столкнутся с данной проблемой, могли ее решить без каких либо особых трудностей. Спасибо за внимание!

Комментарии (6)


  1. Aineko
    26.01.2023 11:50
    +3

    А почему бы не взять и добавить для виртуалки интерфейс, который смотрит в локальную сеть хоста?


    1. NikitaPozdeyev Автор
      26.01.2023 11:53

      Не пробовал делать данным способом. Можно попробовать. Думаю, способов может быть много, я поделился в данной статье лишь одним из способов


    1. Francyz
      26.01.2023 12:10
      +3

      Наверное, тогда бы туториал был бы в 1 строку и с одним скриншотом.


  1. nick-for-habr
    26.01.2023 12:41

    Ну так себе. Разве что для совсем начинающих пользователей пойдёт, кто ничего не знает про NAT и SSH.
    С другой стороны — зачем таким людям вообще подключаться к ВМ на Ubuntu?!
    Из статьи (скорее заметки) же мы видим, как вы сначала создали себе проблему, использовав NAT для подключения сетевого интерфейса ВМ (ошибка конфигурации ВМ: NAT тут не нужен), и уже в первой половине статьи её героически решили через «проброс портов» нажатием соответствующей кнопочки в GUI VirtualBox.
    Во второй части вы сжато скомкано пересказали один из мануалов по настройке ssh client&server, коих миллионы в сети.
    Ну и каким образом и зачем во всём этом оказалась замешана WSL — совершенно непонятно. Родная поддержка ssh есть в Windows уже довольно давно: просто запустите 'ssh' в том же PoSh или даже в CMD — и подключайтесь куда вам нужно. Ещё одна лишняя сущность в этом процессе, как и NAT.


    1. NikitaPozdeyev Автор
      26.01.2023 12:58

      WSL нужна была мне для тестирования Ansible, как я и описал в статье. Я изучаю DevOps и для тестирования работы Ansible (а он не работает на винде), нужен был WSL. Я неоднократно встречал людей, у которых была проблема подключения, когда нужно было подключиться именно из под WSL, поэтому и написал данную статью.


  1. nronnie
    26.01.2023 13:03

    К WSL все это вообще отношения не имеет. Если у вас виртуалка VirtualBox подключена к сети через NAT (что по умолчанию), то она "снаружи" без port mapping вообще никак не доступна: https://www.virtualbox.org/manual/ch06.html#networkingmodes. Если хочется без маппинга портов (который очень неудобен, если есть сразу несколько виртуалок) - подключайте её просто как "bridged" или как "host-only", только тогда еще придется или использовать динамический DNS (если виртуалки получают IP по DHCP), или статические адреса и etc/hosts. Кстати, еще так и не понял, зачем заходить на виртуалку по ssh именно из WSL - в винде уже сто лет свой собственный ssh и клиент и сервер.