← システム思考に戻る

DockerなしでWindowsにRustDeskサーバーを構築する

rustdeskself-hostingwindowsnssmremote-desktop
Windowsフラグを掲げて光るサーバーラックの上に立つシステム管理者のピクセルアート。漫画のクジラが下の虚空に落ちていく
Dockerなし。Proライセンスなし。2つのバイナリとNSSMだけ。

何を構築するか

2つのバイナリ — hbbs(ID/ランデブー)とhbbr(リレー)— をNSSMで自動起動のWindowsサービスとして管理する。LANのクライアントはRustDeskの公開インフラではなく、自分のサーバーを通じて接続する。

サーバーは初回起動時にEd25519の鍵ペアを生成する。すべてのクライアントがサーバーを信頼するために公開鍵が必要。秘密鍵を失ったら、すべて再生成。


前提条件

要件備考
Windows 10/11またはServer 2019以降Windows 11 24H2でテスト済み
サーバーの静的LAN IPDHCP予約でもOK
管理者権限サービスのインストールに必要
RustDeskクライアントのインストールサーバーとリモートマシンの両方に

ステップ1:バイナリをダウンロード

専用ディレクトリを作成する。このガイドではC:\RustDeskServer\を使う — 好きなパスを選べるが、サービスインストール後は移動しないこと。

RustDesk Server最新リリース

  • rustdesk-server-windows-x86_64-unsigned.zipをダウンロード
  • hbbs.exehbbr.exeをサーバーディレクトリに展開

NSSMdkxceフォークのv2.25(RustDesk公式ドキュメントで推奨)

  • win64\nssm.exeを同じディレクトリに展開

こうなっているはず:

C:\RustDeskServer\
├── hbbs.exe
├── hbbr.exe
└── nssm.exe

なぜdkxceフォーク? オリジナルのNSSMは2014年以降更新されていない。RustDesk公式ドキュメントはこのメンテナンスされたフォークにリンクしている。バージョン2.25は最新のWindowsでのサービス管理の重大な問題を修正している。


ステップ2:鍵を生成

hbbsを一度手動で実行して鍵ペアを生成する。管理者権限のPowerShellを開く:

cd C:\RustDeskServer

# まずhbbrを起動(hbbsがhbbrを期待する)
Start-Process .\hbbr.exe -WindowStyle Hidden
Start-Sleep -Seconds 3

# hbbsを起動 — YOUR_SERVER_IPを静的LAN IPに置き換える
Start-Process .\hbbs.exe -ArgumentList "-r YOUR_SERVER_IP" -WindowStyle Hidden
Start-Sleep -Seconds 5

# 両方を終了
Get-Process hbbs, hbbr -ErrorAction SilentlyContinue | Stop-Process -Force

ディレクトリにはこれが含まれる:

C:\RustDeskServer\
├── ...
├── id_ed25519           ← 秘密鍵(絶対に共有しないこと)
├── id_ed25519.pub       ← 公開鍵(クライアントが必要とする)
└── db_v2.sqlite3        ← 後で作成される(最初のクライアント接続時)

公開鍵を読み取る — すべてのクライアントに必要:

Get-Content .\id_ed25519.pub
# 出力: "OeVXq8zY1r3kP7mN=..."のような文字列 — 保存しておく。

ステップ3:NSSMサービスをインストール

ここがほとんどのガイドで失敗するところ。Windows 10/11で譲れない設定が3つある:

  1. AppNoConsole 1 — これがないと、NSSMはサービスの起動に静かに失敗する。これは最新のWindowsでのNSSMの既知のバグ
  2. AppDirectory — これがないと、鍵ファイルとデータベースがC:\Windows\System32に作られる。サーバーが自分の鍵を見つけられなくなる。
  3. DependOnService NlaSvc — これがないと、ネットワークアダプターの準備ができる前にサービスが起動し、ポートのバインドに失敗する。
