VNC najczęściej kojarzy się z zarządzaniem zdalną maszyną. To oczywiście użyteczne zastosowanie ale sensownych zastosowań jest więcej. W tym artykule o trwałej sesji na serwerze, czyli wykorzystywaniu zdalnego desktopu, z którym można się swobodnie rozłączyć i połączyć ponownie.
Zacznijmy od opisu o co chodzi, potem szczegóły konfiguracyjne.
Po co
Sesja na serwerze przydaje się, gdy mamy serwer deweloperski, czyli maszynę, na której są poinstalowane potrzebne frameworki, kompilatory, aplikacje, czy środowiska testowe i na którą logują się użytkownicy, by kompilować, uruchamiać, testować czy przeglądać logi. Najczęstszymi metodami pracy w takiej sytuacji są sesje terminalowe (niewygodnie) albo zdalne dostępy po X11 (natywne z Linuksa, spod Windows wsparte przez Cygwin/X, Xming, Reflection, eXceed...). Stały problem w obu tych wypadkach to duża wrażliwość takich sesji na chwilowe problemy sieciowe, wypięcie kabla czy reset rutera oznaczają konieczność konfigurowania aplikacji od początku. Podobnie kończy się rozładowanie baterii w notebooku, reboot desktopu itd itp.
VNC ładnie rozwiązuje te problemy, pozwalając przy okazji używać tej samej sesji (tj. tego samego pakietu otwartych okien i programów) z różnych maszyn i utrzymywać ją przy życiu przez okresy, gdy żaden podgląd w ogóle nie jest otwarty. Działa to tak:
- użytkownik dostaje swój wirtualny ekran na serwerze,
- z punktu widzenia uruchamianych programów, ekran ten działa jak normalny screen - ma ustaloną rozdzielczość, ilość kolorów itd i przydzielony proces obsługujący sesję, tyle że nie jest związany z żadnym fizycznym monitorem,
- użytkownik wyświetla ten swój ekran przy pomocy klienta VNC, mogąc to zrobić z dowolnego komputera, przy pierwszym podłączeniu zwykle widząc okno logowania GDM czy KDM, a potem zostawiając go w takim stanie, w jakim ma ochotę,
- czy jakiś klient VNC jest aktualnie podłączony, czy nie, desktop funkcjonuje (zegar idzie, programy działają), można np. rozłączyć się na noc, a rano znaleźć wszystko tak, jak było,
- dostęp do takiej sesji jest zabezpieczony hasłem.
Jeden serwer może obsługiwać wielu użytkowników (każdy ma swój ekran, fizycznie mapowany na dedykowany port TCP). Oczywiście trzeba zadbać o zasoby - przede wszystkim pamięć RAM (z tego względu uruchamiane są raczej lekkie desktopy typu XFCE, FVWM czy Fluxbox, a nie KDE lub Gnome).
Serwer nie zawsze musi być prawdziwym serwerem. Czasem używam konfiguracji, w której na moim głównym desktopie roboczym oprócz normalnej sesji wyświetlanej na monitorze w tle chodzi druga sesja, do której podłączam się z laptopa czy niestandardowej maszyny albo na której zostawiam liczące coś programy, które mają przetrwać wylogowanie.
Ważne ostrzeżenie
Protokół VNC nie jest bezpieczny . Poniższe rozwiązanie nadaje się do zabezpieczonej sieci domowej albo firmowej. Przy połączeniach przez internet należy użyć tunelu SSL, SSH albo VPN. W tym artykule tego nie opisuję (zresztą, komfort pracy przez VNC wymaga szybkiej sieci).
Instalacja niezbędnych programów
Instalujemy kluczowy program - Xvnc
albo Xtightvnc
. Do wyboru:
$ sudo apt-get install tightvncserver:
albo
$ sudo apt-get install vnc4server
Obecnie używam tego pierwszego ale w większości wypadków nie powinno być większej różnicy. Używany niżej skrypt
vncserver
jest symlinkiem albo dovnc4server
albo dotightvncserver
, czym zarządzamy przy pomocy mechanizmu alternatyw:$ sudo update-alternatives -config vncserver
Jeszcze jedna opcja to
xwnc
, którego nie testowałem.
Instalujemy też jakiś lekki desktop (np. XFCE albo FluxBox), albo i kilka by użytkownicy mieli wybór:
$ sudo apt-get install xfce4
$ sudo apt-get install fluxbox
$ sudo apt-get install fvwm
$ sudo apt-get install wmaker
Jeżeli będziemy testować lokalnie, instalujemy jakiś VNC viewer, np:
$ sudo apt-get install xvnc4viewer
albo
$ sudo apt-get install xtightvncviewer
Jeżeli chcemy powalczyć o prezentację wewnątrz sesji VNC graficznego okna logowania (sprawia to problemy, patrz niżej), instalujemy też xinetd
i jakiś login manager (gdm
, kdm
, xdm
):
$ sudo apt-get install xinetd gdm
Inne przygotowania systemowe
Każdemu użytkownikowi przydzielamy osobny numer desktopu (1, 2, 3, ...). Będzie on odpowiadał portowi TCP powyżej 5900 (desktop 1 to port 5901, desktop 2 to port 5902 itd).
Przydzielanie tych numerków nie jest absolutnie konieczne, używany niżej skrypt vncserver potrafi znaleźć pierwszy wolny - ale ustawienie stałych adresów jest wygodniejsze (można zrobić stałe linki po stronie klienta).
Jeśli wykorzystujemy firewall, robimy w nim odpowiednią dziurkę (albo tworzymy tunel), by użytkownik miał dostęp do swojego portu.
Przygotowania na koncie użytkownika
Poniższe operacje wykonujemy na koncie każdego użytkownika, który będzie miał uruchomioną sesję.
Definiujemy hasło zabezpieczające dostęp do sesji:
$ vncpasswd ~/.vnc/passwd
(i wpisujemy dwa razy hasło). O to hasło będzie pytał klient VNC próbując się podłączyć.
Tworzymy plik ~/.vnc/xstartup
definiujący rodzaj uruchamianej sesji, na przykład (XFCE):
#!/bin/sh
exec /usr/bin/xfce4-session
albo (fluxbox):
#!/bin/sh
exec /usr/bin/startfluxbox
Na Ubuntu i Debianie listę wszystkich zainstalowanych programów nadających się do zarządzania sesją X11 można dostać pisząc:
$ update-alternatives --list x-window-manager $ update-alternatives --list x-session-manager
(to pierwsze wymieni proste menedżery okien, to drugie Gnome/KDE/XFCE)
Można w tym skrypcie dodać także konkretne programy i wstępnie skonfigurować wygląd, na przykład:
#!/bin/sh
xterm -geometry 80x24+20+20 -ls &
xsetroot -solid black
/usr/bin/startfluxbox
i nawet jeśli fluxbox (czy cokolwiek wybraliśmy) z jakichś powodów nie wystartuje, będziemy mieli terminal (z którego możemy spróbować uruchomić go ręcznie i sprawdzić, co jest nie tak).
Zastanawiamy się też nad rozmiarem ekranu. Dla wygodnej pracy nie powinna być one większa, niż rozmiar ekranu na maszynie/maszynach klienckich. Komuś z laptopem 1024x768 przyda się bądź taki właśnie ekran - jeśli będzie pracować w trybie fullscreen, bądź mniejszy - gdy będzie trzymać sesję w oknie. Za duży ekran oznacza scrollbary.
Testowe uruchomienie
Uruchamiamy z palca (z konta użytkownika, który będzie korzystał z sesji):
$ vncserver :2 -geometry 1024x768
(zamiast :2 odpowiedni port, podobnie w razie potrzeby inna rozdzielczość).
Uwaga: gdy takie polecenie wydałem z terminala pod X11, XFCE nie chciało
startować (Another display manager is running
). Rozwiązaniem jest uruchomienie
z terminala tekstowego, uruchomienie via sudo (sudo -u marcin vncserver :2 -geometry 800x600
) albo inny mechanizm, który pozwoli nam zgubić ustawienia orginalnego środowiska.
Polecenie
vncserver
to pomocniczy skrypt, którego głównym zadaniem jest uruchomićXvnc
z odpowiednimi parametrami a następnie uruchomić odpowiednią sesję. Tovncserver
obsługuje konwencję pliku~/.vnc/xstartup
, domyślne położenie pliku z hasłem itd. Oczywiście można uzyskać samemu podobne efekty uruchamiającXvnc
, jest to bardziej pracochłonne.
Podłączamy się do tej sesji jakimś klientem VNC:
$ vncviewer localhost:2
Powinniśmy zobaczyć w oknie wydzielony desktop.
Jeszcze jedna uwaga dotycząca XFCE. Środowisko to próbuje uruchamiać usługi Gnome albo KDE, co - jeżeli wirtualna sesja jest startowana na maszynie, na której mamy też normalny desktop - bywa kłopotliwe (różne autostartowane programy wstają także tam). Można to wyłączyć (w ramach sesji XFCE czyli wewnątrz okna VNC prawy klik, Settings, Sessions and Startup i w zakładce Advanced czyścimy checkbox Launch Gnome services on startup).
Możemy spróbować zamknąć klienta, ponownie go otworzyć, nawet podłączyć się z innej maszyny. Wszystko powinno działać bez zmian.
Na koniec testów zatrzymujemy serwer:
$ vncserver -kill :2
Stałe uruchamianie
Powyższa technika w wielu wypadkach wystarczy (w szczególności, można zalogować się po ssh, odpalić vncserver
, a następnie wylogować się, serwer będzie działał aż zostanie zatrzymany albo do restartu maszyny).
Stosunkowo łatwo można też napisać skrypt dla /etc/init.d
, co pozwolę sobie z lenistwa pominąć. Skrypt vncserver
niestety nie ma opcji uniknięcia demonizowania, przez co trudno go uruchamiać pod runitem czy upstartem. W takich zastosowaniach trzeba go pominąć i uruchamiać bezpośrednio Xtightvnc
albo Xvnc4
. Na przykład, na potrzeby uruchamiania pod runitem napisałem sobie taki skrypt
#!/bin/sh
DISPLAY=:2
GEOMETRY=1024x768
HOME=/home/marcink
PROGRAM=/usr/bin/Xtightvnc
#PROGRAM=/usr/bin/Xvnc4
HOST=`uname -n`
AUTHCOOKIE=`mcookie`
xauth add "$HOST$DISPLAY" . "$AUTHCOOKIE"
xauth add "$HOST/unix$DISPLAY" . "$AUTHCOOKIE"
xinit $HOME/.vnc/xstartup -- $PROGRAM $DISPLAY \
-geometry $GEOMETRY -depth 24 \
-rfbwait 120000 -rfbauth $HOME/.vnc/passwd
po czym zapisałem go jako ~/service/run/mojevnc/run
(używam
mechanizmu pozwalającego użytkownikom definiować demony).
Jeszcze inną opcją jest skorzystanie z xinetd
(zaletą jest tu uruchamianie
takiej sesji dopiero, gdy ktoś próbuje się z nią połączyć). Na przykład,
tworzymy plik /etc/xinet.d/sesje_vnc
(nazwa dowolna) o treści podobnej do (oczywiście porty, nazwy użytkowników
czy rozdzielczości mogą być inne)
service vnc_marcin
{
protocol = tcp
type = UNLISTED
port = 5901
socket_type = stream
wait = yes
user = marcin
server = /usr/bin/Xvnc
# Poniższe to jeden wiersz
server_args = :1 -inetd -query localhost -once
-geometry 1000x720 -depth 16
passwordFile=/home/maciej/.vnc/passwd
}
W takiej konfiguracji, dzięki opcji -query
, serwer powinien wyświetlić graficzne
okno logowania GDM/KDM/XDM, pozwalając min. na wybranie tam sesji (zamiast
opisywanego wyżej wpisywania jej w ~/.vnc/xstartup
. By to mogło zadziałać,
trzeba w konfiguracji GDM czy KDM włączyć obsługę XDMCP (tak /etc/gdm/gdm.conf
jak /etc/kde3/kdmrc
mają sekcje o tej nazwie, trzeba je znaleźć i przestawić Enable
na true
). Otworzy to port 177, warto go odpowiednio odfiltrować jeśli mamy taką możliwość (musi być dostępny jedynie lokalnie).
Problem z tym rozwiązaniem: bardzo często sprawia kłopoty. W kolejnych wersjach Ubuntu XDMCP to nie działa, to działa, to działa kapryśnie, patrz choćby ten błąd.
Jeden czy wiele podglądów
Przy uruchamianiu jak powyżej, sesja nie jest dzielona, oglądać może ją tylko
jeden użytkownik, gdy otworzymy nowe połączenie, poprzednie zostanie zamknięte.
Można to zmienić dodając (czy to przy wywołaniu vncserver
, czy to Xvnc
) opcję
-alwaysshared
co pozwala na otwarcie wielu równoczesnych podglądów dla tej samej sesji.
Screenshot
Jeszcze obowiązkowy screenshot. Szare okno to podgląd wirtualnego desktopu (tu akurat działającego pod kontrolą ascetycznego fluxboxa). Okno to można w dowolnym momencie zamknąć, widocznej w nim sesji nic to nie zaszkodzi.