.NET、Blazor、SignalR Core で構築されたリモート コントロールおよびリモート スクリプト ソリューション。
手伝ってくれるメンテナーさんを募集中です!あなたが .NET 開発者で、Remotely の前進を支援することに興味がある場合は、Discord のjaredatimmy
に DM を送ってください。
サブレディット: 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 はデフォルトで、ループバック アドレスから転送されたヘッダーのみを受け入れるように設定されています。リモートでは、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 コンテナの破棄とセットアップを通じて保持されます。
Remotely の非 Docker バージョンからアップグレードする場合は、以前のインストールの DB ファイルを上書きします。
サイトをインターネットに公開する場合は、Caddy をリバース プロキシとして使用します。
初めて実行する場合は、メイン ページのRegister
ボタンをクリックしてアカウントを作成します。
組織は、ユーザー、デバイス、およびその他のデータ項目を 1 つのプールにグループ化するために使用されます。
デフォルトでは、サーバー上に存在できる組織は 1 つだけです。
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 に接続します。
開発環境では、サーバーは接続しているすべてのエージェントを最初の組織に割り当てます。
上記 2 つを使用すると、エージェントとサーバーを一緒にデバッグし、リストにデバイスを表示できます。
最初に作成されたアカウントは、サーバーと、そのアカウント用に作成された組織の両方の管理者になります。
組織管理者は、組織ページおよび自分の組織に固有のサーバー ログ エントリにアクセスできます。サーバー管理者は [サーバー構成] ページにアクセスでき、組織に属さないサーバー ログ エントリを表示できます。
「アカウント」セクション内にはブランド用のタブがあり、これはクイック サポート クライアントと Windows インストーラーに適用されます。
ただし、クライアントがブランド情報を取得できるようにするには、アプリ内にハードコーディングされたサーバー URL を使用してソースからクライアントを構築する必要があります。
データベース プロバイダー、接続文字列、および ASP.NET Core ポートは、 docker-compose.yml
の環境変数を介して構成できます。
他のすべての設定は、ログイン後に [サーバー設定] ページで実行します。
AllowApiLogin: API コントローラー経由のログインを許可するかどうか。このアプローチよりも API アクセス トークンの使用をお勧めします。
BannedDevices: 禁止するデバイス ID、名前、または IP アドレスの配列。接続しようとすると、すぐにアンインストール コマンドが送り返されます。
DataRetentionInDays: ログおよびその他のデータがサーバー上に保持される期間。無期限に保持するには、-1 に設定します (非推奨)。
DBProvider: 3 つの接続文字列 (上部) のどれを使用するかを決定します。データベース タイプに適切な DB プロバイダーがコードに自動的にロードされます。
EnableWindowsEventLog: Windows イベント ログにサーバー ログ エントリも追加するかどうか。
EnforceAttendedAccess: クライアントは、無人リモート コントロールの試行を許可するように求められます。
EnableRemoteControlRecording: リモート コントロール セッションの記録をサーバーに保存するかどうか。
これらは/app/AppData/recordings
に保存されます。
それらの保持はDataRetentionInDays
によって管理されます。
ForceClientHTTPS: 転送されたヘッダーが正しく構成されていない場合でも、インストーラーとデスクトップ クライアントに HTTPS スキームの使用を強制します。
KnownProxies: リバース プロキシが別のマシン上にあり、リクエストを Remotely サーバーに転送している場合は、リバース プロキシ サーバーの IP をこのアレイに追加する必要があります。
MaxOrganizationCount: デフォルトでは、サーバー上に存在できる組織は 1 つで、最初のアカウントが登録されるときに自動的に作成されます。その後、自己登録は無効になります。
マルチテナンシーを可能にするには、これを -1 に設定するか、特定の数値に増やします。
RedirectToHttps: ASP.NET Core がすべてのトラフィックを HTTP から HTTPS にリダイレクトするかどうか。これは、同じことを行う Caddy、Nginx、および IIS 構成とは独立しています。
RemoteControlNotifyUsers: 無人リモート コントロール セッションの開始時にエンド ユーザーに通知を表示するかどうか。
RemoteControlRequiresAuthentication: リモート コントロール ページで接続を確立するために認証が必要かどうか。
Require2FA: メイン アプリを使用する前に、ユーザーに 2FA をセットアップするよう要求します。
Smpt-: 自動生成されたシステム電子メールの SMTP 設定 (登録やパスワードのリセットなど)。
テーマ: サイトに使用する色のテーマ。値は「明るい」または「暗い」です。これは、「アカウント - オプション」でユーザーごとに構成することもできます。
TrustedCorsOrigins: JavaScript を介したクロスオリジン API リクエスト用。この配列にリストされている Web サイトは、API へのリクエストを行うことができます。これは認証を許可しませんが、ほとんどのエンドポイントでは依然として認証が必要です。
UseHsts: ASP.NET Core が HTTP Strict Transport Security を使用するかどうか。
UseHttpLogging: すべての HTTP リクエストのログ記録を有効にします。また、転送されたヘッダーの処理の結果として、有効なスキーム、ホスト、リモート IP アドレスに関するClientDownloadsController
の追加のログ エントリも有効になります。
これを機能させるには、 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 では、これは web.config ファイルで stdoutLogEnabled を true に設定することで実行できます。
Windows サーバーでは、上記のログが Windows イベント ログに書き込まれることもあります。
これは、サーバー構成で EnableWindowsEventLog を true に設定することで有効になります。
appsetttings.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
xクリップ
libx11-dev
libxrandr-dev
理想的には、実際のコンピューターまたはラップトップからリモート制御を行うことになります。ただし、少なくともある程度はモバイル デバイスからリモコンを使用できるようにしてみました。コントロールは次のとおりです。
左クリック:シングルタップ
右クリック: 長押ししてから放します
クリックアンドドラッグ: 長押ししてからドラッグします。
/get-support
には、エンド ユーザーがサポートをリクエストできるページがあります。フォームが送信されると、メイン ページのグリッドの上にアラートが表示されます。
このページへのショートカットは、 Program FilesRemotely
フォルダーに配置されます。好きな場所にコピーできます。インストーラーの-supportshortcut
スイッチを使用して、デスクトップに自動的にコピーすることもできます。
.NET には、フレームワーク依存型と自己完結型という 2 つの展開方法があります。
フレームワークに依存した展開では、ターゲット コンピューターに .NET ランタイムがインストールされている必要があります。アプリの構築に使用されたバージョンと同じバージョンである必要があります。
自己完結型の展開にはランタイムのコピーが含まれるため、ターゲット コンピューターにランタイムをインストールする必要はありません。その結果、ファイルの合計サイズはさらに大きくなります。
.NET は、ビルド時にターゲットとなるランタイム識別子を使用します。
リンク: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
コンソールを使用するときに使用できるショートカット キーがいくつかあります。
/ : スラッシュを使用してシェルを切り替えることができます。名前は「オプション」ページで構成できます。
上/下: 上/下矢印を使用して、入力履歴を循環します。
Ctrl + Q: 出力ウィンドウをクリアします。
ホスト ポート (左側) はdocker-compose.yml
で設定できます。 コンテナポート(右側)は変更しないでください。詳細については、作成ドキュメントを参照してください。
Remotely には基本的な API があり、 https://{your_server_url}/swagger
で参照できます。ほとんどのエンドポイントでは、API アクセス トークンによる認証が必要です。API アクセス トークンは、[アカウント] - [API アクセス] に移動して作成できます。
別の Web サイトのブラウザーから API にアクセスする場合は、Web サイトのオリジン URL を TrustedCorsOrigins 配列に追加して、appsettings で CORS を設定する必要があります。 CORS の仕組みに詳しくない場合は、先に進む前によく読んでおくことをお勧めします。たとえば、Remotely API にログインするログイン フォームを https://exmaple.com に作成したい場合は、TrustedCorsOrigins に「https://example.com」を追加する必要があります。
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); }) } })
Alerts API を使用すると、デバイスのエンドポイントに監視およびアラート機能を追加できます。この機能は、Remotely の主な目的から大きく逸脱することなく、基本的な RMM タイプの機能を追加することを目的としています。
Remotely Web サイトに通知を表示したり、電子メールを送信したり、別の 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