Zdalna kontrola pulpitu w oparciu o darmowe i otwarte oprogramowanie
Opublikowane przez Tomasza Strojnego | gru 03, 2014
Wstęp
Na codzień staram się unikać korzystania z zamkniętego oprogramowania, jednak czasem jest ciężko. Do niedawna byłem zmuszony korzystać z Teamviewera. Jest to bardzo dobre narzędzie do pomocy zdalnej i do tego jest darmowe do niekomercyjnego użytku. Mimo wszystko, Teamviewer jest oprogramowaniem zamkniętym i ostatnio zastanawiałem się czy uda się znaleźć otwartą alternatywę.
Przeczesywałem Internet w poszukiwaniu podobnego narzędzia, ale nie znalazłem nic na takim poziomie funkcjonalnym. Chciałem narzędzie, w którym użytkownik będzie w stanie uruchomić serwer jednym kliknięciem, a asystent będzie w stanie podłączyć się do niego jednym kliknięciem. Wszystko to oczywiście powinno być zabezpieczone i dostępne niezależnie od miejsca przebywania użytkownika i asystenta (nawet za NATami).
Techniczne trzy słowa
Wszędzie dostawałem wyniki dotyczące VNC, a z tego co wiem większość programów nie wspiera szyfrowania transmisji. Do tego pozostawał problem NATów.
Po rekonesansie dotyczącym VNC dowiedziałem się, że istnieje możliwość połączeń odwrotnych w VNC. Innymi słowy jest możliwość uruchomienia serwera po stronie użytkownika i połączenia się do klienta po stronie asystenta. Po tym wpadlem na pomysł, żeby otworzyć jakiś niestandardowy port na swoim firewallu i przekierować na swój komputer. Jednak nie do końca mnie to satysfakcjonowało, bo korzystając z takiego rozwiązania mógłbym pomóc znajomym siedząc tylko w swoim mieszkaniu, a obraz i tak byłby przesyłany nieszyfrowaną transmisją. Co nie jest zbyt bezpieczne.
I w ten sposób natknąłem się na artykuł Michaela Franzla: http://michaelfranzl.com/2014/09/07/remote-desktop-via-ssh-teamviewer-alternative/
Gdzie opisuje on jak można rozwiązać mój problem korzystając z tunelowania SSH (opisanego pobieżnie przeze mnie w tym wpisie). Pisząc ten wpis będę się posiłkował wpisem Michaela (zwłaszcza grafikami, które uważam za intuicyjne).
Czego potrzebuję?
Po stronie użytkownika będziemy potrzebowali:
- serwera VNC (ja będę używał x11vnc)
- klienta SSH (u mnie OpenSSH)
Po stronie asystenta będzie potrzebny:
- klient VNC (tutaj będzie przeglądarka od TightVNC vncviewer)
- klient SSH (j.w.)
Niezależnie:
- Serwer SSH (najlepiej swój, o czym zaraz)
Zasada działania
Wychodząc od początku:
- asystent siedzi przy komputerze sittinghere
- uzytkownik siedzi przy komputerze overthere
- gdzieś niezależnie od nich znajduje się publicznie widoczny serwer SSH (na grafikach nazwany hopper) przez który będą "przeskakiwały" nasze dane.
Z założenia serwer nasłuchuje na porcie 22 (chociaż nie ma przeciwskazań żeby to był dowolny inny port). Będziemy się logować na dowolnego użytkownika który ma możliwość utworzenia socketa. Będziemy używali portów wysokich (~7000) żeby nie było problemów z uprawnieniami roota.
Sytuacja początkowa wygląda następująco:
Firewalle blokują dostęp z zewnątrz na maszyny sittinghere i overthere, a w serwerze hopper mamy otwarty port 22. sittinghere i overthere są za NATami, więc żeby otworzyć przejście trzeba zainicjować połączenie z wewnątrz sieci.
W tej sytuacji po stronie klienta musimy uruchomić serwer VNC. Przykładowym poleceniem jest:
x11vnc -nap -noxdamage -passwd 123456 -bg
Po tym poleceniu sytuacja wygląda następująco:
Serwer VNC nasłuchuje domyślnie na porcie 5900. Trzymamy się tego, że nie było problemów, chociaż prawda jest taka, że może to być na innym porcie. Jeżeli połączenie będzie miało dotyczyć innego ekranu, wtedy dostaniemy numer portu + numer ekranu. Innymi słowy, dla DISPLAY=0 dostaniemy port 5900, ale dla DISPLAY=1 dostaniemy port 5901.
Teraz z komputera użytkownika musimy się połączyć do naszego serwera SSH.
ssh -R 7001:localhost:5900 uzytkownik@hopper
Korzystając z tego polecenia prosimy sshd na serwerze, żeby po spięciu połączenia otworzył port 7001 i przekierował wszystko na to połączenie którego własnie używamy. Innymi słowy wszyscy którzy się połączą na tym serwerze na port 7001, wygląda to tak jakby szyfrowanym łączem połączyli się do komputera overthere na port 5900.
Na obecną chwilę sytuacja wygląda następująco:
To jest wszystko co robi użytkownik ze swojego komputera.
Po stronie asystenta (sittinghere) trzeba teraz spiąć podobny tunel. Można do tego celu użyć polecenia:
ssh -L 7002:localhost:7001 uzytkownik@hopper
To polecenie sprawia, że na komputerze asystenta jest spinane połączenie pomiędzy portem 7001 na hopperze i portem 7002 na localhoście, czyli sittinghere. Innymi słowy jak ktoś połączy się do tego portu na tym komputerze to tak jakby się połączył do portu 7001 na serwerze hopper. Czyli idąc dalej, tak jakby się połączył na port 5900 na overthere.
Po wykonaniu tego polecenia całość wygląda następująco:
Ostatnim krokiem jest uruchomienie przeglądarki vnc, która podłączy się do komputera lokalnego na port 7002.
Można do tego użyć polecenia:
vncviewer localhost:7002
W ten sposób dochodzimy do sytuacji końcowej:
W tym momencie powinniśmy zobaczyć ekran użytkownika przy komputerze asystenta.
Dodatkowe zabezpieczenie
Dlatego wcześniej polecałem posiadanie swojego serwera SSH, że po pierwsze na tym serwerze nasze dane będą rozszyfrowywane (i dopiero szyfrowane z powrotem), a po drugie będziemy w stanie ograniczyć dostęp użytkownikom, którzy się łączą do serwera SSH jak poniżej.
Do połączenia pomiędzy dwoma znajomymi nie będzie problemu. Często jednak zdarza się, że z serwerem SSH łączą się osoby, którym nie do końca możemy ufać i wypadałoby dodatkowo ograniczyć możliwości jakie są w stanie wykonać użytkownicy i asystenci na naszym serwerze.
Można do tego celu skorzystać z paczki SleepShell. Po skonfigurowaniu tego shella, użytkownik nie będzie w stanie zrobić nic, poza otwarciem portu do tunelu SSH.
Chroot Directory w serwerze SSH
Podchodząc do sprawy bardziej paranoicznie, możemy zabezpieczyć się w razie wydostania się użytkownika ze sleepshella. Do tego celu możemy skorzystać z funkcji konfiguracyjnej serwera SSH ChrootDirectory.
Podsumowanie
Cały proces da się oskryptować i przenieść na dowolną platformę wspierającą SSH oraz VNC. Myślę, że niedługo pojawi się jakieś repo na Githubie dotyczące takich skryptów.
Zgodnie z tym co pisał Michael połączenie jest lepsze niż w przypadku komercyjnych rozwiązań. Ja nie miałem jeszcze okazji przetestować tego w rzeczywistym świecie, ale w domowym laboratorium trzeba przyznać że efekt jest zadowalający.
Źródła
- http://michaelfranzl.com/2014/09/07/remote-desktop-via-ssh-teamviewer-alternative/
- http://www.techrepublic.com/blog/linux-and-open-source/chroot-users-with-openssh-an-easier-way-to-confine-users-to-their-home-directories/
- http://blog.bodhizazen.net/linux/how-to-restrict-access-with-rbash/
Edycje / notki:
Zgodnie z tym co napisał KaP, można było zaszkodzić serwerowi przez uruchomienie w nieskończonej pętli shella. Mogło się to skończyć skończeniem PIDów na serwerze. Zaproponował on użycie SleepShella, który idealnie pasuje do podanego problemu.
Mam zamiar jeszcze dodać szyfrowanie po kluczach tak żeby nie trzeba było podawać hasła do użytkownika remote za każdym razem. Jakieś propozycje?
Komentarze
Dodaj komentarz
Informacje o najnowszych wpisach publikuję na moim profilu na Facebook.