У многих из нас есть родственники и друзья, которые не очень хорошо разбираются в компьютерах и периодически просят помочь настроить то или иное программное обеспечение. В таких случаях помогать можно подключившись к компьютеру пользователя через программу удаленного администрирования. Давайте рассмотрим вариант подключения к удаленным компьютерам без использования проприетарного ПО.
Для подключения к компьютерам других пользователей можно воспользоваться такими программами, как TeamViewer, AnyDesk, Ammyy и т.п. Но использование проприетарных решений всегда ставит нас в зависимость от вендора, и иногда это вызывает непредвиденные проблемы. Например, пользователи могут столкнуться с внезапным появлением сообщения «Обнаружено коммерческое использование», после которого программа прекращает нормально функционировать в бесплатном режиме. Для предприятия логичным шагом будет покупка лицензии, но если среди наших пользователей только родственники и друзья, то покупка лицензии представляется не всегда лучшим выбором. Существует программное обеспечение, распространяющееся под свободными лицензиями и позволяющее решить нашу задачу без дополнительных затрат. Исторически программы для удаленного администрирования предназначены для работы в локальной сети, и главным ограничением для их использования является отсутствие прямой связи с компьютером пользователя.
Для предлагаемого мной решения обязательным условием является наличие публичного IP-адреса, через который будет подниматься SSH-туннель. Варианты организации SSH-туннелей хорошо описаны в сети, например, можно почитать тут. Условно будем называть администратором человека, оказывающего помощь, а пользователем — человека, к компьютеру которого требуется подключиться. Рассматривать будем вариант, когда администратор имеет публичный IP-адрес. Для однократных подключений этот вариант выглядит наиболее удобным, потому что не требует постоянно включенного ПО ни на сервере, ни на клиенте.
Предположим, что администратор работает на компьютере PC1, а подключиться требуется к пользовательскому компьютеру PC2. Оба компьютера под управлением ОС Windows.

