Инструкция по установке лёгкого графического окружения XFCE и VNC-сервера на Ubuntu (aarch64), с безопасным доступом через SSH-туннель по приватному ключу — без открытия VNC-порта в интернет.
VNC-сервер слушает только localhost на сервере. Наружу открыт только SSH (порт 22), уже защищённый ключом. Клиент пробрасывает порт 5901 через SSH-туннель — VNC-трафик идёт внутри зашифрованного канала и снаружи вообще не виден.
sudo apt update && sudo apt upgrade -y
sudo apt install xfce4 xfce4-terminal -y --no-install-recommends
sudo apt install tigervnc-standalone-server tigervnc-common -y
Если рабочего пользователя ещё нет — создать его (не root):
sudo adduser ubuntu
sudo usermod -aG sudo ubuntu # если нужны права администратора
su - ubuntu
Если пользователь уже существует и есть sudo-права (sudo -l показывает (ALL : ALL) ALL) — этот шаг пропускается, работаем от него напрямую.
vncpasswd
mkdir -p ~/.vnc
touch ~/.Xresources
nano ~/.vnc/xstartup
Содержимое xstartup:
#!/bin/bash
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
xrdb $HOME/.Xresources 2>/dev/null
exec startxfce4
exec startxfce4 — важная деталь: без exec сессия может завершиться раньше, чем реально запустится ("cleanly exited too early").
chmod +x ~/.vnc/xstartup
Также стоит сразу поставить dbus-x11 — без него XFCE-сессия в VNC часто падает сразу после старта:
sudo apt install dbus-x11 -y
vncserver -localhost yes -geometry 1920x1080 -depth 24 :1
Проверка, что порт слушает только локально:
sudo ss -tlnp | grep 5901
Ожидается 127.0.0.1:5901, не 0.0.0.0:5901.
Остановить тестовую сессию перед настройкой автозапуска:
vncserver -kill :1
sudo nano /etc/systemd/system/vncserver@.service
[Unit]
Description=Start TigerVNC server at startup
After=syslog.target network.target
[Service]
Type=forking
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu
ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1
ExecStart=/usr/bin/vncserver -localhost yes -geometry 1920x1080 -depth 24 :%i
ExecStop=/usr/bin/vncserver -kill :%i
[Install]
WantedBy=multi-user.target
Строку PIDFile=... в юнит добавлять не нужно — с ней systemd иногда не успевает найти PID-файл вовремя (Can't open PID file... Operation not permitted) из-за имени хоста с двоеточием в пути. Без неё Type=forking всё равно корректно отслеживает запуск.
Активация:
sudo systemctl daemon-reload
sudo systemctl enable vncserver@1.service
sudo systemctl start vncserver@1.service
sudo systemctl status vncserver@1.service
Ожидаемый результат: Active: active (running), Loaded: ... enabled.
vncserver -kill или vncserver :1 вручную в терминале — это ломает связь между systemd и реальным процессом и приводит к статусу failed. Управление сессией — только через systemctl start|stop|restart vncserver@1.service.
VNC-порт (5901) наружу не открывается — доступ только через SSH-туннель.
sudo ufw allow OpenSSH
sudo ufw enable
В облачном провайдере (Oracle Cloud Security List/NSG и т.п.) — тоже открыт должен быть только порт 22.
Через терминал (Linux/macOS):
ssh -i /path/to/private_key -L 5901:localhost:5901 -N ubuntu@ПУБЛИЧНЫЙ_IP
Через Bitvise SSH Client (Windows): на вкладке C2S (Client-to-Server forwarding) добавить правило:
Затем в VNC-клиенте (TigerVNC Viewer, Remmina, RealVNC) подключиться к localhost:5901 и ввести VNC-пароль.
Подключаться так можно из любой точки мира — публичный IP сервера уже используется для самого SSH-соединения, а VNC-трафик идёт внутри зашифрованного туннеля.
DISPLAY=:1 и XAUTHORITY=~/.Xauthority.touch ~/.Xresources.startxfce4 & вместо exec startxfce4.Такая схема даёт полноценный удалённый рабочий стол XFCE на Ubuntu ARM64, при этом VNC-порт физически недоступен снаружи — единственная точка входа это SSH, защищённый приватным ключом.