
DGX Spark にリモートデスクトップ環境を構築する(RustDesk + Tailscale)
はじめに
こんにちは、クラスメソッド製造ビジネステクノロジー部の森茂です。
DGX Spark の記事をいくつか書いてきましたが、今回は少し趣向を変えて、リモートデスクトップ環境の構築を取り上げます。
普段は SSH 経由の CLI 操作がメインで、GUI デスクトップにはほとんど触れていませんでした。ただ、GNOME Shell が動いているのにもったいないなと思っていたところで、リモートデスクトップ環境を整えてみることにしました。
この記事では、RustDesk と Tailscale の組み合わせで、中継サーバーなしのセキュアなリモートデスクトップ接続を構築する手順を紹介します。(私の環境では少々手こずったのですが、ほとんどの環境によっては何の手間もなく始められるかも。。。)
なぜ RustDesk + Tailscale なのか
リモートデスクトップの選択肢を調べていくなかで、RustDesk というオープンソースのリモートデスクトップソフトウェアの存在を知りました。名前のとおり Rust 言語で書かれており、軽量かつクロスプラットフォームで動作します。今回はこの RustDesk と Tailscale を組み合わせた「Direct IP Access」構成を選びました。
主な選択肢を比較すると、以下のようになります。
| 選択肢 | メリット | デメリット |
|---|---|---|
| VNC(TigerVNC 等) | 枯れた技術、設定がシンプル | 描画が重め、暗号化が別途必要 |
| Chrome Remote Desktop | セットアップが簡単 | Google アカウント依存、ARM 対応が? |
| RustDesk(公開サーバー経由) | オープンソース、クロスプラットフォーム | 公開リレーサーバー経由で遅延あり |
| RustDesk + Tailscale | 中継なし直接接続、二重暗号化 | 両方のセットアップが必要 |
個人的な決め手は、まず Tailscale の Direct IP Access を使えば hbbs/hbbr などの中継サーバーが不要で、インフラ管理がゼロになる点でした。加えて、Tailscale(WireGuard)と RustDesk(NaCl E2E)による二重暗号化で、経路と画面転送の両方が保護されます。
今回構築する接続の全体像は以下のとおりです。
中継サーバーを経由せず、Tailscale の WireGuard トンネル内で RustDesk が直接通信する構成です。
前提条件
今回の環境は以下のとおりです。
| 項目 | DGX Spark(サーバー側) | MacBook Pro(クライアント側) |
|---|---|---|
| OS | Ubuntu 24.04(DGX OS) | macOS |
| アーキテクチャ | aarch64(Grace CPU) | Apple Silicon |
| Tailscale IP | 100.x.x.x | 100.x.x.x |
| ディスプレイ | X11 + GDM + GNOME Shell | - |
Tailscale はすでに両マシンで設定済みで、tailscale status で direct 接続が確認できている状態です。
DGX Spark 側のセットアップ
RustDesk のインストール
DGX Spark は aarch64 アーキテクチャなので、ARM 版の deb パッケージをインストールします。
# アーキテクチャの確認
uname -m
# aarch64
# 最新版のダウンロード(2026年2月時点で 1.4.5)
cd /tmp
wget https://github.com/rustdesk/rustdesk/releases/download/1.4.5/rustdesk-1.4.5-aarch64.deb
# インストール
sudo dpkg -i rustdesk-1.4.5-aarch64.deb
sudo apt-get install -f -y
Direct IP Access と固定パスワードの設定
Tailscale 経由の直接接続を有効化し、無人アクセス用のパスワードを設定します。
# Direct IP Access を有効化
sudo rustdesk --option direct-server Y
# 固定パスワードを設定(16文字以上推奨)
sudo rustdesk --password '<your-strong-password>'
# RustDesk ID を確認(メモしておく)
rustdesk --get-id
systemd サービスの設定
RustDesk をサービスとして起動しますが、ここで一つはまりポイントがありました。systemd サービスは X11 セッションの外で動くため、ディスプレイ情報を明示的に渡す必要があります。
まず、現在のセッション情報を確認しましょう。
# X11 のディスプレイ番号を確認
# GNOME Shell のプロセスから環境変数を取得
cat /proc/$(pgrep -u $(whoami) gnome-shell | head -1)/environ | tr '\0' '\n' | grep ^DISPLAY=
# DISPLAY=:1
# XAUTHORITY のパスを確認
cat /proc/$(pgrep -u $(whoami) gnome-shell | head -1)/environ | tr '\0' '\n' | grep ^XAUTHORITY=
# XAUTHORITY=/run/user/1000/gdm/Xauthority
この情報を使って、systemd のオーバーライドファイルを作成します。
sudo mkdir -p /etc/systemd/system/rustdesk.service.d
sudo tee /etc/systemd/system/rustdesk.service.d/override.conf <<'EOF'
[Service]
Environment="DISPLAY=:1"
Environment="XAUTHORITY=/run/user/1000/gdm/Xauthority"
Environment="DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
Environment="XDG_SESSION_TYPE=x11"
EOF
sudo systemctl daemon-reload
sudo systemctl enable rustdesk
sudo systemctl start rustdesk
ヘッドレス環境での xorg.conf 設定
そしてここが今回一番はまったポイントです。
DGX Spark にモニターを接続せずに運用していると、xrandr の出力がすべて disconnected になります。RustDesk の画面キャプチャライブラリ(libscrap)は xrandr のモニター情報を使ってディスプレイを列挙するため、接続済みモニターが 0 件だと「ディスプレイがありません」というエラーになります。
# モニター未接続時の xrandr 出力
xrandr
# Screen 0: minimum 8 x 8, current 3440 x 1440, maximum 32767 x 32767
# HDMI-0 disconnected primary
# USB-C-0 disconnected
# USB-C-1 disconnected
# ...
X11 のスクリーン自体は存在していて GNOME も描画しているのに、RustDesk から見ると「画面がない」状態になるわけです。
解決策は、xorg.conf で NVIDIA ドライバーに対して HDMI-0 を「接続済み」として扱わせることです。
sudo vim /etc/X11/xorg.conf
Section "Device" に以下の 2 行を追加します。
Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
+ Option "ConnectedMonitor" "HDMI-0"
+ Option "ModeValidation" "NoDFPNativeResolutionCheck,NoVirtualSizeCheck,NoMaxPClkCheck,NoEdidMaxPClkCheck,NoMaxSizeCheck,NoHorizSyncCheck,NoVertRefreshCheck,NoWidthAlignmentCheck"
EndSection
ConnectedMonitor は物理的にモニターが繋がっていなくても、指定した出力を「接続済み」として認識させるオプションです。ModeValidation は EDID 情報がない状態でも各種解像度を許可するためのオプションです。
設定後、GDM を再起動します。
sudo systemctl restart gdm
再起動後に xrandr を確認すると、HDMI-0 が connected になっているはずです。
xrandr
# Screen 0: minimum 8 x 8, current 1920 x 1080, maximum 32767 x 32767
# HDMI-0 connected primary 1920x1080+0+0
# ...
解像度の調整
リモートデスクトップ用に解像度を変更したい場合は、nvidia-settings で即座に変更できます。(RustDesk クライアントアプリからも調整可能)
DISPLAY=:1 XAUTHORITY=/run/user/1000/gdm/Xauthority \
nvidia-settings --assign CurrentMetaMode="HDMI-0: 1920x1080 +0+0"
ファイアウォール設定
Tailscale 経由の通信はすでに WireGuard で暗号化されているため、ファイアウォール設定なしでも接続は可能です。ただし、ufw が有効な環境では Tailscale インターフェース限定でポートを明示的に開放しておくと、より堅牢になります。
sudo ufw allow in on tailscale0 to any port 21118 proto tcp comment 'RustDesk Direct IP'
sudo ufw allow in on tailscale0 to any port 21119 proto tcp comment 'RustDesk Direct IP'
tailscale0 に限定することで、Tailscale 外からのアクセスをブロックできます。
MacBook Pro 側のセットアップ
クライアント側は比較的シンプルです。
brew install --cask rustdesk
macOS の「システム設定 > プライバシーとセキュリティ」で以下を許可します。
- 画面収録 → RustDesk にチェック
- アクセシビリティ → RustDesk にチェック
RustDesk を起動したら、左側の「ID」入力欄に DGX Spark の Tailscale IP(100.x.x.x)を入力して接続します。初回接続時にパスワードを聞かれるので、先ほど rustdesk --password で設定した固定パスワードを入力してください。

