КДПВ


Пользование виртуальными машинами на Linux в Hyper-V из коробки — несколько менее комфортное занятие, чем с гостевыми Windows-машинами. Причиной тому является то, что Hyper-V все же изначально не предназначался для десктопного пользования; нельзя просто взять, поставить пакет гостевых дополнений и получить работоспособное графическое ускорение, буфер обмена, общие директории и другие радости жизни, как это происходит в VirtualBox.


Hyper-V сам предоставляет несколько сервисов интеграции — так, гости могут пользоваться службой теневого копирования (VSS) хоста, гостям можно послать сигнал выключения, гости могут синхронизировать системное время с хостом виртуализации, с хоста возможен обмен файлами с виртуальной машиной (Copy-VMFile в PowerShell). Для некоторых гостевых операционных систем, в числе которых, конечно, находится и Windows, в приложении Virtual Machine Connection (vmconnect.exe) доступен Enhanced Session Mode, работающий по протоколу RDP и позволяющий пробрасывать в виртуальную машину дисковые устройства и принтеры, а также пользоваться общим буфером обмена.


Enhanced Session Mode из коробки работает в Windows в Hyper-V сразу после установки. С гостями на Linux нужно устанавливать RDP-сервер, поддерживающий vsock (специальное виртуальное сетевое адресное пространство в Linux, предназначенное для коммуникации с гипервизором). Если для Ubuntu в приложении VMCreate, идущим с Hyper-V на настольных редакциях Windows, есть специальный подготовленный шаблон виртуальной машины, в котором работающий с vsock RDP-сервер XRDP уже предустановлен, то с другими дистрибутивами все менее однозначно — так, у автора этого поста получилось включить ESM в Fedora. Здесь же мы активируем Enhanced Session Mode для виртуальной машины с Arch Linux.


Установка сервисов интеграции


Здесь все более или менее просто, нам достаточно установить пакет hyperv из репозитория community:


% sudo pacman -S hyperv

Включим сервисы VSS, обмена метаданными и файлами:


% for i in {vss,fcopy,kvp}; do sudo systemctl enable hv_${i}_daemon.service; done

Установка XRDP


Репозиторий linux-vm-tools на GitHub предоставляет скрипты, автоматизирующие процесс установки и настройки XRDP, для Arch Linux и Ubuntu. Установим Git, если он еще не установлен, вместе с компилятором и другим софтом для ручных сборок, после чего склонируем репозиторий:


% sudo pacman -S git base-devel
% git clone https://github.com/microsoft/linux-vm-tools.git
% cd linux-vm-tools/arch

На момент написания этой статьи самым свежим выпуском XRDP, который устанавливается скриптом makepkg.sh, предложенным в репозитории, является 0.9.11, в котором сломан парсинг vsock://-адресов, поэтому придется установить XRDP из Git и драйвер Xorg к нему из AUR вручную. Патч к XRDP, предлагаемый в AUR, также слегка устарел, поэтому придется отредактировать PKGBUILD и патч вручную.


Склонируем репозитории с PKGBUILD-ами из AUR (обычно эту процедуру вместе со сборкой автоматизируют программами вроде yay, но автор проделывал всю эту процедуру на чистой системе):


% git clone https://aur.archlinux.org/xrdp-devel-git.git
% git clone https://aur.archlinux.org/xorgxrdp-devel-git.git

Установим сначала сам XRDP. Откроем файл PKGBUILD любым текстовым редактором.


Отредактируем параметры сборки. PKGBUILD для сборки XRDP из Git не включает поддержку vsock при сборке, поэтому включим ее самостоятельно:


 build() {
   cd $pkgname
   ./configure --prefix=/usr                --sysconfdir=/etc                --localstatedir=/var                --sbindir=/usr/bin                --with-systemdsystemdunitdir=/usr/lib/systemd/system                --enable-jpeg                --enable-tjpeg                --enable-fuse                --enable-opus                --enable-rfxcodec                --enable-mp3lame -              --enable-pixman
+              --enable-pixman +              --enable-vsock
   make V=0
 }

В патче arch-config.diff, правящем юниты и скрипты запуска XRDP под пути к файлам, используемым в Arch Linux, содержится в том числе патч к скрипту instfiles/xrdp.sh, который на момент написания статьи был удален из поставки XRDP, поэтому патч придется отредактировать вручную:


  [Install]
  WantedBy=multi-user.target
