Сервисы, с помощью которых можно организовать подключение сотрудников на удаленке, обычно работают через свои серверы. Почти всегда соединение получается медленнее прямых подключений, да и безопасность таких служб тоже под большим вопросом. Чаще всего архитектура этих решений построена вокруг реализации VNC (Virtual Network Computing). Система базируется на протоколе RFB (Remote FrameBuffer). Управление устроено так: с одного компьютера на другой передаются нажатия клавиш и движения мыши и содержимое экрана ретранслируется через сеть. Сам VNC не шифрует передаваемые данные. Если требуется обеспечить повышенную безопасность, сессия может быть установлена через SSL, SSH или VPN-туннели, что несколько усложняет задачу.
На публичных сервисах все соединения устанавливаются через сервер, который выдает ID клиентов, подключая их либо через VPN напрямую друг к другу, либо через собственный канал. Конечно, можно поднять свой VPN-сервер, настроить маршрутизацию VPN-сети и локальной сети предприятия и подключать сотрудников по прямым IP-адресам. В этом случае клиенту нужно, помимо логина, пароля и адреса подключения, передать еще клиент VPN и данные для авторизации. Для некоторых пользователей все это сложновато, а это, в свою очередь усложнит поддержку.
Пробросить порты на локальные ПК тоже не вариант. Это небезопасно, да и настраивать маршрутизацию замучаешься, когда клиентов становится больше двух. В Linux есть замечательный клиент Remmina, который позволяет пробрасывать сессии RDP/VNC через SSH-соединение без дополнительных клиентов. В Windows можно организовать SSH-туннели через клиентские приложения, которые необходимо настраивать на удаленных пользовательских машинах. SSH-клиент «из коробки» есть только в Windows 10, но как быть с юзерами семерки и восьмерки? Да и для Windows 10 придется писать батник, и не один. Все это не добавляет баллов стандартным решениям. Но всегда можно придумать нестандартное. Чем мы прямо сейчас и займемся.
Постановка задачи
Итак, задача у нас будет следующая. Подключать пользователя по RDP (как выяснилось, это намного привычнее для большинства из них). Самое главное преимущество RDP по сравнению с VNC — это скорость. RDP быстрее потому, что этот протокол перерисовывает на стороне клиента только измененную часть экрана, а значит, данных передается меньше. Подключение должно быть безопасным. Подключение должно выполняться с минимальными настройками и не требовать от пользователя никаких дополнительных действий.
А что скажет Google?
В общем‑то, задача не новая, и реализаций построения SSH-туннеля существует довольно много. В Google можно с ходу найти решения на базе PuTTY или варианты для Windows 10. Мы своих пользователей любим (и свои нервы тоже). А значит, надо дать им такой инструмент, который не нужно настраивать и который будет работать надежно.
Иными словами, решение должно отвечать следующим требованиям:
- простота для пользователя;
- легкость поддержки;
- простая и понятная подготовка и настройка «серверных частей».
Решение будет основано на технологии RDP over SSH. Технически мы организуем это так:
- клиент SSH для организации туннеля с пробросом порта до целевого ПК подключения;
- автоматический старт RDP-сессии без дополнительного ввода параметров подключения.
Система должна быть легко встраиваемой, и должен быть клиент для продвинутых пользователей (опционально).
Готовим серверную часть
Простые вещи вроде настройки RDP или SSH-сервера мы рассматривать не будем. Инструкций в интернете имеется тьма, а у нас объем ограничен, да и перегружать статью не хочется. Также я не стану подробно рассказывать, как реализовать получение данных с Kerio Control: на странице проекта можно найти готовый код.
Первым делом нам нужно разрешить RDP-подключения на клиентских машинах в локальной сети. Если там реализовано централизованное управление типа Active Directory, тебе повезло. Разрешаем подключение к RDP в групповых политиках. Если нет, обходим рабочие места ногами и разрешаем на целевых локальных машинах RDP. Не забываем и о файрволах.
Вторым шагом нам понадобится доступный из интернета SSH-сервер. Технически подойдет любое решение. Я использовал VPS с Debian 10 (один мой знакомый поднимал такой сервак даже на роутере, что небезопасно). Дальше стоит разделить решения на несколько версий, конкретная реализация зависит от того, как организовано получение данных для авторизации пользователей.
Первоначально у нас использовался Kerio с авторизацией пользователей через AD.
Клиент подключался по SSH, пробрасывал порт на API Kerio Control Server, затем подключался к нему, выполнял поиск по заданным параметрам (логин или фамилия сотрудника), искал IP локального ПК. Далее разрывал SSH-соединение и устанавливал новое уже с пробросом порта на найденный IP, на порт RDP (3389), после чего штатными средствами Windows поднималась сессия RDP с передачей параметров подключения.
Такое решение работало довольно быстро, но нам этого стало мало, и мы разделили его на две части. Серверный скрипт стал работать на SSH-сервере и сам время от времени ходить в Kerio за информацией. Клиентская часть подключалась к серверу по SFTP, искала нужные данные, оформленные в JSON, и выполняла подключение. В итоге скорость работы увеличилась.
Рекомендую сразу настроить сервер OpenSSH с доступом по ключам и подготовить RSA-ключи для авторизации. Для этого нужно создать отдельного пользователя и ограничить его в правах, затем отдать ему публичную часть ключа. Ниже приведу часть /
с настройками этих двух пользователей:
Match User sftp PubkeyAuthentication yes # PasswordAuthentication yes ChrootDirectory /srv/sftp ForceCommand internal-sftp AllowTcpForwarding noMatch User user1 X11Forwarding no ForceCommand /usr/bin/cmatrix # Подойдет и любая другая заглушка (можно заморочиться и отправлять пользователя в песочный bash) PasswordAuthentication yes
Первому пользователю SFTP разрешено подключаться только к этому самому SFTP. Второму — лишь для проброса портов. Если у тебя используется Kerio для получения данных о пользователях, Active Directory или еще что‑то централизованное, рекомендую завести отдельную учетку и ограничить ее в правах на всякий случай.
Реализация
Итак, мы приблизились к реализации намеченной цели. Писать будем все это дело на Python 3.8. Во‑первых, это мультиплатформенный язык, во‑вторых, собирается быстро и просто. В‑третьих, он легкий в освоении, в‑четвертых, включает огромное количество библиотек.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»