接続してみる
MacBook Pro 側のセットアップが完了したら、RustDesk から DGX Spark に接続してみましょう。

パスワードを入力すると、DGX Spark の GNOME デスクトップが MacBook の画面に表示されます。Tailscale の直接接続(derp リレーなし)だと、同一ネットワーク内であればほぼ遅延を感じません。テキスト編集やターミナル操作は快適で、Web ブラウザのスクロールも引っかかりなく動きます。
接続後は RustDesk のツールバーから以下の調整が可能です。

- ウィンドウサイズの変更(クライアント側でリサイズ可能)
- 画質の調整(Balanced / Best)
- FPS の変更(デフォルト 30fps、動きの多い操作をするなら 60fps)
普段は SSH で十分なのですが、DGX Dashboard を確認したいときや、画像生成系の WebUI を活用したいときなど、GUI がほしい場面は意外とあります。そういったときにサッと繋がるリモートデスクトップ環境があると便利ですね。
トラブルシューティング
「ディスプレイがありません」エラー
最も遭遇しやすい問題です。RustDesk のサーバーログで以下のエラーが出ている場合は、xorg.conf の ConnectedMonitor 設定を確認してください。
ERROR: Failed to get display 0, displays len: 0
ログは以下の場所で確認できます。
# systemd ジャーナル
journalctl -u rustdesk -f
# RustDesk 独自のログ
cat ~/.local/share/logs/RustDesk/server/rustdesk_rCURRENT.log
接続できるが画面が真っ暗
GNOME のロック画面が表示されている可能性があります。RustDesk 経由でマウスを動かすかクリックすると、パスワード入力画面が現れます。
毎回ロック解除するのが面倒な場合は、GDM の自動ログインを有効にする方法もあります。
# /etc/gdm3/custom.conf に以下を追記
[daemon]
AutomaticLoginEnable=true
AutomaticLogin=<your-username>
Tailscale + RustDesk の固定パスワードで二重に保護されているので、自宅ネットワーク内であれば自動ログインのリスクは許容範囲かなと思っています。
systemd サービスの環境変数が反映されない
override.conf の内容が正しいか確認しましょう。
# オーバーライドファイルの確認
cat /etc/systemd/system/rustdesk.service.d/override.conf
# サービスのリロードと再起動
sudo systemctl daemon-reload
sudo systemctl restart rustdesk
まとめ
RustDesk + Tailscale の Direct IP Access で、DGX Spark のリモートデスクトップ環境を構築しました。
今回のポイントは以下のとおりです。
- Tailscale ネットワーク内で直接接続するため、中継サーバーが不要
- ヘッドレス運用時は xorg.conf の
ConnectedMonitor設定が必須 - systemd サービスには X11 セッション情報(DISPLAY、XAUTHORITY 等)を渡す必要がある
今回はヘッドレス環境での xrandr まわりの問題にはかなりはまりました。「物理モニターがなくても X11 スクリーンは存在するのに、RustDesk からは見えない」という状況は直感に反するところがあり、原因特定に時間がかかりました。同じ構成で試す方の参考になれば幸いです。
SSH で十分と思っていましたが、たまに GUI がほしくなる場面は意外とあるもので、これで DGX Spark の活用幅がまた少し広がりました。
参考リンク
- Tailscale × RustDesk 公式ガイド — Tailscale 側の設定手順とベストプラクティス
- RustDesk Linux クライアントドキュメント — Linux 版のインストールと設定
- RustDesk ヘッドレス Linux サポート Wiki — ヘッドレス環境での設定方法(xorg.conf 等)