-diff -up src/xrdp-devel-git/instfiles/xrdp.sh.orig src/xrdp-devel-git/instfiles/xrdp.sh
---- src/xrdp-devel-git/instfiles/xrdp.sh.orig  2017-08-30 00:27:28.000000000 -0600
-+++ src/xrdp-devel-git/instfiles/xrdp.sh   2017-08-30 00:28:00.000000000 -0600
-@@ -17,7 +17,7 @@
- # Description: starts xrdp
- ### END INIT INFO
- 
--SBINDIR=/usr/local/sbin
-+SBINDIR=/usr/bin
- LOG=/dev/null
- CFGDIR=/etc/xrdp
- 
 diff -up src/xrdp-devel-git/sesman/startwm.sh.orig src/xrdp-devel-git/sesman/startwm.sh
 --- src/xrdp-devel-git/sesman/startwm.sh.orig  2017-08-30 00:27:30.000000000 -0600

Соберем и установим пакет командой % makepkg --skipchecksums -si (ключ --skipchecksums нужен для отключения проверки контрольных сумм исходных файлов, поскольку мы редактировали их вручную).


Перейдем в директорию xorgxrdp-devel-git, после чего просто соберем пакет командой % makepkg -si.


Перейдем в директорию linux-vm-tools/arch и запустим скрипт install-config.sh, устанавливающий настройки XRDP, PolicyKit и PAM:


% sudo ./install-config.sh

Скрипт устанавливает устаревшую настройку use_vsock, которая игнорируется с версии 0.9.11, поэтому отредактируем файл конфигурации /etc/xrdp/xrdp.ini вручную:


 ;   port=vsock://<cid>:<port>
-port=3389
+port=vsock://-1:3389

 ; 'port' above should be connected to with vsock instead of tcp
 ; use this only with number alone in port above
 ; prefer use vsock://<cid>:<port> above
-use_vsock=true
+;use_vsock=true

 ; regulate if the listening socket use socket option tcp_nodelay

Добавим в файл ~/.xinitrc запуск своего предпочитаемого оконного менеджера / среды рабочего стола, который будет выполняться при запуске X-сервера:


% echo "exec i3" > ~/.xinitrc

Выключим виртуальную машину. Активируем транспорт vsock для виртуальной машины, выполнив следующую команду в PowerShell от администратора:


PS Admin > Set-VM -VMName НАЗВАНИЕ_МАШИНЫ -EnhancedSessionTransportType HvSocket

Включим виртуальную машину снова.


Подключение


Как только после запуска системы запустится сервис XRDP, приложение vmconnect это определит и в меню станет доступен пункт View -> Enhanced Session. При выборе этого пункта нам предложат установить разрешение экрана, а на вкладке Local Resources открывшегося диалога можно будет выбрать устройства, пробрасываемые внутрь RDP-сессии.


Диалог выбора разрешения экрана
Диалог выбора Local Resources


Подключимся. Увидим окно входа XRDP:


Окно входа XRDP


Введем свои имя пользователя и пароль.


Использование


Профит от этих манипуляций заметен: сессия RDP работает намного отзывчивее, чем при работе с виртуальным дисплеем без Enhanced Session. Проброшенные внутрь VM через RDP диски доступны в директории ${HOME}/shared-drives:


Проброшенное внутрь VM содержимое диска C


Буфер обмена работает нормально. Пробрасывать принтеры внутрь нельзя, это не только не поддерживается, но и ломает проброс дисков. Также не работает звук, но автору это и не требовалось. Для того, чтобы захватывались сочетания клавиш вроде Alt+Tab, нужно разворачивать vmconnect на весь экран.


Если по каким-либо причинам есть желание использовать вместо приложения vmconnect встроенный в Windows RDP-клиент или, например, подключаться к этой машине из другой машины, то нужно будет поменять в файле /etc/xrdp/xrdp.ini port на tcp://:3389. Если виртуальная машина подключена к Default Switch и получает сетевые настройки по DHCP, то подключиться к ней с хоста можно по адресу название_машины.mshome.net. Войти в TTY можно только из приложения vmconnect, выключив Enhanced Mode.


