Системное администрирование / Аналог Teamviewer из VNC, SSH и суперклея

в 18:12, , рубрики: teamviewer, vnc, метки: ,

Всем хорош teamviewer, вот только в коммерческих целях он какой-то не бесплатный, о чем не устает напоминать… Да и вообще, не хорошо нарушать лицензию.
Но удобство запуска quick support впечатляет — клиент запускает маленькую программку, диктует циферки по телефону и вуаля, мы видим его рабочий стол. Никаких VPN, никаких пробросов портов и прочей предварительной настройки. Удобно же?
В качестве бесплатного аналога вполне подходит VNC, с call-back подключением вполне приемлемо, да вот только когда клиентов много, и компьютер к которому цепляются тоже не один начинаются те же проблемы (хотя и более решаемые). Идея teamviewer лично мне нравится больше. А если нравится, почему бы не сделать свою реализацию…
Сразу оговорюсь, предлагаемое решение, еще даже и не решение совсем, реализация задумки была выполнена «на попробовать», но вполне доказала свою работоспособность, а улучшательства и удобства — можно допилить по ходу времени.
Итак, за основу возьмём winvnc (tightvnc), прикрутим к нему реверсивный SSH-туннель, а определять клиента будем, например по номеру порта. Нам потребуется:
OpenSSH сервер (на линуксе, например), web-сервер (с php в моем случае).
Клиент будет использовать собс-но winvnc (я взял из комплекта tightvnc-portable) и консольный клиент SSH plink из пакета Putty.
В альфа-версии нашего клиента удаленной поддержки не будет ничего лишнего (да и не лишнего тоже много чего не будет), и Т.З. для сервера будет выглядеть примерно так:На сервере должен быть бесправный пользователь некий, без права входа в систему, но с возможностью поднимать реверсивные туннели. Прямые туннели так же должны быть ограничены.

Сервер должен как-то должен сообщать клиенту данные о туннеле, адрес, свободный порт из некоего диапазона.

Для клиента:
При запуске клиент при запуске должен запросить с сервера данные о туннеле.
Запускать winvnc с заранее определенными настройками
Поднимать SSH-туннель с полученными настройками.
Приступим:
Не буду углубляться в вопросы запуска apache2+php+OpenSSH, предположим, что все это уже имеется.
Добавим пользователя vnc:
$ sudo useradd -M -s /bin/false vnc

Назначим пароль:
$ sudo passwd vnc

Пароль любой, он все равно будет лежать где-то в открытом виде.
В sshd_config (/etc/ssh/sshd_config) разрешим открывать порты на всех сетевых интерфейсах, добавив опцию:
GatewayPorts=yes

Без неё туннель откроется на адресе 127.0.0.1 (со стороны сервера) и без дополнительных шаманств его использовать удаленно не получится. Остается перезапустить OpenSSH$ sudo service ssh restart
Передавать настройки клиенту придумалось в виде cmd скрипта, который запустит plink и оповестит клиента о волшебной циферке которую нужно сообщить. Этим займется скрипт на PHP (или на чем будет удобно) вида:

И добавим разрешения для фаерволла:
#разрешение уже установленных соединений
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#запрещение всех остальных пользователю vnc
itpables -A OUTPUT -m owner --uid-owner `id -u vnc` -j REJECT
# разрешение соединений в диапазон 40000-50000
itpables -A INPUT -p tcp --dport 40000:50000 -j ACCEPT
Остальные настройки (политика по-умолчанию, разрешение SSH, HTTP -трафика, для при):
itpables -P INPUT DROP
itpables -A INPUT -p tcp —dport 22 -j ACCEPT
itpables -A INPUT -p tcp —dport 80 -j ACCEPT

Теперь приступим к сборке пакета для клиента. В него войдет:
winvnc (повторюсь, я взял из пакета tightVNC portable) и необходимые библиотеки
plink с сайта puttywget for windows (binaries и dependencies)
reg-файлы настроек для winvnc и настройки для plink. Последний очень хочет одобренный ключ SSH в реестре и нет никакой возможности не интерактивно добавить его.
Для получения заветных кусков реестра, запускаем Putty цепляемся к нашему SSH-серверу, принимаем ключ и экспортируем реестр:
reg export HKEY_CURRENT_USERSoftwareSimonTathamPuTTYSshHostKeys keys.reg

Точно также поступаем с настройками winvnc: запускаем на стендовом компьютере,
в настройках задаем:Пароль или пустой, по вкусу, на вкладке Server,

там же устанавливаем номер порта я поставил 11111 (используется в толькл PHP-скрипте).

На вкладке Administration разрешаем loopback соединения, в случае пустого пароля — разрешаем их использование.

Ну и выключаем HTTP сервер, он в нашем случае не используется.

Применяем, закрываем и экспортируем:
reg export HKEY_CURRENT_USERSoftwareORLWinVNC3 winvnc.reg

Добавим vb-скрипт, который будет выводить окно сообщения заданным текстом:
mb.vbs:
Set objArgs = WScript.Arguments
messageText = objArgs(0)
MsgBox messageText

И самый главный скрипт, который все свяжет:
runme.cmd:
winvnc.exe -kill
reg import host-key.reg
reg import winvnc.reg
start winvnc.exe -run
wget http://mysshserver.com/script.php -O tunnel.cmd && tunnel.cmd
winvnc.exe -kill

в нем пришибаем winvnc (вдруг уже работает?),
импортируем куски реестра,
запускаем winvnc
скачиваем скрипт и если скачался — запускаем его.
Остается сложить все вышеописанное в одну папку и запаковать в SFX архив, с запуском этого скрипта после распаковки: для WinRAR SFX как-то так:
Silent=1
Path=%TEMP%support
SavePath
Setup=%TEMP%supportrunme.cmd

и можно отдавать клиенту. При запуске, тихо и незаметно распакуется архив, запустится скрипт runme.cmd, который настроит winvnc, plink, скачает скрипт запуска туннеля, запустит его и оповестит клиента о номере порта.
Как и в случае с teamviewer — клиент сообщает его, и можно подключаться (уже к нашему SSH-серверу, с указанным номером порта)
В итоге имеем:Клиент может сидеть за NAT

VNC Viewer так же может быть за NAT

Единственное, что необходимо для подключения к клиенту — номер порта, который продиктует клиент.

Теперь о планах на будущее:Убрать тяжелый wget и вообще все скрипты переписать на VBS

Сделать web-интерфейс для отслеживания подключенных клиентов и возможность скачать VNC-файл для быстрого подключения.

Что еще?


  1. himera:

    спасибо

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js