远程控制和远程脚本解决方案,使用 .NET、Blazor 和 SignalR Core 构建。
我正在寻找维护人员来帮助我!如果您是一名 .NET 开发人员并且有兴趣帮助推动 Remotely 向前发展,请在jaredatimmy
上向我发送有关 Discord 的 DM。
Reddit 子版块:https://www.reddit.com/r/remotely_app/
Docker: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 或其他社交网站的“讨论”选项卡中寻求社区支持。远程维护人员根本无法为所有可能的环境设置提供指导和支持。
话虽如此,ASP.NET Core 需要在反向代理后面设置以下标头: X-Forwarded-Proto
、 X-Forwarded-Host
和X-Forwarded-For
。这些分别与方案 (http/https)、原始请求的 URL 和客户端的 IP 地址相关。生成的方案和主机被注入到安装程序和桌面客户端中,以便它们知道将请求发送到哪里。客户端 IP 地址用于设备信息中。
远程代码不会解析或处理这些值。它是由 ASP.NET Core 的内置中间件在内部完成的。如果值未按预期显示,这是因为标头丢失、未包含正确的值、格式不正确或未通过已知代理链(见下文)。
为了避免注入攻击,ASP.NET Core 默认只接受来自环回地址的转发标头。远程还会添加 docker-compose 文件中定义的 Docker 网关 IP (172.28.0.1)。如果您使用非默认配置,则必须将所有防火墙和反向代理地址添加到服务器配置中的KnownProxies
数组中。
如果您无法正确配置反向代理,您至少可以通过在服务器配置页面中设置Force Client HTTPS
来强制使用 HTTPS 方案。
有关该主题的 Microsoft 完整文档可以在这里找到:https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer
Remotely 的数据将保存在/app/AppData
下的容器中,该容器将安装到 Docker 主机上的/var/www/remotely/
。
该文件夹将包含Remotely.db 和服务器生成的日志。
这些文件将在新远程容器的拆卸和设置过程中持续存在。
如果从 Remotely 的非 Docker 版本升级,请覆盖之前安装的数据库文件。
如果您想将网站公开到互联网,请使用 Caddy 作为反向代理。
如果这是第一次运行,请通过单击主页上的Register
按钮来创建您的帐户。
组织用于将用户、设备和其他数据项分组到一个池中。
默认情况下,一台服务器上只能存在一个组织。
Register
按钮将会消失。
人们将不再能够自己创建帐户。
要允许自行注册,请增加MaxOrganizationCount
或将其设置为 -1(请参阅配置部分)。
该帐户将同时是服务器管理员和组织管理员。
系统会自动为该帐户创建一个组织。
您可以启用 HTTP 日志记录以查看服务器日志中的所有请求和响应,包括标头。这对于调试反向代理、API 或 SignalR 问题很有帮助。可以在“服务器配置”页面上启用该选项。
更改上述内容后,必须重新启动容器才能使更改生效。
以下步骤将配置您的 Windows 11 计算机以构建远程服务器和客户端。
安装 Visual Studio 2022。
.NET SDK(最新版本)。
MSBuild(自动选择 Roslyn 编译器)。
NuGet 目标和构建任务。
.NET Framework 4.8 SDK。
对于调试和开发,您将需要所有相关的工作负载。
ASP.NET 和 Web 开发
.NET 桌面开发
.NET Core跨平台开发
链接:https://visualstudio.microsoft.com/downloads/
您应该选择以下工作负载:
您应该选择以下各个组件:
安装适用于 Windows 的 Git。
链接:https://git-scm.com/downloads
安装最新的 LTS 节点:
链接:https://nodejs.org/
克隆 git 存储库: git clone https://github.com/immense/Remotely --recurse
调试时,代理将使用预定义的设备 ID 并连接到 https://localhost:5001。
在开发环境中,服务器会将所有连接代理分配给第一个组织。
上面两个允许您一起调试代理和服务器,并在列表中查看您的设备。
创建的第一个帐户将是服务器和为该帐户创建的组织的管理员。
组织管理员有权访问组织页面和特定于其组织的服务器日志条目。服务器管理员有权访问“服务器配置”页面,并且可以查看不属于组织的服务器日志条目。
在“帐户”部分中,有一个品牌选项卡,该选项卡将应用于快速支持客户端和 Windows 安装程序。
但是,客户端需要从源代码构建,并在应用程序中硬编码服务器 URL,以便能够检索品牌信息。
数据库提供程序、连接字符串和 ASP.NET Core 端口可通过docker-compose.yml
中的环境变量进行配置。
登录后,所有其他配置都在“服务器配置”页面中完成。
AllowApiLogin:是否允许通过API控制器登录。建议使用 API 访问令牌而不是这种方法。
BannedDevices:要禁止的设备 ID、名称或 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:用于通过 JavaScript 进行跨源 API 请求。允许此数组中列出的网站向 API 发出请求。这不会授予身份验证,而大多数端点仍然需要身份验证。
UseHsts:ASP.NET Core 是否将使用 HTTP 严格传输安全。
UseHttpLogging:启用所有 HTTP 请求的日志记录。还可以在ClientDownloadsController
中启用有关有效方案、主机和远程 IP 地址的附加日志条目,作为处理转发标头的结果。
您必须显式设置Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware
的日志级别才能使其正常工作。有关示例,请参阅 appsettings.json。
默认情况下,远程使用 SQLite 数据库。首次运行时,它会创建一个为 appsettings.json 中的 SQLite 连接字符串指定的文件。
您可以通过将ApplicationOptions
中的DBProvider
更改为SQLServer
或PostgreSQL
来更改数据库。
在客户端上,日志保存在%ProgramData%RemotelyLogs
中
在服务器容器内,日志将写入/app/AppData/logs
,该日志(默认情况下)将安装到主机上的/var/www/remotely/Logs
。
内置 ASP.NET Core 日志写入控制台 (stdout)。如果需要,您可以将其重定向到文件。
在 IIS 中,可以通过将 stdoutLogEnabled 设置为 true 在 web.config 文件中完成此操作。
在 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:仅测试了 Ubuntu 的最新 LTS 版本。
对于Ubuntu的“快速支持”客户端,您必须首先安装以下依赖项:
libc6-dev
libxtst-dev
剪辑
libx11-dev
libxrandr-dev
理想情况下,您可以从实际的计算机或笔记本电脑进行远程控制。不过,我尝试让遥控器至少在某种程度上可以通过移动设备使用。以下是控件:
左键单击:单击
右键单击:长按,然后松开
单击并拖动:长按,然后拖动
/get-support
有一个页面,最终用户可以在其中请求支持。提交表单后,主页上的网格上方会出现一条警报。
此页面的快捷方式位于Program FilesRemotely
文件夹中。您可以将其复制到任何您喜欢的地方。您还可以使用安装程序上的-supportshortcut
开关将其自动复制到桌面。
.NET 有两种部署方法:依赖框架和独立部署。
依赖于框架的部署需要在目标计算机上安装 .NET 运行时。它必须与用于构建应用程序的版本相同。
独立部署包含运行时的副本,因此您无需将其安装在目标计算机上。因此,总文件大小要大得多。
.NET 使用构建时目标的运行时标识符。
链接:https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
使用控制台时有几个可用的快捷键。
/ :斜杠将允许您在 shell 之间切换。名称可在“选项”页面中配置。
向上/向下:使用向上/向下箭头循环浏览输入历史记录。
Ctrl + Q:清除输出窗口。
主机端口(左侧)可以在docker-compose.yml
中配置。 集装箱端口(右侧)不应更改。有关详细信息,请参阅撰写文档。
Remotely 有一个基本的 API,可以在https://{your_server_url}/swagger
浏览。大多数端点需要通过 API 访问令牌进行身份验证,可以通过转到帐户 - API 访问来创建该令牌。
从另一个网站上的浏览器访问 API 时,您需要通过将网站源 URL 添加到 TrustedCorsOrigins 数组来在 appsettings 中设置 CORS。如果您不熟悉 CORS 的工作原理,我建议您先阅读一下,然后再继续。例如,如果我想在 https://exmaple.com 上创建一个登录远程 API 的登录表单,我需要将“https://example.com”添加到 TrustedCorsOrigins。
对 API 的每个请求都必须有一个名为“X-Api-Key”的标头。该值应该是 API 密钥的 ID 和密钥,以冒号分隔(即 [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
以下是使用基于 cookie 的登录 API (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 类型功能,但不会偏离远程的主要目的太远。
警报可以设置为在远程网站上显示通知、发送电子邮件和/或执行单独的 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