Jak doniosło osnews (i nie tylko) Google wypuściło swoją wersję serwera NX - neatx. Prezentacja Google (PDF) akcentuje ten sam model pracy, który opisywałem w artykule o wirtualnej sesji - utrzymywanie wirtualnych desktopów na serwerach i zdalny dostęp do nich, ponadto przymierzałem się kiedyś do instalacji FreeNX (zostało mi wrażenie trudnego do opanowania bałaganu), dlatego rzecz mnie zainteresowała.
NeatX faktycznie udało mi się zainstalować dość łatwo, opis poniżej.
Zanim jednak przejdę do szczegółów, pewne sprostowanie. Google nie
zaimplementowało całości serwera NX, podstawowym elementem -
wirtualnym serwerem X11 - pozostaje nxagent
firmy NoMachine,
udostępniany w ramach jej komponentów open-source.
Neatx to reimplementacja niezbędnej otoczki - uruchamiania
procesów, zarządzania sesjami itd. Nadal też używany jest ten sam
program kliencki (darmowy ale nie open-source).
Specyfika NX
W porównaniu do VNC, NX zapewnia wydajniejszy protokół (wierzę na słowo, benchmarków nie robiłem), automatyczne zabezpieczanie komunikacji przy pomocy sesji SSH (ale patrz niżej), brak konieczności uruchamiania demona czy serwisu, wreszcie większy wpływ klienta na charakterystyki sesji (choćby - rozmiar desktopu czy rodzaj sesji).
Wspominane SSH działa dosyć specyficznie: klient NX ma zaszyty w sobie
klucz prywatny SSH (ustalony, de facto trzeba go traktować jako
dobrze znany), który zostaje autoryzowany do dostępu do konta nx
tworzonego
na serwerze. Powyższemu kontu ustawiamy jako shell specjalny program
(nxserver-login-wrapper
), który obsługuje prawdziwe logowanie (wymaga
od programu klienckiego przesłania identyfikatora i hasła właściwego
użytkownika). Dlatego jest to połowiczne SSH - zabezpiecza
transmisję przed podsłuchem ale nie pozwala na autoryzowanie się
kluczami prywatnymi.
Wymaga to zaufania do oprogramowania serwera NX (podobnego do zaufania jakim darzymy - np. - GDM czy SSHD), ma też konsekwencje dla bezpieczeństwa (każdy kto ma dostęp SSH do maszyny może próbować się logować identyfikatorem i hasłem na dowolne konto).
Oczywiście tak czy siak jest bezpieczniej niż przy normalnym VNC (nie zabezpieczonym w żaden sposób).
Właściwa sesja (proces agenta) i inne procesy pomocnicze są w razie potrzeby uruchamiane w ramach obsługi powyższego logowania, stąd zarówno brak potrzeby konfigurowania demonów startujących z systemem, jak możliwość przekazywania przez klienta charakterystyk sesji.
Pobieranie kodu
Według tej strony należy zrobić:
$ svn checkout http://neatx.googlecode.com/svn/trunk/ neatx-read-only
Ja jak zwykle trochę inaczej:
$ hgimportsvn http://neatx.googlecode.com/svn/trunk/ neatx-vendor $ cd neatx-vendor $ hgpullsvn
co daje mercurialowe repozytorium z pełną historią projektu. Jego ewentualne odświeżanie:
$ cd /ścieżka/do/neatx-vendor $ hgpullsvn
Oczywiście nie jest to obowiązkowe, normalny checkout wystarczy.
Instalacja programów
hgimportsvn
ihgpullsvn
:$ sudo apt-get install hgsvn
Narzędzi tych należy używać z pewną ostrożnością, dla projektów o długiej historii początkowy import jest długotrwały i mocno obciąża serwer (pobiera wszystkie wersje po kolei). Neatx ma ich raptem paręnaście i proces jest szybki.
Przygotowanie do instalacji
Wymagane komponenty i biblioteki instaluje polecenie (kopiuję z pliku INSTALL
):
$ sudo apt-get install openssh-server \ python python-pexpect python-simplejson \ python-gtk2 python-gobject \ gcc autoconf automake \ python-docutils netcat
Do tego trzeba doinstalować NX Agenta. Dla Ubuntu - także zgodnie
z INSTALL
- wystarczy użycie dodatkowego repozytorium z tej strony. Czyli:
$ sudo vim /etc/apt/sources.list.d/nxagent.list
do którego skopiowałem z strony ppa:
deb http://ppa.launchpad.net/freenx-team/ppa/ubuntu jaunty main deb-src http://ppa.launchpad.net/freenx-team/ppa/ubuntu jaunty main
(intrepid, hardy czy gutsy podobnie). A potem:
$ sudo apt-get update $ sudo apt-get install nxagent
Instalacja
Kompilacja:
$ cd /ścieżka/do/neatx-vendor/neatx $ ./autogen.sh $ ./configure --prefix=/usr/local \ --sysconfdir=/etc \ --localstatedir=/var $ make $ sudo make install
Trwa to króciutko (kompilacja jednego pliku w C i generacja paru
plików pythonowych). Powyższe opcje configure
umieszczają
neatx
w /usr/local
(skrypty w /usr/local/lib/neatx
,
kod w /usr/local/lib/python2.6/dist-packages/neatx
,
szczątkowa dokumentacja w /usr/local/share/doc/neatx
, klucz
w /usr/local/share/neatx
) ale
zapewniają używanie /etc/neatx.conf
jako pliku konfiguracyjnego oraz /var/lib/neatx/sessions
do informacji
o bieżących sesjach.
Następnie trzeba założyć użytkownika nx
. Tu także odrobinę odejdę od
zaleceń z INSTALL
, używając (w debianowym stylu) jako katalogu
domowego /var/nx
:
$ sudo mkdir /var/nx $ sudo useradd --system \ -d /var/nx \ -s /usr/local/lib/neatx/nxserver-login-wrapper \ nx $ sudo chown nx.nx /var/nx
Potem jeszcze skopiowanie klucza SSH autoryzującego dostęp klienta NX do tego konta:
$ sudo mkdir ~nx/.ssh $ sudo cp /usr/local/share/neatx/authorized_keys.nomachine \ ~nx/.ssh/authorized_keys $ sudo chown nx.nx ~nx/.ssh/authorized_keys $ sudo chmod go-rwx ~nx/.ssh/authorized_keys
Uwaga: przypominam, że powyższy klucz jest dobrze znany, odpowiedni
klucz prywatny jest dystrybuowany w ramach klienta NX. Jest to pewne
ryzyko, w szczególności trzeba pilnować by konto nx
nie pozostało
z normalnym shellem.
Konfiguracja
Skopiowałem plik konfiguracyjny:
$ sudo cp /usr/local/share/doc/neatx/neatx.conf.example \ /etc/neatx.conf
i podedytowałem go następująco:
[global] loglevel = debug nx-protocol-version = 3.3.0 start-console-command = /usr/bin/xterm start-kde-command = /usr/bin/lxsession start-gnome-command = /usr/bin/gnome-session
Skąd to KDE i GNOME? Podsyła to klient NX, mający w dropdownie wyboru rodzaju sesji bezpośrednio te opcje (a także CDE, którego w przypadu neatx nie udało mi się na nic zmapować). Można pod te słowa podpiąć co innego, na przykład powyżej po wyborze KDE uruchamiam sesję LXDE (lekki desktop o którym już pisałem).
Instalacja klienta
Pobrałem klienta ze strony NoMachine
(jest pakiet .deb
a także .tar.gz
, używałem .deb
) i zainstalowałem go:
$ sudo dpkg -i nxclient_3.3.0-6_i386.deb
Testowałem lokalnie ale oczywiście klient może działać na innej maszynie niż serwer (w tym przecież sens usługi).
Uruchamianie klienta
Albo ręczne:
$ /usr/NX/bin/nxclient
albo Applications/Internet/NX Client for Linux/NX Client for Linux
(uwaga: jest to podfolder, więc pojawia się to na samym początu listy elementów folderu Internet - przez dłuższą chwilę miałem problem z zauważeniem).
Przy pierwszym uruchomieniu
pojawia się NX Connection Wizard
. Tam na razie podałem maszynę localhost
i typ połączenia LAN
.
Typem sesji jest Unix (inne typy pozwalają używać tego programu jako klienta innych protokołów - zwykłego VNC, RDP a nawet X11 z logowaniem XDCMP), jako rodzaj sesji wybrałem KDE (co wobec powyższej konfiguracji zakończy się sesją LXDE).
Po zapisaniu definicji połączenia można uruchamiać, pojawia się pytanie o identyfikator i hasło:
Przy czym chodzi tu o normalne dane konta używane do logowania na danej maszynie.
Przycisk Configure pozwala wrócić do parametrów połączenia
Tworzenie nowej sesji jest stosunkowo powolne, obrazki
i
można podziwiać dłuższą chwilę.
Problemy
Przy pierwszym podejściu ostatecznie obejrzałem informację:
Na szczęście neatx
dość przyzwoicie loguje. Wpisy
są kierowane do syslog-a, u mnie trafiały do
/var/log/user.log
. A tam:
Jul 14 17:57:40 platon nxnode[2986]: INFO daemon:486 Starting program, executable=None, args=['/usr/lib/nx/nxagent', '-D', '-name', u'Neatx - marcink@platon.mekk.waw.pl:296 - LocalTest', '-options', '/var/lib/neatx/sessions/C47213F83770D6F472337A7F1C68BD4C/options', '-nolisten', 'tcp', ':296'] Jul 14 17:57:40 platon nxnode-wrapper[2984]: Traceback (most recent call last): Jul 14 17:57:40 platon nxnode-wrapper[2984]: File "/usr/local/lib/python2.6/dist-packages/neatx/node.py", line 309, in __XAuthDone Jul 14 17:57:40 platon nxnode-wrapper[2984]: self.__StartNxAgent() Jul 14 17:57:40 platon nxnode-wrapper[2984]: File "/usr/local/lib/python2.6/dist-packages/neatx/node.py", line 340, in __StartNxAgent Jul 14 17:57:40 platon nxnode-wrapper[2984]: self.__nxagent.Start() Jul 14 17:57:40 platon nxnode-wrapper[2984]: File "/usr/local/lib/python2.6/dist-packages/neatx/agent.py", line 229, in Start Jul 14 17:57:40 platon nxnode-wrapper[2984]: pid = daemon.Program.Start(self) Jul 14 17:57:40 platon nxnode-wrapper[2984]: File "/usr/local/lib/python2.6/dist-packages/neatx/daemon.py", line 512, in Start Jul 14 17:57:40 platon nxnode-wrapper[2984]: **kwargs) Jul 14 17:57:40 platon nxnode-wrapper[2984]: glib.GError: Failed to execute child process "/usr/lib/nx/nxagent" (No such file or directory)
Faktycznie - program nxagent
u mnie to /usr/bin/nxagent
a nie /usr/lib/nx/nxagent
. Ta lokalizacja okazała się zhardcodowana
w neatx/lib/constants.py
, zatem:
$ sudo vim /usr/local/lib/python2.6/dist-packages/neatx/constants.py
gdzie zmieniłem definicję zmiennej NXAGENT
na:
NXAGENT = "/usr/bin/nxagent"
Tym razem pojawiło się:
za czym kryło się (również w /var/log/user.log
):
Jul 14 18:03:15 platon nxnode[4502]: DEBUG daemon:456 /usr/bin/nxagent stderr: Error: Call to bind failed for TCP port 4433. Error is 98 'Address already in use'.
To prawda, na porcie 4433 działała przypadkiem jakaś testowa aplikacja (pech - mój ulubiony port testowy).
Nie udało mi się nigdzie znaleźć ustawień portów - tylko w constants.py
jest wzmianka:
# Taken from nxcomp/Misc.cpp NX_PROXY_PORT_OFFSET = 4000
budząca podejrzenia że coś jest tu wkompilowane. Zdecydowałem się ustąpić i 4433 zwolnić dla neatx.
Sukces
Po powyższych korektach wszystko poprawnie się uruchomiło. Pozostał jeszcze problem opisywany poprzednio dla VNC i wynikający z testowania na desktopie - wirtualna sesja dobrała się do autostartu głównej sesji desktopowej uruchamiając np. drugą kopię komunikatora.
Rozwiązać to można tak samo jak uprzednio - redefiniując w środowisku sesji
XDG_CONFIG_HOME
. Najczystszym rozwiązaniem wydaje mi się napisanie
skryptów - np. - /etc/neatx/start-kde.sh
i /etc/neatx/start-gnome.sh
- i
podanie ich właśnie w /etc/neatx.conf
. W treści można umieścić to samo,
co poprzednio trafiało do ~/.vnc/startup
.
Zrzut ekranu działającej sesji pozwolę sobie tym razem pominąć, brak mi już pomysłów, co ciekawego w środku uruchomić.