IP-адреса указаны для примера, и в скриптах их надо заменять на свои. В случае использования внешнего SSH-сервера (например, VPS/VDS, которые сейчас зачастую можно найти дешевле стоимости публичного IP у некоторых провайдеров) изменения потребуются в организации SSH-туннеля, что не должно представлять особой сложности и в статье не описывается.
Суть предлагаемой схемы работы:
-
На публичном IP открывается порт для входящих соединений и пробрасывается на администраторский компьютер PC1, на котором на этом порте запускается SSH-сервер.
-
На пользовательском компьютере PC2 запускается SSH-клиент, который подключается к SSH-серверу PC1 и пробрасывает на него локальный порт.
-
На PC2 запускается VNC-сервер, ожидающий соединения на локальном порте PC2.
-
На PC1 запускается VNC-клиент, который подключается к локальному порту PC1, проброшенному по SSH с PC2.
То есть компьютер PC1 будет выступать одновременно в роли SSH-сервера и VNC-клиента, а пользовательский компьютер PC2 — SSH-клиента и VNC-сервера.
Требования к функциональности:
-
Удаленный доступ должен работать только тогда, когда это ожидается администратором и пользователем.
-
Не должно быть возможности подключиться к сеансу третьему лицу или перехватить передаваемые данные (предполагаем, что используемое ПО не содержит уязвимостей, а используемые компьютеры не содержат вредоносного ПО).
-
Пользователь не должен испытывать существенных затруднений при развертывании ПО на своей стороне.
-
Дистрибутивы для разных пользователей должны быть независимы, механизм создания дистрибутива для нового пользователя должен быть максимально упрощен.
Для реализации будем использовать:
TightVNC я выбрал из-за наличия актуальной сборки VNC-сервера под Windows под лицензией GNU GPL, и возможности передавать файлы между сервером и клиентом. Из дистрибутивов потребуются файлы: libcrypto.dll, ssh.exe, ssh-keygen.exe, sshd.exe, tvnserver.exe и tvnviewer.exe. Решение проверялось на Windows 7 и Windows 10 (разных версий), но должно работать на любых ОС, где можно запустить SSH и VNC.
В Windows 10 SSH-клиент предустановлен (как минимум, начиная с версии 1809) по пути «%SystemRoot%\System32\OpenSSH\ssh.exe», но для универсальности SSH-клиент включен в архив.
Для каждого пользователя будет создаваться отдельный независимый дистрибутив. Все действия выполняются запуском bat-файлов.
Администраторская часть дистрибутива
Для начала рассмотрим состав файлов на стороне администратора PC1 (SSH-сервер и VNC-клиент):
-
authorized_keys — содержит открытый ключ SSH-клиента, необходим для подключения клиента к нашему серверу;
-
ssh_host_rsa_key — закрытый ключ SSH-сервера;
-
sshd_config — минимально необходимый конфиг SSH-сервера;
-
run_sshd.bat — скрипт запуска SSH-сервера;
-
ssh_host_rsa_key.pub — открытый ключ SSH-сервера (вообще говоря, для запуска сервера не нужен, используется на клиенте);
-
libcrypto.dll, sshd.exe и tvnviewer.exe — ранее распакованные бинарники.
Запуск сервера осуществляется запуском файла run_sshd.bat.
set ssh_bin=%~dp0 "%ssh_bin%sshd.exe" -f "%~dp0sshd_config" -h "%~dp0ssh_host_rsa_key" -E "%~dp0sshd.log"
Используемые параметры:
-
%~dp0— путь к каталогу запускаемого скрипта; -
-f config_file— путь к файлу конфигурации; -
-h host_key_file— путь к закрытому ключу сервера; -
-E log_file— путь к log-файлу (опционально).
Бинарники не обязательно держать в том же каталоге, можно разместить их в общем каталоге для всех клиентов и указать путь через переменную ssh_bin.
У используемого sshd версии 8.1.0.0p1-Beta есть особенности: для запуска обязательно надо указывать полный путь к sshd.exe, а authorized_keys должен находиться по пути «%USERPROFILE%.ssh\authorized_keys». То есть перед запуском сервера открытый ключ клиента обязательно должен быть добавлен в «%USERPROFILE%.ssh\authorized_keys». Либо при запуске sshd можно использовать опцию -o AuthorizedKeysFile=<...>.
Содержимое sshd_config:
PubkeyAuthentication yes PasswordAuthentication no SyslogFacility LOCAL0 Port 11111
Описание опций:
-
PubkeyAuthentication— разрешает аутентификацию на основе открытого ключа; -
PasswordAuthentication— запрещает аутентификацию с использованием пароля; -
SyslogFacility— категория журналирования для сохранения лога в файл; -
Port— номер порта, который слушает сервер.
Если в логах sshd.log возникает ошибка «WARNING: UNPROTECTED PRIVATE KEY FILE!», то надо поправить права на файле:
icacls.exe "ssh_host_rsa_key" /remove "%COMPUTERNAME%\%USERNAME%" icacls.exe "ssh_host_rsa_key" /inheritance:r icacls.exe "ssh_host_rsa_key" /grant "%COMPUTERNAME%\%USERNAME%:(R)"
В некоторых случаях (если sshd видит проблему с правами на файле с ключами) на SSH-клиенте возникает ошибка: «Permission denied (publickey,keyboard-interactive)». При этом в логах SSH-сервера при включенной отладке (опция -d) можно увидеть: «Bad permissions. Try removing permissions for user: …» В этом случае надо поправить права на файле authorized_keys, изменить их можно тем же способом, что и для файла ssh_host_rsa_key выше.
Пользовательская часть дистрибутива
На стороне пользователя PC2 (SSH-клиент и VNC-сервер) нам потребуются следующие файлы:
-
id_rsa — закрытый ключ клиента;
-
id_rsa.pub — открытый ключ клиента (для запуска на клиенте не требуется — используется на сервере);
-
known_hosts — содержит публичный IP-адрес SSH-сервера и его открытый ключ;
-
tightvnc.reg — настройки tightVNC-сервера;
-
prepare.bat — скрипт подготовки (запускается на клиенте однократно);
-
run.bat — скрипт запуска SSH-клиента и VNC-сервера;
-
libcrypto.dll, ssh.exe, tvnserver.exe — ранее распакованные бинарники.
Перед запуском на стороне пользователя необходимо произвести настройки, которые объединены в файле prepare.bat. Этот скрипт выполняется однократно при первичной настройке компьютера пользователя и делает следующее:
1. Настраивает права доступа к закрытому ключу (иначе SSH-клиент не запускается).
icacls.exe "%~dp0id_rsa" /remove "%COMPUTERNAME%\%USERNAME%" icacls.exe "%~dp0id_rsa" /inheritance:r icacls.exe "%~dp0id_rsa" /grant "%COMPUTERNAME%\%USERNAME%:(R)"
2. Настраивает VNC-сервер. Здесь возможны два варианта. Если прав локального администратора у пользователя нет, то настройки VNC надо импортировать в ветку HKEY_CURRENT_USER и запускать tvnserver.exe от имени пользователя.
reg.exe import tightvnc.reg
Но это ограничит возможности удаленного помощника: нельзя будет управлять приложениями, требующими повышения привилегий. Если пользователь готов дать удаленному помощнику права локального администратора, то настройки надо экспортировать в ветку HKEY_LOCAL_MACHINE и запускать tvnserver.exe как сервис. Для установки tvnserver как сервиса надо запустить (от имени администратора):
regedit /s "%~dp0tightvnc.reg" "%~dp0tvnserver.exe" -install sc config tvnserver start= demand
Последняя строка нужна для того, чтобы наш сервис запускался по требованию (только когда это нужно пользователю).
Запуск на стороне пользователя выполняется с помощью файла run.bat. Вариант без прав локального администратора:
start tvnserver.exe "%~dp0ssh.exe" -fN -n -R 55555:127.0.0.1:33333 username@1.2.3.4 -p 11111 -i "%~dp0id_rsa" -o "UserKnownHostsFile=""%~dp0known_hosts""" -E "%~dp0ssh.log" tvnserver.exe -controlapp -shutdown
Вариант с правами локального администратора:
"%~dp0tvnserver.exe" -start "%~dp0ssh.exe" -fN -n -R 55555:127.0.0.1:33333 username@1.2.3.4 -p 11111 -i "%~dp0id_rsa" -o "UserKnownHostsFile=""%~dp0known_hosts""" -E "%~dp0ssh.log" "%~dp0tvnserver.exe" -stop
В скрипте сначала запускается VNC-сервер, потом устанавливается соединение с SSH-сервером. Консольное окно c SSH-клиентом будет висеть до конца сеанса. По нему, кстати, можно диагностировать проблемы: если окно пропало, значит что-то пошло не так и надо смотреть в ssh.log. Расширенное журналирование можно включить опцией -vvvv.
Важно! Порядок запуска сервера и клиента имеет значение: запускать SSH-клиент имеет смысл только при работающем SSH-сервере.
Параметры запуска SSH-клиента:
-
-fN— фоновый режим; -
-n— предотвращает чтение из stdin (используется в фоновом режиме); -
-R— определяет реверсный туннель, перенаправляющий трафик с порта 55555 компьютера PC1 на порт 33333 компьютера PC2; -
username@ip— %USERNAME% пользователя, под которым запущен sshd на PC1, и публичный IP SSH-сервера; -
-p— публичный порт SSH-сервера (для простоты считаем, что порт прокидывается через NAT без изменения номера); -
-i— путь к закрытому ключу клиента; -
-o UserKnownHostsFile— путь к файлу с публичным ключом сервера; -
-E— путь к log-файлу.
Подготовка tightvnc.reg
Для подготовки конфига TightVNC надо запустить VNC-сервер (например, на виртуальной машине), настроить порт для соединений (в нашем случае 33333) и ограничить доступ к удаленному управлению. Остальные настройки на усмотрение администратора. Предлагаю доступ ограничить следующим образом: разрешить только Loopback Connections — установить флаги «Allow loopback connections» и «Allow only loopback connections». Еще можно настроить правила подключения.

