Для чего
Мне нужен headless LXC-контейнер с экономичным декстопным окружением, доступ к которому будет осуществляться по VNC, а лучше - по RDP.
Варианты решения
В качестве ОС контейнера выступает Ubuntu 16.04.
Для запуска иксов в headless-контейнере понадобится эмуляция видеоадаптера.
Для этих целей можно использовать либо xvfb (X Virtual Frame Buffer) либо xdummy. Оба пакета присутствуют в репозиториях большинства дистрибутивов, однако, более продвинутым является xdummy.
В данной заметке я рассмотрю настройку двух этих решений.
В качестве десктопного окружения я протестирую пару - Xfce и LXDE. Сразу скажу, что вариант с Xfce мне понравился гораздо больше.
Для доступа к графической оболочке я планирую использовать VNC или RDP (но можно использовать и другие протоколы). Например: SPICE - https://discuss.linuxcontainers.org/t/access-container-via-spice-sharing-clipboard/2544/3
Xfce + xdummy + xrdp
Установка необходимых компонент:
sudo apt-get -y install nano curl xserver-xorg-video-dummy xserver-xorg-core x11vnc xubuntu-desktop
Настройки X для работы с xdummy (файлик /etc/X11/xorg.conf):
# This xorg configuration file is meant to be used # to start a dummy X11 server. # For details, please see: # https://www.xpra.org/xorg.conf # Here we setup a Virtual Display of 1600x900 pixels Section "Device" Identifier "Configured Video Device" Driver "dummy" #VideoRam 4096000 #VideoRam 256000 VideoRam 16384 EndSection Section "Monitor" Identifier "Configured Monitor" HorizSync 5.0 - 1000.0 VertRefresh 5.0 - 200.0 Modeline "1600x900" 33.92 1600 1632 1760 1792 900 921 924 946 EndSection Section "Screen" Identifier "Default Screen" Monitor "Configured Monitor" Device "Configured Video Device" DefaultDepth 24 SubSection "Display" Viewport 0 0 Depth 24 Virtual 1600 900 EndSubSection EndSection
Список строчек для различных режимов:
Modeline "1920x1080" 23.53 1920 1952 2040 2072 1080 1106 1108 1135 Modeline "1680x1050" 20.08 1680 1712 1784 1816 1050 1075 1077 1103 Modeline "1600x1200" 22.04 1600 1632 1712 1744 1200 1229 1231 1261 Modeline "1600x900" 33.92 1600 1632 1760 1792 900 921 924 946 Modeline "1440x900" 30.66 1440 1472 1584 1616 900 921 924 946 ModeLine "1366x768" 72.00 1366 1414 1446 1494 768 771 777 803 Modeline "1280x1024" 31.50 1280 1312 1424 1456 1024 1048 1052 1076 Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841 Modeline "1280x768" 23.11 1280 1312 1392 1424 768 786 789 807 Modeline "1360x768" 24.49 1360 1392 1480 1512 768 786 789 807 Modeline "1024x768" 18.71 1024 1056 1120 1152 768 786 789 807
XRDP
Я буду использовать связку xrdp + xorgrdp. Раньше довольно популярным было использование x11rdp, однако его поддержки нужно пересобрать Xorg, а в случае с xorgrdp этого не требуется.
Xrdp можно установить из репозитория, однако он там довольно старый. Я предпочитаю собирать последнюю версию.
Ставим средства для сборки:
sudo apt-get install git autoconf libtool pkg-config gcc g++ make libssl-dev libpam0g-dev libjpeg-dev libx11-dev libxfixes-dev libxrandr-dev flex bison libxml2-dev intltool xsltproc xutils-dev python-libxml2 g++ xutils libfuse-dev libmp3lame-dev nasm libpixman-1-dev xserver-xorg-dev
Скачиваем и собираем:
mkdir ./xrdp cd xrdp/ wget https://github.com/neutrinolabs/xorgxrdp/releases/download/v0.2.1/xorgxrdp-0.2.1.tar.gz wget https://github.com/neutrinolabs/xrdp/releases/download/v0.9.2/xrdp-0.9.2.tar.gz tar -xvf ./xrdp-0.9.2.tar.gz cd ./xrdp-0.9.2 ./bootstrap ./configure --enable-fuse --enable-rfxcodec --enable-mp3lame --enable-pixman --disable-painter --disable-ipv6 make sudo make install sudo ln -s /usr/local/sbin/xrdp{,-sesman} /usr/sbin cd .. tar xvfz xorgxrdp-0.2.1.tar.gz cd xorgxrdp-0.2.1 ./bootstrap ./configure make sudo make install
Настройка XRDP
В принципе, достаточно просто включить сервис и уже можно подключаться.
sudo systemctl enable xrdp sudo service xrdp start
Однако, неплохо бы немного скорректировать список доступных при подключении опций - по умолчанию он избыточен.
Для этого открываем файлик /etc/xrdp/xrdp.ini и в нижней части в разделе Session types удаляем или комментируем все, кроме:
; ; Session types ; [Xorg] name=Xorg lib=libxup.so username=ask password=ask ip=127.0.0.1 port=-1 code=20
lightdm
/etc/lightdm/lightdm.conf
[Seat:*] xserver-allow-tcp=false xserver-command=X -nolisten tcp
Проблемы
После обновления контейнера Ubutnu 16.04 до 18.04 перестал работать xrdp.
После ввода логина и пароля он долго тупит, а потом выдает:
login successful for display 10 started connecting connection problem, giving up some problem
В логе /var/log/xrdp.log ошибки:
[DEBUG] Closed socket 19 (AF_UNIX)
В логе /var/log/xrdp-sesman.log ошибка:
[ERROR] X server for display 10 startup timeout
В директории пользователя, который логинится в файле ~/.xorgxrdp.XX.log такое:
[ 4034.806] (II) LoadModule: "xorgxrdp" [ 4034.807] (II) Loading /usr/lib/xorg/modules/libxorgxrdp.so [ 4034.807] (II) Module XORGXRDP: vendor="X.Org Foundation" [ 4034.807] compiled for 1.18.4, module version = 1.0.0 [ 4034.807] ABI class: X.Org Video Driver, version 20.0 [ 4034.807] (EE) xorgxrdp: module ABI major version (20) doesn't match the server's version (23) [ 4034.807] (II) UnloadModule: "xorgxrdp" [ 4034.807] (II) Unloading xorgxrdp [ 4034.807] (EE) Failed to load module "xorgxrdp" (module requirement mismatch, 0)
Причина - несоответствие ABI собранного вручную модуля xorgxrdp и текущего Xorg.
Решение - пересобрать xorgxrdp с текущими библиотеками xserver-xorg-dev и переустановить его.
LXDE + Xvfb + x11vnc
В качестве ОС контейнера выступает Ubuntu 16.04, а в качестве DE - пакет lubuntu-desktop.
sudo apt-get update && sudo apt-get -y upgrade
sudo apt-get -y install nano curl xvfb xserver-xorg-core x11vnc lubuntu-desktop
Дальше план такой - в скрипт /etc/X11/xinit/xserverrc прописываем запуск Xvfb - в результате у нас будет дисплей :0 и прописываем в конфигурацию lightdm запуск этого скрипта (вместо дефолтной команды X). В результате при старте lightdm у нас запустится Xvfb. Потом создадим сервис x11vnc и настроим его автозапуск.
Поехали.
Настраиваем lightdm, чтобы он запускал при старте иксов /etc/X11/xinit/xserverrc, а не дефолтную команду xserver-command=X . Для этого в файлик /etc/lightdm/lightdm.conf пишем вот что:
[SeatDefaults] greeter-session=lightdm-gtk-greeter user-session=Xubuntu xserver-command=/etc/X11/xinit/xserverrc
Cкорректируем /etc/X11/xinit/xserverrc, чтобы запускался Xvfb
#!/bin/sh #exec /usr/bin/X -nolisten tcp "$@" exec Xvfb :0 -screen 0 1024x768x24
Теперь нужно организовать автоматический запуск x11vnc. Это можно сделать двумя путями. Либо прописать строку запуска в /etc/rc.local, либо создать сервис в systemd. Создадим сервис. В файлик /lib/systemd/system/x11vnc.service напишем такое:
[Unit] Description=Remote control service x11vnc After=graphical.target [Service] Restart=always RestartSec=5 Type=simple ExecStart=-/usr/bin/x11vnc -display :0 -auth "/var/run/lightdm/root/:0" -rfbauth /etc/x11vnc.pass -o /var/log/x11vnc.log User=x11vnc Group=x11vnc [Install] WantedBy=graphical.target
Создадим пользователя для запуска этого сервиса, создадим файлик с логами и дадим на него права:
sudo useradd x11vnc --system sudo touch /var/log/x11vnc.log sudo chown -R x11vnc /var/log/x11vnc.log
Включаем и запускаем сервис:
sudo systemctl enable x11vnc.service sudo systemctl start x11vnc.service
Проверяем статус сервиса:
sudo systemctl status x11vnc.service
И, наконец, задаем пароль для VNC:
sudo x11vnc -storepasswd yourVNCpasswordHERE /etc/x11vnc.pass sudo chown x11vnc /etc/x11vnc.pass
Discussion