Использованные источники:


  1. Hyper-V — Arch Wiki
  2. Багрепорты на GitHub: 1, 2

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


  1. vsb
    29.12.2019 20:40

    А USB-криптотокены можно прокидывать через этот режим?


    PS ещё надо упомянуть, что гостевая машина Windows должна иметь редакцию не ниже Pro, на Home RDP не работает. Эти две проблемы стали для меня решающей, из-за которых я решил отказаться от Hyper-V и использовать VirtualBox. Туда и USB-устройство целиком прокинуть можно и никаких проблем с редакциями.


    1. tdemin Автор
      29.12.2019 21:02

      У меня нет криптотокена, проверить не могу. В списке устройств, предлагаемых к пробросу, есть смарт-карты, но насколько оно работоспособно под линуксом, не знаю.


    1. mmMike
      30.12.2019 05:49

      Присоединяюсь к вопросу. Общий буфер (copy|paste) и диски это легко решается и без RDP.
      А вот проброс USB гостевую машину… (любой raw USB)
      VirtualBox однозначно выигрывает тем что это делается "из коробки" и очень просто.


      Какие тогда плюсы у Huper-V перед VirtualBox остаются (если нужно не хостевую Windows) — даже не знаю.
      Может кто расскажет в чем лучше может быть Huper-V vs VirtualBox, если используется Linux в гостевой?


      1. dth_apostle
        30.12.2019 08:42
        +1

        Как минимум тем, что не требует пользовательской сессии. Задача пробрасывания USB-токена достаточно специфичная (нам бы 1 запустить) и "колхозная" (без обид, сам заморачивался по причине жмотства конторы на USB-over-IP). МС исходно заявляли, что в случае корпоративного использования проброс USB небезопасен и именно поэтому не реализован. Но почему-то именно эта специфичная и узкая задача избирается, как критерий критиками. Если это, и правда, единственный недостаток Hyper-V, то, ИМХО, это лучшая реклама.


        1. DaemonGloom
          30.12.2019 09:46

          Virtualbox тоже не требует сессию — можно настроить запуск виртуалок в headless режиме.


          1. dth_apostle
            30.12.2019 14:18

            Да, посмотрел — есть функция запуска из shell'а, то есть можно написать свой скрипт запуска ВМ со старта, но все «фишки», типа паузы машин при перезапуске гипервизора, восстановления состояния при неожиданном выключении, управления памятью гипервизора (как virtualbox будет «разруливать» память между 2-3-5мя ВМ.


        1. mmMike
          30.12.2019 10:18

          Колхозная или нет. Это зависит от конкретных задач. Если ПО (которое только по Linux) нужно запускать/писать/отлаживать, которое активно пользует USB периферию. А основной комп — Windows…
          А c opensource USB-IP-USB как то не очень (хоть самому писать.)


          Не всем же нужен вариант webсервис. сайт… и тп. в виртуалке. Хотя допускаю, что это 99% случаев


          1. dth_apostle
            30.12.2019 14:08

            хмм, ну да, ваш кейс (как мне кажется) не совсем типичный. более тго, ваша ситуация как раз требует пользовательской сессии, так что не необходимости в автозапуске ВМ.


        1. vsb
          30.12.2019 11:01

          Можете посоветовать USB-over-IP реализацию для домашнего применения (не слишком дорогую)?


          1. dth_apostle
            30.12.2019 14:06

            это был очень давний кейс. вот, например, расмотрение на хабре: habr.com/ru/post/100951


      1. DaemonGloom
        30.12.2019 09:44

        Тем, что если hyper-v уже зачем-то нужен (докер, виртуалки с виндой), то virtualbox вместе с ним не запустится нормально.


        1. mmMike
          30.12.2019 10:11

          Это то понятно. Что VirtualBox c Hyper-v одновременно не живет (даже останов и выключение Hyper-v как то не очень помогает).


          Я про сравнение использование в чистом виде.


          Мне VirtualBox показался как минимум удобнее для Linux server (не говоря уже Linux desktop). Но удобство вещь субъективная. А с точки зрения эксплуатации (надежность,… пр.) я четких сравнительных данных (не рекламных) на основе опыта эксплуатации не нашел.


  1. algot
    30.12.2019 17:30

    Пробовал играться с Майкрософтовскими образами Ubuntu через Quick Create и наткнулся на такую проблему:
    Ubuntu 18.04 нормально запускается в enhanced режиме через xrdp и все работает как надо.
    Образ Ubuntu 19.04 вроде как имеет установленный xrdp, но работает без enhanced режима и не просит выбрать разрешение, а конектится по стандарту.
    Как понять, почему xrdp не подхватывается на 19.04? Может в настройках что-то подкрутить?
    Я просто даже не знаю, с чего начать копать.