После настроек надо выгрузить ветку из реестра: HKEY_LOCAL_MACHINE\Software\TightVNC\Server (или HKEY_CURRENT_USER\Software\TightVNC\Server, если VNC-сервер запускался без расширенных привилегий). Также для исключения ситуации, когда у пользователя были в реестре неподходящие настройки VNC-сервера, можно добавить в начало reg-файла строки [-HKEY_LOCAL_MACHINE\Software\TightVNC\Server] и/или [-HKEY_CURRENT_USER\Software\TightVNC\Server].
После запуска run_sshd.bat на сервере и run.bat на клиенте администратор может подключиться к компьютеру пользователя командой
tvnviewer.exe 127.0.0.1:55555
Генератор дистрибутива
Для упрощения создания дистрибутива для нового пользователя предлагается сделать простой генератор, который представляет собой обычный bat-файл. Текст максимально простой; единственное, на что можно обратить внимание, это формирование файла known_hosts. В нём перед отрытым ключом должен находиться IP-адрес SSH-сервера. Для этого IP-адрес записывается во временный файл (без перевода строки), а после объединения IP и ключа временный файл удаляется. IP-адрес и номера портов надо указывать свои, для примера использовались следующие:
-
1.2.3.4— публичный IP-адрес администратора; -
11111— открытый порт на публичном IP-адресе, который пробрасывается на открытый порт 11111 на PC1 (требуется корректно настроить firewall на всех узлах); -
33333— порт на PC2, на котором VNC-сервер ожидает соединение; -
55555— порт на PC1, к которому подключается VNC-клиент (на PC1).
В качестве имени пользователя
usernameнадо указать имя аккаунта администратора, под которым запускается SSH-сервер. Тестировались только варианты с именем латинскими буквами без пробелов. Как поведет себя система, если имя будет кириллицей или содержать пробелы, не проверялось. Также для читабельности убраны разные проверки на ошибки, потому что в bat это выглядит несколько монструозно. Для демонстрации рабочей концепции обработка ошибок не обязательна.
Основной скрипт генерации:
set ssh_srv_ip=1.2.3.4 set ssh_srv_user=%USERNAME% set ssh_srv_port=11111 set vnc_host_port=33333 set vnc_local_port=55555 mkdir ssh_cli-vnc_srv\ mkdir ssh_srv-vnc_cli\ @rem ключи пользователя ssh-keygen -t rsa -b 4096 -f ./id_rsa -C "" -q -N "" copy id_rsa.pub ssh_srv-vnc_cli\authorized_keys move id_rsa ssh_cli-vnc_srv\ move id_rsa.pub ssh_cli-vnc_srv\ echo @rem "%%~dp0tvnserver.exe" -start>ssh_cli-vnc_srv\run.bat echo start tvnserver.exe>>ssh_cli-vnc_srv\run.bat echo "%%~dp0ssh.exe" -fN -n -R %vnc_local_port%:127.0.0.1:%vnc_host_port% %ssh_srv_user%@%ssh_srv_ip% -p %ssh_srv_port% -i "%%~dp0id_rsa" -o "UserKnownHostsFile=""%%~dp0known_hosts""" -E "%%~dp0ssh.log">>ssh_cli-vnc_srv\run.bat echo tvnserver.exe -controlapp -shutdown>>ssh_cli-vnc_srv\run.bat echo @rem "%%~dp0tvnserver.exe" -stop>>ssh_cli-vnc_srv\run.bat @rem ключи администратора ssh-keygen -t rsa -b 4096 -f ./ssh_host_rsa_key -C "" -q -N "" <nul set /p dummy=%ssh_srv_ip% >tmp copy /b tmp+ssh_host_rsa_key.pub ssh_cli-vnc_srv\known_hosts del tmp move ssh_host_rsa_key ssh_srv-vnc_cli\ move ssh_host_rsa_key.pub ssh_srv-vnc_cli\
Генератор формирует ключи и bat-файлы, которые отличаются для каждого клиента, остальные файлы можно просто скопировать в нужные каталоги.
copy libcrypto.dll ssh_cli-vnc_srv\ copy ssh.exe ssh_cli-vnc_srv\ copy tvnserver.exe ssh_cli-vnc_srv\ copy tightvnc.reg ssh_cli-vnc_srv\ copy prepare.bat ssh_cli-vnc_srv\ copy run_sshd.bat ssh_srv-vnc_cli\ copy sshd_config ssh_srv-vnc_cli\ copy libcrypto.dll ssh_srv-vnc_cli\ copy sshd.exe ssh_srv-vnc_cli\ copy tvnviewer.exe ssh_srv-vnc_cli\
Резюме
В качестве итога перечислю всё, что нужно сделать.
Первичная настройка на стороне администратора:
-
Открыть порт для SSH-сервера, настроить firewall.
-
Сгенерировать дистрибутив, скорректировать bat при необходимости (например, для работы с повышенными привилегиями в системе пользователя).
-
Разместить authorized_keys по пути «%USERPROFILE%.ssh\authorized_keys» (добавить в файл строку с новым ключом). Ограничить права доступа к файлам с ключами.
-
Упаковать пользовательскую часть в архив и передать его пользователю любым доступным способом (например, временно запустив web-сервер на компьютере администратора).
Первичная настройка на стороне пользователя:
-
Пользователь должен получить архив со своей частью файлов. Если для распаковки используются встроенные средства Windows, то сначала надо убрать у скачанного файла поток Zone.Identifier (в свойствах файла нажать кнопку «разблокировать»).
-
После распаковки архива пользователю требуется запустить файл prepare.bat. В зависимости от того, что приготовил администратор, может потребоваться запуск с повышенными привилегиями.
Порядок установки соединения:
-
Администратор запускает run_sshd.bat на PC1 (SSH-сервер).
-
Пользователь запускает run.bat на PC2 (SSH-клиент и VNC-сервер, в зависимости от настроек может потребоваться подтверждение повышения привилегий).
-
Администратор запускает VNC-клиент: tvnviewer.exe 127.0.0.1:55555
Если всё настроено корректно, то теперь администратор может управлять компьютером пользователя.
ссылка на оригинал статьи https://habr.com/ru/company/domclick/blog/595149/
Добавить комментарий