$DIR = "C:\RustDeskServer"
$IP  = "YOUR_SERVER_IP"   # ← 静的LAN IPに置き換える

# --- hbbr(リレー)をインストール ---
& $DIR\nssm.exe install hbbr "$DIR\hbbr.exe"
& $DIR\nssm.exe set hbbr AppDirectory $DIR
& $DIR\nssm.exe set hbbr AppNoConsole 1
& $DIR\nssm.exe set hbbr Start SERVICE_DELAYED_AUTO_START
& $DIR\nssm.exe set hbbr DependOnService NlaSvc
& $DIR\nssm.exe set hbbr AppStdout "$DIR\hbbr_stdout.log"
& $DIR\nssm.exe set hbbr AppStderr "$DIR\hbbr_stderr.log"
& $DIR\nssm.exe set hbbr AppRotateFiles 1
& $DIR\nssm.exe set hbbr AppRotateOnline 1
& $DIR\nssm.exe set hbbr AppRotateBytes 1048576

# --- hbbs(ID/ランデブー)をインストール ---
& $DIR\nssm.exe install hbbs "$DIR\hbbs.exe" "-r $IP"
& $DIR\nssm.exe set hbbs AppDirectory $DIR
& $DIR\nssm.exe set hbbs AppNoConsole 1
& $DIR\nssm.exe set hbbs Start SERVICE_DELAYED_AUTO_START
& $DIR\nssm.exe set hbbs DependOnService "NlaSvc" "hbbr"
& $DIR\nssm.exe set hbbs AppStdout "$DIR\hbbs_stdout.log"
& $DIR\nssm.exe set hbbs AppStderr "$DIR\hbbs_stderr.log"
& $DIR\nssm.exe set hbbs AppRotateFiles 1
& $DIR\nssm.exe set hbbs AppRotateOnline 1
& $DIR\nssm.exe set hbbs AppRotateBytes 1048576

# --- 両方を起動 ---
& $DIR\nssm.exe start hbbr
Start-Sleep -Seconds 3
& $DIR\nssm.exe start hbbs

確認:

Get-Service hbbs, hbbr | Format-Table Name, Status, StartType

両方がRunning / Automaticと表示されるはず。

hbbsとhbbrサービスが自動起動で実行中のPowerShell出力
両方のサービスが遅延自動起動で実行中

ステップ4:ポートを確認

RustDeskは5つのポートを使用する。基本的なLAN運用に必要なのは3つだけ:

ポートプロトコルサービス用途必須
21115TCPhbbsNATタイプテスト
21116TCP+UDPhbbsID登録 + ハートビート
21117TCPhbbrリレー(リモートセッション)
21118TCPhbbsWebクライアント(WebSocket)
21119TCPhbbrWebリレー(WebSocket)

クイックチェック:

netstat -an | findstr /R "2111[5-7].*LISTENING"

6行表示されるはず(3ポート × IPv4 + IPv6)。足りない場合はstderrログを確認。

RustDeskポート21115、21116、21117がIPv4とIPv6でリッスンしているnetstat出力
6つのリスナーすべて確認 — 3ポートをIPv4とIPv6で

ファイアウォール:Windowsファイアウォールが有効な場合、受信規則を作成:

New-NetFirewallRule -DisplayName "RustDesk hbbs TCP" -Direction Inbound -Protocol TCP -LocalPort 21115-21116 -Action Allow -RemoteAddress YOUR_SUBNET/24
New-NetFirewallRule -DisplayName "RustDesk hbbs UDP" -Direction Inbound -Protocol UDP -LocalPort 21116 -Action Allow -RemoteAddress YOUR_SUBNET/24
New-NetFirewallRule -DisplayName "RustDesk hbbr TCP" -Direction Inbound -Protocol TCP -LocalPort 21117 -Action Allow -RemoteAddress YOUR_SUBNET/24

