Удалённый рабочий стол на Ubuntu 24.04: xrdp и Xfce
Большую часть работы на Linux сервере удобнее делать через SSH. Графический рабочий стол ест оперативную память, за которую вы платите, расширяет поверхность атаки и подтормаживает на всём, что перерисовывается. И всё же иногда он оправдан. Ниже показано, как поднять Xfce на Ubuntu 24.04, работать с ним по RDP и не оставить окно входа открытым в интернет.
Сначала убедитесь, что он вам нужен
Рабочий стол на сервере оправдан, когда браузер должен работать изнутри сети, например веб-интерфейс железки в закрытом VLAN, или когда у графической утилиты нет консольного аналога. Более лёгкие варианты закрывают большую часть таких задач. Для браузера:
ssh -D 1080 alice@vps.example.com
Это SOCKS5 прокси на вашей машине: указываете Firefox на 127.0.0.1:1080, трафик уходит с сервера, а рисует локальный браузер. Для одной программы ssh -X требует xauth и X11Forwarding yes на сервере плюс X сервер на вашей стороне, XQuartz на macOS или VcXsrv на Windows; этого хватает на одно окно, но не на то, что постоянно движется. RDP уместен, когда нужна сессия, от которой можно отключиться и потом вернуться.
Сколько это стоит по памяти
Цифры приблизительные. Простаивающая сессия Xfce через xrdp с одним терминалом занимает от 400 до 500 МБ, если считать Xorg, саму сессию и вспомогательные процессы xrdp. Firefox с пятью вкладками добавляет от 800 МБ до 1,5 ГБ и за день только растёт. GNOME Shell без видеокарты запросил бы 1,2 ГБ на одну оболочку, поэтому здесь используется Xfce.
Итого 2 ГБ хватает на лёгкое администрирование, 4 ГБ реалистично, как только появляется браузер, и каждый следующий пользователь стоит примерно ещё одного браузера. Следите и за процессором: без видеокарты каждый пиксель рисует он. Наши тарифы VPS позволяют добавить память позже, поэтому начните скромно и померьте free -m под реальной нагрузкой. Если рабочий стол становится чьим-то ежедневным рабочим местом, ему больше подходит выделенный сервер.
Ставим Xfce, а не полноценный десктоп
sudo apt update
sudo apt install --no-install-recommends xfce4 xfce4-terminal dbus-x11 x11-xserver-utils
В 24.04 метапакет xfce4 рекомендует desktop-base, tango-icon-theme, thunar-volman, xfce4-notifyd и xorg. Пропустив их, вы остаётесь на этом шаге без X сервера, и это нормально, если сразу перейти к следующему шагу: xorgxrdp приходит вместе с xrdp и зависит от xserver-xorg-core. Пакет dbus-x11 даёт dbus-launch, к которому откатываются скрипты Xsession, если сессионная шина ещё не запущена.
Не ставьте здесь ни xubuntu-desktop, ни ubuntu-desktop, ни менеджер входа: физической консоли, где логиниться, нет, так что lightdm или gdm3 будут только держать память.
xrdp и сессия Xfce
sudo apt install xrdp
dpkg -l xorgxrdp
В Ubuntu 24.04 приезжает xrdp 0.9.24, и всё дальнейшее рассчитано на него. --no-install-recommends здесь не применяйте: без xorgxrdp, одного из рекомендованных пакетов, xrdp тихо откатывается на сессии Xvnc, которые выглядят и ведут себя иначе. Строка dpkg -l покажет, встал ли он.
Три вещи остаются на вас. Первое: демон должен читать TLS ключ, поэтому ему нужна группа ssl-cert:
id xrdp
sudo adduser xrdp ssl-cert
sudo systemctl restart xrdp
Без неё клиент подключается, договаривается и сразу отваливается, а в /var/log/xrdp.log видно, что не открывается /etc/ssl/private/ssl-cert-snakeoil.key.
Второе: вход под root. Серия 0.9 приносит AllowRootLogin=true в секции [Security] файла /etc/xrdp/sesman.ini, так что на любом образе с заданным паролем root вход по RDP для root открыт. Посмотрите строку и выключите её:
sudo grep -n AllowRootLogin /etc/xrdp/sesman.ini
sudo sed -i 's/^AllowRootLogin=true/AllowRootLogin=false/' /etc/xrdp/sesman.ini
sudo systemctl restart xrdp-sesman
Третье: сессии надо сказать, что запускать. Файл /etc/xrdp/startwm.sh заканчивается вызовом собственной функции wm_start, которая в Debian и Ubuntu подключает /etc/X11/Xsession, а Xsession выполняет ~/.xsession, если такой файл есть. Для каждого пользователя:
printf '#!/bin/sh\nexec /usr/bin/xfce4-session\n' > ~/.xsession
chmod +x ~/.xsession
chmod здесь для порядка, а не по необходимости: /etc/X11/Xsession.d/50x11-common_determine-startup запускает неисполняемый ~/.xsession через вашу login оболочку, а не пропускает его. Чтобы задать сессию всем сразу, замените строку wm_start в конце startwm.sh на exec startxfce4.
Окна polkit, которыми пугают старые статьи, про создание устройства с управлением цветом и про обновление репозиториев, требуют colord, PackageKit и агента аутентификации, а здесь нет ни одного из них. Если их подсунет унаследованный образ, учтите: файл .pkla на 24.04 не делает ничего, потому что polkit 124 больше не поддерживает этот слой, а правила теперь пишутся на JavaScript в /etc/polkit-1/rules.d/.
Не дайте рабочему столу усыпить сервер
Кнопки Ждущий режим и Спящий режим окно выхода Xfce берёт у systemd-logind, и один невнимательный клик убирает VPS из сети, пока кто-то с доступом к консоли её не разбудит. Замаскируйте цели, и logind сообщит, что они недоступны:
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
Не выставляйте 3389 в интернет
Порты RDP сканируют непрерывно, а xrdp проверяет настоящие системные учётные записи через PAM, так что при открытом 3389 до шелла остаётся один слабый пароль. Привяжите демон к loopback, в секции [Globals] файла /etc/xrdp/xrdp.ini:
port=tcp://127.0.0.1:3389
sudo systemctl restart xrdp
sudo ss -tlnp | grep 3389
Там должен остаться только 127.0.0.1. Теперь туннель:
ssh -N -L 13389:127.0.0.1:3389 alice@vps.example.com
RDP клиент направляйте на localhost:13389; в Windows 3389 часто уже занят.
Если туннель непрактичен, ограничьте порт на файрволе. Сначала верните xrdp на публичный адрес, потому что у демона, привязанного к loopback, нет сокета, который правило могло бы защищать: задайте port=3389 и перезапустите. Затем разрешите SSH до включения ufw, иначе политика запрета входящих по умолчанию отрежет вас от машины без консоли:
sudo ufw allow OpenSSH
sudo ufw allow from 203.0.113.10 to any port 3389 proto tcp
sudo ufw enable
sudo ufw status numbered
Смысл в этом есть только с действительно статическими адресами, ведь целый диапазон домашнего провайдера ничего не ограничивает. В любом случае переведите сам SSH на ключи и отключите парольную аутентификацию: теперь он и есть входная дверь.
Буфер обмена, звук и диски клиента
Текстовый буфер обмена работает в обе стороны без настройки, за него отвечает xrdp-chansrv, по одному процессу на сессию; если pgrep -a xrdp-chansrv ничего не возвращает, переподключитесь. Копирование из Linux программы, которая заполняет только выделение PRIMARY, то есть выделил, чтобы скопировать, и средняя кнопка, чтобы вставить, до Windows не доедет, там нужен настоящий ctrl+c.
Звук идёт через PipeWire, а pipewire-module-xrdp приходит с рекомендациями xrdp и потому уже установлен. Ему всё ещё нужна сессия PipeWire с pipewire-pulse от имени вашего пользователя, а на серверном образе её может не быть, поэтому, если нужен звук, добавьте pipewire pipewire-pulse wireplumber. Старого pulseaudio-module-xrdp, к которому отсылают другие статьи, в репозиториях Ubuntu нет.
Диски клиента пробрасываются по умолчанию, так как EnableFuseMount по умолчанию равен true, и появляются в ~/thinclient_drives, потому что у поставляемого FuseMountName нет ведущего слеша. Монтирование исчезает вместе с сессией, поэтому никогда не направляйте туда резервное копирование. Чтобы выключить, задайте EnableFuseMount=false в секции [Chansrv] файла /etc/xrdp/sesman.ini, где строка лежит под комментарием, и перезапустите xrdp-sesman.
Сессии и куда смотреть, когда сломалось
Отключённая сессия продолжает работать со всем, что в ней открыто, и три брошенные сессии, каждая с браузером, добьют небольшой VPS. В /etc/xrdp/sesman.ini, секция [Sessions]:
KillDisconnected=true
DisconnectedTimeLimit=7200
IdleTimeLimit=0
MaxSessions=10
Значения в секундах, DisconnectedTimeLimit игнорируется, пока KillDisconnected не выставлен в true, и именно на этом спотыкаются старые инструкции, всё меньше 60 поднимается до 60, и обе настройки работают только с сессиями xorgxrdp.
Когда что-то не работает, читайте в таком порядке:
sudo systemctl status xrdp xrdp-sesman
sudo tail -n 50 /var/log/xrdp.log
sudo tail -n 50 /var/log/xrdp-sesman.log
tail -n 50 ~/.xsession-errors
Синий экран xrdp и мгновенный обрыв после правильного пароля означают, что команда запуска сессии упала, и ~/.xsession-errors назовёт виновника: обычно ~/.xsession указывает на непоставленную программу или внутри самого файла происходит ошибка. Чёрный экран с живым курсором означает, что сессия стартовала, а оконный менеджер нет. Если окно входа не появляется совсем, вопрос к файрволу и привязке, то есть обратно к ss -tlnp. Обрыв сразу после рукопожатия TLS почти всегда указывает на группу ssl-cert.
Последнее: раскладка клавиатуры. xrdp берёт её у клиента, и если он угадал неверно, setxkbmap ru или setxkbmap lv внутри сессии чинит это для текущего входа. Постоянное решение живёт в /etc/xrdp/xrdp_keyboard.ini, который для сессий xorgxrdp сопоставляет идентификаторы раскладок RDP с раскладками XKB; файлы km-*.ini, на которые ссылаются старые статьи, относятся к пути Xvnc. Русская раскладка уже есть как rdp_layout_ru=0x00000419; для латышской добавьте rdp_layout_lv=0x00000426 в [default_rdp_layouts] и rdp_layout_lv=lv в [default_layouts_map], затем перезапустите.
Когда всё заработает, постарайтесь в этом не жить: каждый час простоя с открытым браузером тратит память впустую. Если вы предпочтёте, чтобы эту конфигурацию держал кто-то другой, наши инженеры обслуживают её в собственном дата центре в Риге и доступны круглосуточно через IT поддержку.
Читайте дальше
Готовы начать?
Запустите за минуты или обсудите с инженером, что подходит вашему проекту.