Uma solução de controle remoto e script remoto, desenvolvida com .NET, Blazor e SignalR Core.
Estou procurando mantenedores para me ajudar! Se você é um desenvolvedor .NET e está interessado em ajudar a continuar avançando remotamente, envie-me um DM no Discord em jaredatimmy
.
Subreddit: https://www.reddit.com/r/remotely_app/
Docker: https://hub.docker.com/r/immybot/remotely
Tutorial: https://www.youtube.com/watch?v=t-TFvr7sZ6M (Obrigado, @bmcgonag!)
mkdir -p /var/www/remotely wget -q https://raw.githubusercontent.com/immense/Remotely/master/docker-compose/docker-compose.yml docker-compose up -d
O único proxy reverso suportado é o Caddy, e somente quando ele está diretamente voltado para a Internet. A configuração padrão do Caddy fornece tudo que o ASP.NET Core e o SignalR precisam para funcionar corretamente.
Se você estiver tendo problemas de rede com qualquer outra configuração, como um firewall adicional ou Nginx, procure o suporte da comunidade na guia Discussões, no Reddit ou em outro site social. Os mantenedores do Remotely simplesmente não podem fornecer orientação e suporte para todas as configurações de ambiente possíveis.
Dito isso, o ASP.NET Core exige que os seguintes cabeçalhos sejam definidos quando estiver atrás de um proxy reverso: X-Forwarded-Proto
, X-Forwarded-Host
e X-Forwarded-For
. Eles se correlacionam ao esquema (http/https), à URL da solicitação original e ao endereço IP do cliente, respectivamente. O esquema e o host resultantes são injetados nos instaladores e clientes de desktop, para que eles saibam para onde enviar solicitações. O endereço IP do cliente é usado nas informações do dispositivo.
O código Remotely não analisa nem manipula esses valores. Isso é feito internamente pelo middleware integrado do ASP.NET Core. Se os valores não aparecerem conforme o esperado, é porque os cabeçalhos estavam faltando, não continham os valores corretos, não estavam no formato correto ou não passaram por uma cadeia de proxies conhecidos (veja abaixo).
Para evitar ataques de injeção, o padrão do ASP.NET Core é aceitar apenas cabeçalhos encaminhados de endereços de loopback. Remotamente também adicionará o IP do gateway Docker (172.28.0.1) definido no arquivo docker-compose. Se você estiver usando uma configuração não padrão, deverá adicionar todos os endereços de firewall e proxy reverso à matriz KnownProxies
na Configuração do Servidor.
Se você não conseguir configurar seus proxies reversos corretamente, você pode pelo menos forçar o uso do esquema HTTPS definindo Force Client HTTPS
na página Configuração do servidor.
A documentação completa da Microsoft sobre o tópico pode ser encontrada aqui: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer
Os dados para Remotely serão salvos no contêiner em /app/AppData
, que será montado em /var/www/remotely/
em seu host Docker.
Esta pasta conterá Remotely.db e logs gerados pelo servidor.
Esses arquivos persistirão durante a desmontagem e configuração de novos contêineres remotamente.
Se estiver atualizando de uma versão não Docker do Remotely, substitua o arquivo DB de sua instalação anterior.
Use o Caddy como proxy reverso se quiser expor o site à Internet.
Se esta for a primeira vez, crie sua conta clicando no botão Register
na página principal.
As organizações são usadas para agrupar usuários, dispositivos e outros itens de dados em um único pool.
Por padrão, apenas uma organização pode existir em um servidor.
O botão Register
desaparecerá.
As pessoas não poderão mais criar contas por conta própria.
Para permitir o autorregistro, aumente MaxOrganizationCount
ou defina-o como -1 (consulte a seção Configuração).
Esta conta será o administrador do servidor e o administrador da organização.
Uma organização é criada automaticamente para a conta.
Você pode ativar o log HTTP para ver todas as solicitações e respostas nos logs do servidor, incluindo cabeçalhos. Isso pode ser útil para depurar problemas de proxy reverso, API ou SignalR. A opção pode ser habilitada na página Configuração do Servidor.
Depois de alterar o acima, você deve reiniciar o contêiner para que as alterações tenham efeito.
As etapas a seguir configurarão sua máquina Windows 11 para construir o servidor e os clientes remotamente.
Instale o Visual Studio 2022.
SDK do .NET (versão mais recente).
MSBuild (que seleciona automaticamente os compiladores Roslyn).
Destinos do NuGet e tarefas de build.
SDK do .NET Framework 4.8.
Para depuração e desenvolvimento, você precisará de todas as cargas de trabalho relevantes.
ASP.NET e desenvolvimento web
Desenvolvimento de desktop .NET
Desenvolvimento multiplataforma .NET Core
Link: https://visualstudio.microsoft.com/downloads/
Você deve ter as seguintes cargas de trabalho selecionadas:
Você deve ter os seguintes componentes individuais selecionados:
Instale o Git para Windows.
Link: https://git-scm.com/downloads
Instale o nó LTS mais recente:
Link: https://nodejs.org/
Clone o repositório git: git clone https://github.com/immense/Remotely --recurse
Ao depurar, o agente usará um ID de dispositivo predefinido e se conectará a https://localhost:5001.
No ambiente de desenvolvimento, o servidor atribuirá todos os agentes de conexão à primeira organização.
Os dois acima permitem que você depure o agente e o servidor juntos e veja seu dispositivo na lista.
A primeira conta criada será de administrador do servidor e da organização criada para a conta.
Um administrador da organização tem acesso à página Organização e às entradas de log do servidor específicas de sua organização. Um administrador de servidor tem acesso à página Configuração do servidor e pode ver entradas de log do servidor que não pertencem a uma organização.
Na seção Conta, há uma guia para marca, que se aplicará aos clientes de suporte rápido e ao instalador do Windows.
No entanto, os clientes precisarão ter sido criados a partir da fonte com a URL do servidor codificada nos aplicativos para que possam recuperar as informações da marca.
O provedor de banco de dados, as cadeias de conexão e a porta do ASP.NET Core são configuráveis por meio de variáveis de ambiente em docker-compose.yml
.
Todas as outras configurações são feitas na página Server Config assim que você estiver logado.
AllowApiLogin: permite o login por meio do controlador de API. Tokens de acesso à API são recomendados nesta abordagem.
BannedDevices: uma série de IDs, nomes ou endereços IP de dispositivos a serem banidos. Quando eles tentarem se conectar, um comando de desinstalação será enviado imediatamente de volta.
DataRetentionInDays: Por quanto tempo os logs e outros dados serão mantidos no servidor. Defina como -1 para reter indefinidamente (não recomendado).
DBProvider: Determina qual das três strings de conexão (na parte superior) será usada. O provedor de banco de dados apropriado para o tipo de banco de dados é carregado automaticamente no código.
EnableWindowsEventLog: se também serão adicionadas entradas de log do servidor ao log de eventos do Windows.
EnforceAttendedAccess: os clientes serão solicitados a permitir tentativas de controle remoto autônomas.
EnableRemoteControlRecording: Se deseja salvar gravações de sessões de controle remoto no servidor.
Eles serão salvos em /app/AppData/recordings
.
A sua retenção é regida por DataRetentionInDays
.
ForceClientHTTPS: força os instaladores e clientes de desktop a usarem o esquema HTTPS, mesmo se os cabeçalhos encaminhados estiverem configurados incorretamente.
KnownProxies: Se o seu proxy reverso estiver em uma máquina diferente e encaminhar solicitações para o servidor Remotely, você precisará adicionar o IP do servidor proxy reverso a esta matriz.
MaxOrganizationCount: Por padrão, pode existir uma organização no servidor, que é criada automaticamente quando a primeira conta é registrada. Depois disso, o autorregistro será desativado.
Defina como -1 ou aumente para um número específico para permitir multilocação.
RedirectToHttps: se o ASP.NET Core redirecionará todo o tráfego de HTTP para HTTPS. Isso é independente das configurações de Caddy, Nginx e IIS que fazem o mesmo.
RemoteControlNotifyUsers: se uma notificação será mostrada ao usuário final quando uma sessão de controle remoto autônoma for iniciada.
RemoteControlRequiresAuthentication: se a página de controle remoto requer autenticação para estabelecer uma conexão.
Require2FA: Exija que os usuários configurem 2FA antes de poderem usar o aplicativo principal.
Smpt-: Configurações de SMTP para e-mails de sistema gerados automaticamente (como registro e redefinição de senha).
Tema: O tema de cores a ser usado no site. Os valores são "Claro" ou "Escuro". Isso também pode ser configurado por usuário em Conta - Opções.
TrustedCorsOrigins: para solicitações de API de origem cruzada via JavaScript. Os sites listados nesta matriz podem fazer solicitações à API. Isto não concede autenticação, que ainda é necessária na maioria dos endpoints.
UseHsts: se o ASP.NET Core usará HTTP Strict Transport Security.
UseHttpLogging: permite o registro em log de todas as solicitações HTTP. Também permite entradas de log adicionais em ClientDownloadsController
relacionadas ao esquema efetivo, host e endereço IP remoto como resultado do processamento de cabeçalhos encaminhados.
Você deve definir explicitamente um nível de log para Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware
para que isso funcione. Veja appsettings.json para ver um exemplo.
Por padrão, remotamente usa um banco de dados SQLite. Quando executado pela primeira vez, ele cria um arquivo conforme especificado para a cadeia de conexão SQLite em appsettings.json.
Você pode alterar o banco de dados alterando DBProvider
em ApplicationOptions
para SQLServer
ou PostgreSQL
.
Nos clientes, os logs são mantidos em %ProgramData%RemotelyLogs
Dentro do contêiner do servidor, os logs serão gravados em /app/AppData/logs
, que (por padrão) será montado em /var/www/remotely/Logs
no host.
Os logs internos do ASP.NET Core são gravados no console (stdout). Você pode redirecionar isso para um arquivo, se desejar.
No IIS, isso pode ser feito no arquivo web.config definindo stdoutLogEnabled como true.
Em servidores Windows, os logs acima também podem ser gravados no log de eventos do Windows.
Isso é habilitado na Configuração do Servidor definindo EnableWindowsEventLog como true.
Você pode definir níveis de registro e outras configurações em appsetttings.json.
Mais informações: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/
Windows: apenas a versão mais recente do Windows 11 é testada. O Windows 7 e o 8.1 devem funcionar, embora o desempenho seja reduzido no Windows 7.
O Windows 2019/2022 também deve funcionar, mas não é testado regularmente.
Linux: apenas a versão LTS mais recente do Ubuntu é testada.
Para o cliente de “suporte rápido” do Ubuntu, você deve primeiro instalar as seguintes dependências:
libc6-dev
libxtst-dev
xclip
libx11-dev
libxrandr-dev
Idealmente, você faria o controle remoto a partir de um computador ou laptop real. No entanto, tentei tornar o controle remoto pelo menos um pouco utilizável em um dispositivo móvel. Aqui estão os controles:
Clique com o botão esquerdo: toque único
Clique com o botão direito: mantenha pressionado e solte
Clique e arraste: mantenha pressionado e arraste
Há uma página em /get-support
onde os usuários finais podem solicitar suporte. Ao enviar o formulário, um alerta aparece na página principal, acima da grade.
Um atalho para esta página é colocado na pasta Program FilesRemotely
. Você pode copiá-lo para onde quiser. Você também pode copiá-lo para a área de trabalho automaticamente usando a opção -supportshortcut
no instalador.
O .NET possui dois métodos de implantação: dependente da estrutura e independente.
As implantações dependentes da estrutura exigem que o tempo de execução do .NET seja instalado nos computadores de destino. Deve ser a mesma versão usada para criar o aplicativo.
As implantações independentes incluem uma cópia do runtime, portanto, você não precisa instalá-lo nos computadores de destino. Como resultado, o tamanho total do arquivo é muito maior.
O .NET usa identificadores de tempo de execução que são direcionados durante a construção.
Link: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
Existem algumas teclas de atalho disponíveis ao usar o console.
/: Slash permitirá que você alterne entre shells. Os nomes são configuráveis na página Opções.
Para cima/para baixo: use as setas para cima/para baixo para percorrer o histórico de entrada.
Ctrl + Q: Limpa a janela de saída.
A porta host (lado esquerdo) pode ser configurada em docker-compose.yml
. A porta do contêiner (lado direito) não deve ser alterada. Consulte a documentação de composição para obter detalhes.
Possui remotamente uma API básica, que pode ser navegada em https://{your_server_url}/swagger
. A maioria dos endpoints exige autenticação por meio de um token de acesso à API, que pode ser criado acessando Conta - Acesso à API.
Ao acessar a API do navegador em outro site, você precisará configurar o CORS em appsettings adicionando o URL de origem do site à matriz TrustedCorsOrigins. Se você não está familiarizado com o funcionamento do CORS, recomendo lê-lo antes de continuar. Por exemplo, se eu quisesse criar um formulário de login em https://exmaple.com conectado à API Remotely, precisaria adicionar "https://example.com" ao TrustedCorsOrigins.
Cada solicitação à API deve ter um cabeçalho denominado "X-Api-Key". O valor deve ser o ID e o segredo da chave de API, separados por dois pontos (ou seja, [ApiKey]:[ApiSecret]).
Abaixo está um exemplo de solicitação de 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
Abaixo estão exemplos de uso da API de login baseada em cookies (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); }) } })
A API Alerts oferece a capacidade de adicionar funcionalidades de monitoramento e alerta aos endpoints do seu dispositivo. Este recurso tem como objetivo adicionar funcionalidade básica do tipo RMM sem divergir muito do objetivo principal do Remotely.
Os alertas podem ser configurados para mostrar uma notificação no site do Remotely, enviar um e-mail e/ou realizar uma solicitação de API separada.
Para usar Alertas, primeiro você precisa criar um token de API (ou vários tokens) para seus dispositivos usarem. Em seguida, crie uma tarefa agendada ou algum outro script recorrente para realizar o trabalho. Abaixo está um exemplo de como usar o PowerShell para criar um trabalho agendado que verifica o espaço em disco diariamente.
$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