YOUR_SUBNET/24をLANの範囲に置き換える(例:192.168.1.0/24)。ローカルマシンのみにアクセスを制限。


ステップ5:クライアントを設定

すべてのクライアント — サーバーマシン上のものも含めて — を自分のサーバーに向ける必要がある。

オプションA:コマンドライン(推奨)

Windows:

& "$env:ProgramFiles\RustDesk\rustdesk.exe" --config "host=YOUR_SERVER_IP,key=YOUR_PUBLIC_KEY"

macOS:

sudo /Applications/RustDesk.app/Contents/MacOS/RustDesk --config "host=YOUR_SERVER_IP,key=YOUR_PUBLIC_KEY"

オプションB:GUI

RustDesk → 設定(⚙)→ ネットワーク → ID/リレーサーバー:

  • IDサーバーYOUR_SERVER_IP
  • キーid_ed25519.pubの内容
  • リレーサーバー:空欄のまま(自動検出)
  • APIサーバー:空欄のまま(Pro機能のみ)
自己ホスティングサーバー用に設定されたIDサーバーとキーフィールドを表示するRustDeskクライアントのネットワーク設定
IDサーバーとキーだけが必要なフィールド — 残りは空欄のまま

クライアント登録の確認

設定後、サーバーのログを確認:

Get-Content C:\RustDeskServer\hbbs_stdout.log -Tail 5

接続した各クライアントについてupdate_pk <CLIENT_ID>のエントリーが表示されるはず。接続を試みた際にクライアントのIDが「does not exist」と表示される場合、そのクライアントはまだサーバーに登録されていない。

すべての接続で両側が同じサーバーを使用する必要がある。 これがサポート問題の第一位。


メンテナンス

タスクコマンド
サービスの状態Get-Service hbbs, hbbr
サーバーログGet-Content C:\RustDeskServer\hbbs_stdout.log -Tail 20
サービス再起動Restart-Service hbbs; Restart-Service hbbr
サービス停止Stop-Service hbbs; Stop-Service hbbr
サービス削除nssm remove hbbs confirm; nssm remove hbbr confirm
鍵の再生成id_ed25519*を削除、hbbsを再起動

時間を無駄にする落とし穴

NSSMサービスが起動に静かに失敗する。 AppNoConsole 1を設定する。Windows 10/11でのNSSMの既知の問題で、サービスコンテキストでのコンソール割り当てが失敗する。このフラグなしでは、サービスが有用なエラーなしに起動-停止ループに入る。

鍵とデータベースがSystem32に現れる。 AppDirectoryをサーバーフォルダに設定する。NSSMはデフォルトでシステムディレクトリを作業ディレクトリとして使用する。hbbsは作業ディレクトリからの相対パスでファイルを書き込む。

サービスが起動時に失敗するが、手動で起動すると動作する。 SERVICE_DELAYED_AUTO_STARTDependOnService NlaSvcを追加する。早期起動サービスが始まる時点ではネットワークアダプターの準備ができていない。ネットワーク依存を持つ遅延起動でこれを解決。

接続時に「ID does not exist」。 ソースとターゲットの両方のマシンがサーバーを使用するよう設定されている必要がある。公開RustDeskサーバーを指しているクライアントのIDはそこにしか存在しない — 自分のサーバーにはその記録がない。

RustDesk ServerのGUIラッパーをNSSMと同時に実行しないこと。 GUIインストーラーRustDeskServer.Setup.exeとNSSMは両方とも同じバイナリを管理しようとする。どちらか一方を選ぶ。このガイドではNSSMを使用する — ユーザーログインなしで再起動に耐えるため。

-k _フラグは不要。 鍵ベースの認証はサーバーバージョン1.1.11以降デフォルト。含めても無害だが不要。

クライアント設定のリレーサーバーはオプション。 リレーがhbbsと同じマシンで動作している場合(一般的なケース)、クライアントは自動検出する。リレーが別のホストにある場合のみ設定。


参考資料