Решение для удаленного управления и удаленного написания сценариев, созданное на основе .NET, Blazor и SignalR Core.
Я ищу сопровождающих, которые помогут мне! Если вы разработчик .NET и заинтересованы в том, чтобы помочь удаленному продвижению вперед, пришлите мне личное сообщение в Discord по адресу jaredatimmy
.
Субреддит: https://www.reddit.com/r/remotely_app/
Докер: https://hub.docker.com/r/immybot/remotely
Учебное пособие: https://www.youtube.com/watch?v=t-TFvr7sZ6M (спасибо, @bmcgonag!)
mkdir -p /var/www/remotely wget -q https://raw.githubusercontent.com/immense/Remotely/master/docker-compose/docker-compose.yml docker-compose up -d
Единственный поддерживаемый обратный прокси-сервер — Caddy, и только тогда, когда он напрямую подключен к Интернету. Конфигурация по умолчанию для Caddy предоставляет все, что необходимо ASP.NET Core и SignalR для правильной работы.
Если у вас возникли проблемы с сетью при любой другой настройке, например, при использовании дополнительного брандмауэра или Nginx, обратитесь за поддержкой сообщества на вкладке «Обсуждения», на Reddit или другом социальном сайте. Специалисты по сопровождению Remotely просто не могут предоставить рекомендации и поддержку для всех возможных настроек среды.
С учетом вышесказанного ASP.NET Core требует установки следующих заголовков за обратным прокси-сервером: X-Forwarded-Proto
, X-Forwarded-Host
и X-Forwarded-For
. Они соответствуют схеме (http/https), URL-адресу исходного запроса и IP-адресу клиента соответственно. Полученная схема и хост внедряются в установщики и настольные клиенты, чтобы они знали, куда отправлять запросы. IP-адрес клиента используется в информации об устройстве.
Код Remotely не анализирует и не обрабатывает эти значения. Это делается внутри встроенного промежуточного программного обеспечения ASP.NET Core. Если значения не отображаются так, как ожидалось, это связано с тем, что заголовки отсутствовали, не содержали правильных значений, были не в правильном формате или не прошли через цепочку известных прокси (см. ниже).
Чтобы избежать атак путем внедрения, ASP.NET Core по умолчанию принимает только перенаправленные заголовки с адресов обратной связи. Удаленно также будет добавлен IP-адрес шлюза Docker (172.28.0.1), определенный в файле docker-compose. Если вы используете конфигурацию, отличную от конфигурации по умолчанию, необходимо добавить все адреса брандмауэра и обратного прокси-сервера в массив KnownProxies
в конфигурации сервера.
Если вам не удается правильно настроить обратные прокси-серверы, вы можете, по крайней мере, принудительно использовать схему HTTPS, установив Force Client HTTPS
на странице конфигурации сервера.
Полную документацию Microsoft по этой теме можно найти здесь: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer.
Данные для удаленного доступа будут сохранены в контейнере /app/AppData
, который будет смонтирован в /var/www/remotely/
на вашем хосте Docker.
Эта папка будет содержать файл Remotely.db и журналы, созданные сервером.
Эти файлы сохранятся после удаления и установки новых удаленных контейнеров.
При обновлении версии Remotely, отличной от Docker, перезапишите файл БД из предыдущей установки.
Используйте Caddy в качестве обратного прокси-сервера, если вы хотите открыть сайт для доступа в Интернет.
Если это первый запуск, создайте свою учетную запись, нажав кнопку Register
на главной странице.
Организации используются для группировки пользователей, устройств и других элементов данных в единый пул.
По умолчанию на сервере может существовать только одна организация.
Кнопка Register
исчезнет.
Люди больше не смогут создавать учетные записи самостоятельно.
Чтобы разрешить самостоятельную регистрацию, увеличьте значение MaxOrganizationCount
или установите для него значение -1 (см. раздел «Конфигурация»).
Эта учетная запись будет одновременно администратором сервера и администратором организации.
Для учетной записи автоматически создается организация.
Вы можете включить ведение журнала HTTP, чтобы видеть все запросы и ответы в журналах сервера, включая заголовки. Это может быть полезно для отладки проблем с обратным прокси-сервером, API или SignalR. Эту опцию можно включить на странице конфигурации сервера.
После изменения вышеперечисленного необходимо перезапустить контейнер, чтобы изменения вступили в силу.
Следующие шаги позволят настроить ваш компьютер с Windows 11 для создания удаленного сервера и клиентов.
Установите Visual Studio 2022.
.NET SDK (последняя версия).
MSBuild (который автоматически выбирает компиляторы Roslyn).
Цели NuGet и задачи сборки.
Пакет SDK для .NET Framework 4.8.
Для отладки и разработки вам потребуются все соответствующие рабочие нагрузки.
ASP.NET и веб-разработка
Разработка настольных компьютеров .NET
Кроссплатформенная разработка .NET Core
Ссылка: https://visualstudio.microsoft.com/downloads/
У вас должны быть выбраны следующие рабочие нагрузки:
У вас должны быть выбраны следующие отдельные компоненты:
Установите Git для Windows.
Ссылка: https://git-scm.com/downloads
Установите последнюю версию узла LTS:
Ссылка: https://nodejs.org/
Клонируйте репозиторий git: git clone https://github.com/immense/Remotely --recurse
При отладке агент будет использовать заранее определенный идентификатор устройства и подключаться к https://localhost:5001.
В среде разработки сервер назначит всех подключающихся агентов первой организации.
Два приведенных выше варианта позволяют вам одновременно отлаживать агент и сервер и видеть свое устройство в списке.
Первая созданная учетная запись будет администратором как сервера, так и организации, созданной для этой учетной записи.
Администратор организации имеет доступ к странице организации и записям журнала сервера, специфичным для его организации. Администратор сервера имеет доступ к странице конфигурации сервера и может видеть записи журнала сервера, которые не принадлежат организации.
В разделе «Учетная запись» есть вкладка для фирменного оформления, которая будет применяться к клиентам быстрой поддержки и установщику Windows.
Однако клиенты должны быть созданы из исходного кода с жестко закодированным в приложениях URL-адресом сервера, чтобы они могли получить информацию о брендинге.
Поставщик базы данных, строки подключения и порт ASP.NET Core настраиваются с помощью переменных среды в docker-compose.yml
.
Вся остальная конфигурация выполняется на странице конфигурации сервера после входа в систему.
AllowApiLogin: разрешить ли вход в систему через контроллер API. Для этого подхода рекомендуется использовать токены доступа к API.
BannedDevices: массив идентификаторов, имен или IP-адресов устройств, подлежащих запрету. Когда они попытаются подключиться, команда удаления будет немедленно отправлена обратно.
DataRetentionInDays: как долго журналы и другие данные будут храниться на сервере. Установите значение -1, чтобы сохранять на неопределенный срок (не рекомендуется).
DBProvider: определяет, какая из трех строк подключения (вверху) будет использоваться. Соответствующий поставщик БД для типа базы данных автоматически загружается в код.
EnableWindowsEventLog: следует ли также добавлять записи журнала сервера в журнал событий Windows.
EnforceAttendedAccess: клиентам будет предложено разрешить попытки автоматического удаленного управления.
EnableRemoteControlRecording: сохранять ли записи сеансов удаленного управления на сервере.
Они будут сохранены в /app/AppData/recordings
.
Их хранение регулируется DataRetentionInDays
.
ForceClientHTTPS: заставляет установщики и клиенты настольных компьютеров использовать схему HTTPS, даже если пересылаемые заголовки настроены неправильно.
KnownProxies: Если ваш обратный прокси-сервер находится на другом компьютере и перенаправляет запросы на удаленный сервер, вам необходимо добавить IP-адрес обратного прокси-сервера в этот массив.
MaxOrganizationCount: по умолчанию на сервере может существовать одна организация, которая создается автоматически при регистрации первой учетной записи. После этого саморегистрация будет отключена.
Установите для этого параметра значение -1 или увеличьте его до определенного числа, чтобы разрешить мультиарендность.
RedirectToHttps: будет ли ASP.NET Core перенаправлять весь трафик с HTTP на HTTPS. Это не зависит от конфигураций Caddy, Nginx и IIS, которые делают то же самое.
RemoteControlNotifyUsers: показывать ли уведомление конечному пользователю при запуске автоматического сеанса удаленного управления.
RemoteControlRequiresAuthentication: требует ли страница удаленного управления аутентификацию для установления соединения.
Require2FA: Требовать от пользователей настройки 2FA, прежде чем они смогут использовать основное приложение.
Smpt-: настройки SMTP для автоматически создаваемых системных сообщений электронной почты (например, регистрация и сброс пароля).
Тема: цветовая тема, используемая для сайта. Значения: «Светлый» или «Темный». Это также можно настроить для каждого пользователя в разделе «Учетная запись» — «Параметры».
TrustedCorsOrigins: для запросов API между источниками через JavaScript. Веб-сайтам, перечисленным в этом массиве, разрешено отправлять запросы к API. Это не обеспечивает аутентификацию, которая по-прежнему требуется на большинстве конечных точек.
UseHsts: будет ли ASP.NET Core использовать строгую транспортную безопасность HTTP.
UseHttpLogging: включает ведение журнала для всех HTTP-запросов. Также включает дополнительные записи журнала в ClientDownloadsController
касающиеся действующей схемы, хоста и удаленного IP-адреса в результате обработки пересылаемых заголовков.
Чтобы это работало, вы должны явно установить уровень журнала для Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware
. Пример см. в файле appsettings.json.
По умолчанию Remotely использует базу данных SQLite. При первом запуске он создает файл, указанный для строки подключения SQLite в appsettings.json.
Вы можете изменить базу данных, изменив DBProvider
в ApplicationOptions
на SQLServer
или PostgreSQL
.
На клиентах журналы хранятся в папке %ProgramData%RemotelyLogs
В контейнере сервера журналы будут записываться в /app/AppData/logs
, который (по умолчанию) будет смонтирован в /var/www/remotely/Logs
на хосте.
Встроенные журналы ASP.NET Core записываются на консоль (стандартный вывод). При желании вы можете перенаправить это в файл.
В IIS это можно сделать в файле web.config, установив для stdoutLogEnabled значение true.
На серверах Windows вышеуказанные журналы также могут быть записаны в журнал событий Windows.
Это можно включить в конфигурации сервера, установив для EnableWindowsEventLog значение true.
Вы можете настроить уровни ведения журнала и другие параметры в appsettings.json.
Дополнительная информация: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/.
Windows: тестируется только последняя версия Windows 11. Windows 7 и 8.1 должны работать, однако производительность в Windows 7 будет снижена.
Windows 2019/2022 также должна работать, но не тестируется регулярно.
Linux: тестируется только последняя LTS-версия Ubuntu.
Для клиента «быстрой поддержки» Ubuntu необходимо сначала установить следующие зависимости:
libc6-dev
libxtst-dev
xclip
libx11-dev
libxrandr-dev
В идеале вы должны осуществлять удаленное управление с настоящего компьютера или ноутбука. Тем не менее, я постарался сделать пульт дистанционного управления хоть в какой-то степени удобным для использования с мобильного устройства. Вот элементы управления:
Щелчок левой кнопкой мыши: одно нажатие.
Щелкните правой кнопкой мыши: нажмите и удерживайте, затем отпустите.
Нажмите и перетащите: нажмите и удерживайте, затем перетащите.
В /get-support
есть страница, на которой конечные пользователи могут запросить поддержку. Когда форма будет отправлена, на главной странице над сеткой появится предупреждение.
Ярлык этой страницы находится в папке Program FilesRemotely
. Вы можете скопировать его куда угодно. Вы также можете автоматически скопировать его на рабочий стол, используя переключатель -supportshortcut
в установщике.
.NET имеет два метода развертывания: зависимый от платформы и автономный.
Для развертываний, зависящих от платформы, на целевых компьютерах должна быть установлена среда выполнения .NET. Это должна быть та же версия, которая использовалась для создания приложения.
Автономные развертывания включают копию среды выполнения, поэтому вам не нужно устанавливать ее на целевые компьютеры. В результате общий размер файла намного больше.
.NET использует идентификаторы времени выполнения, которые используются при сборке.
Ссылка: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog.
При использовании консоли доступно несколько сочетаний клавиш.
/ : косая черта позволит вам переключаться между оболочками. Имена настраиваются на странице параметров.
Вверх/Вниз: используйте стрелки вверх/вниз для циклического просмотра истории ввода.
Ctrl + Q: очистить окно вывода.
Хост-порт (слева) можно настроить в docker-compose.yml
. Порт контейнера (правая сторона) менять не следует. Подробности смотрите в документации по Compose.
Remotely имеет базовый API, который можно просмотреть по адресу https://{your_server_url}/swagger
. Большинству конечных точек требуется аутентификация с помощью токена доступа к API, который можно создать, перейдя в раздел «Учетная запись» — «Доступ к API».
При доступе к API из браузера на другом веб-сайте вам необходимо настроить CORS в настройках приложения, добавив URL-адрес источника веб-сайта в массив TrustedCorsOrigins. Если вы не знакомы с тем, как работает CORS, я рекомендую прочитать об этом, прежде чем продолжить. Например, если бы я хотел создать форму входа на https://exmaple.com, которая бы входила в Remotely API, мне нужно было бы добавить https://example.com в TrustedCorsOrigins.
Каждый запрос к API должен иметь заголовок с именем «X-Api-Key». Значением должно быть идентификатор и секрет ключа API, разделенные двоеточием (например, [ApiKey]:[ApiSecret]).
Ниже приведен пример запроса API:
POST https://localhost:5001/API/Scripting/ExecuteCommand/PSCore/f2b0a595-5ea8-471b-975f-12e70e0f3497 HTTP/1.1 Content-Type: application/json X-Api-Key: 31fb288d-af97-4ce1-ae7b-ceebb98281ac:HLkrKaZGExYvozSPvcACZw9awKkhHnNK User-Agent: PostmanRuntime/7.22.0 Accept: */* Cache-Control: no-cache Host: localhost:5001 Accept-Encoding: gzip, deflate, br Content-Length: 12 Connection: close Get-Location
Ниже приведены примеры использования API входа на основе файлов cookie (JavaScript):
// Log in with one request, then launch remote control with another. fetch("https://localhost:5001/api/Login/", { method: "post", credentials: "include", mode: "cors", body: '{"email":"[email protected]", "password":"P@ssword1"}', headers: { "Content-Type": "application/json", } }).then(response=>{ if (response.ok) { fetch("https://localhost:44351/api/RemoteControl/Viewer/b68c24b0-2c67-4524-ad28-dadea7a576a4", { method: "get", credentials: "include", mode: "cors" }).then(response=>{ if (response.ok) { response.text().then(url=>{ window.open(url); }) } }) } }) // Log in and launch remote control in the same request. fetch("https://localhost:5001/api/RemoteControl/Viewer/", { method: "post", credentials: "include", mode: "cors", body: '{"email":"[email protected]", "password":"P@ssword1", "deviceID":"b68c24b0-2c67-4524-ad28-dadea7a576a4"}', headers: { "Content-Type": "application/json", } }).then(response=>{ if (response.ok) { response.text().then(url=>{ window.open(url); }) } })
API оповещений дает вам возможность добавлять функции мониторинга и оповещений к конечным точкам вашего устройства. Эта функция предназначена для добавления базовых функций типа RMM, не отклоняясь слишком далеко от основной цели Remotely.
Оповещения можно настроить для отображения уведомления на веб-сайте Remotely, отправки электронного письма и/или выполнения отдельного запроса API.
Чтобы использовать оповещения, вам сначала необходимо создать токен API (или несколько токенов) для использования вашими устройствами. Затем создайте запланированное задание или другой повторяющийся сценарий для выполнения этой работы. Ниже приведен пример использования PowerShell для создания запланированного задания, которое ежедневно проверяет дисковое пространство.
$Trigger = New-JobTrigger -Daily -At "5 AM" $Option = New-ScheduledJobOption -RequireNetwork Register-ScheduledJob -ScriptBlock { $OsDrive = Get-PSDrive -Name C $FreeSpace = $OsDrive.Free / ($OsDrive.Used + $OsDrive.Free) if ($FreeSpace -lt .1) { Invoke-WebRequest -Uri "https://localhost:5001/api/Alerts/Create/" -Method Post -Headers @{ X-Api-Key="3e9d8273-1dc1-4303-bd50-7a133e36b9b7:S+82XKZdvg278pSFHWtUklqHENuO5IhH" } -Body @" { "AlertDeviceID": "f2b0a595-5ea8-471b-975f-12e70e0f3497", "AlertMessage": "Low hard drive space. Free Space: $([Math]::Round($FreeSpace * 100))%", "ApiRequestBody": null, "ApiRequestHeaders": null, "ApiRequestMethod": null, "ApiRequestUrl": null, "EmailBody": "Low hard drive space for device Maker.", "EmailSubject": "Hard Drive Space Alert", "EmailTo": "[email protected]", "ShouldAlert": true, "ShouldEmail": true, "ShouldSendApiRequest": false } "@ -ContentType "application/json" } } -Name "Check OS Drive Space" -Trigger $Trigger -ScheduledJobOption $Option