ネットワークRustDeskARPWindowsWi-Fi

RustDeskのローカルIP指定で接続エラーになる問題

RustDeskのローカルIP指定で接続エラーになる問題

はじめに

自室のデスクトップのWindowsで個人開発をするにあたり,作業場所を自由にしたいという気持ちから,ASUS(「エイスース」と読むことを最近知りました)のノートPCを買ってRustDeskでリモデして作業できるようにしました。

ローカルIP指定で接続したら有線じゃなくてもサクサク動くしめっちゃ快適なんですが,使っているうちに接続が失敗するようになってきました。

出鼻を挫かれて涙目になりながらも,RustDesk自体は引き続き使っていきたいので,Claude Codeに手伝ってもらいながらトラシューしました。

症状

RustDeskで対象PCに繋ごうとすると,クライアント画面に「Failed to connect to 192.168.◯.◯:◯◯ 後でもう一度お試しください」と出てしまう。

切り分け

まずRustDesk自体のログ(%AppData%\RustDesk\log\配下)を確認してみましたが,画面に出てた内容以上の情報は特になし。

次にネットワークのレイヤーまで降りて,対象PCへの疎通を直接確認することにしました。接続元PCから対象PCのIPアドレス宛にpingを打つと,「宛先ホストに到達できません」。なるほど。

念のため接続元PCでarp -aを確認すると,対象PCのIPアドレスに対応するエントリが見当たらず,実際にARP解決ができていないことが確認できました。

暫定措置

「そもそもARPで動的に解決できていないのが原因っぽいな」というところまではわかったんですが,この問題を更に掘り下げるよりはとりあえずリモデできるようにして当初の作業に戻りたかったので,暫定措置としてnetshコマンドで静的ARPエントリを登録しました(要管理者権限)。

netsh interface ipv4 add neighbors "<接続元PCのインターフェース名>" "<対象PCの現在のIPアドレス>" "<対象PCのMACアドレス>"

インターフェース名はGet-NetAdapternetsh interface ipv4 show interfacesで確認できます。

ちなみに,この暫定措置は過去2回実施して,1回目はたしか(ログ紛失)arp -sコマンドで登録したと思うんですが,2回目に試したらARP entry addition failed: アクセスが拒否されましたエラーで失敗したため,netsh interface ipv4 add neighborsに切り替えたという経緯があります。調べたらarp -sはWindows7以降上手く動かなくなっているらしいので,静的ARPエントリを追加するなら最初からこっちを使うのがよさそうです(我ながら1回目はどうやって登録したんだろう……)。

登録したらpingのメッセージが「宛先ホストに到達できません」から「要求がタイムアウトしました」に変わり(デスクトップ側のファイアウォールでICMP拒否しているので正常),RustDeskの接続も復活しました。ひとまずめでたし。

ただ,この時点ではそもそもなぜ動的なARP解決が失敗してたのかまでは分かっておらず,「静的に登録したら直った」というところまでしか確認できていませんでした。

根本原因の調査

とはいえ,端末やルータを再起動してIPが変わったらまたARPエントリの登録をやり直さないといけない(1敗)とか考えると,やっぱり根本的な原因を究明して安定的な恒久措置を講じたいので,この記事を書くにあたって,Claude Codeの力を借りながら「そもそもなぜARP解決が失敗していたのか」を改めて調べ直すことにしました(netshコマンドいちいち覚えられない)。

ARP解決が失敗する原因の候補を洗い出してもらい,一つずつ潰していきます。

  • クライアント分離(APアイソレーション): 無線LANのAP(アクセスポイント)には,同じAPに繋がった端末同士のレイヤー2通信を遮断する「クライアント分離」という機能があります(公衆Wi-Fiなどのセキュリティ対策としてよく使われる)。これが有効だと,同じWi-Fi上にいてもARP要求・応答がそもそも端末間を行き来できません。が,LAN内のARPテーブル未登録なデバイスにpingを打つと普通に成功したので,これは該当せず。
  • ARPオフロード: 本来ホストがスリープ状態のときに,NIC側がホストの代わりにARP要求へ応答してくれる低消費電力機能です(へ~)。スリープ復帰後にこの機能が正しく引き継がれず,ARP解決に失敗する原因になることがあると言われています。デバイスマネージャーでネットワークアダプタの詳細設定を確認しましたが,最初から無効になっていました。そもそもデスクトップは常時起動してるからあんま関係なさそう。
  • VPN: TailscaleのようなVPNクライアントは,仮想ネットワークアダプタを追加してルーティングテーブルを書き換えることがあります。これが有効だと,本来物理LAN経由で届くはずの通信が仮想アダプタ側に迂回し,物理NIC側でARP解決ができなくなる可能性があります。今回の場合,接続失敗時にVPNは起動していませんでした。

最後に残ったのが,デスクトップ側のWi-Fiアダプタの「Power Saving」設定でした。この機能が有効だと,無線チップが間欠的にスリープ(Doze)状態に入り,その間に届いた入力フレーム(ARP要求を含む)を取りこぼすことがあります。デバイスマネージャーで確認すると「Auto」になっていました。

これを「無効」に変更してからpingを打つと,静的エントリを登録しなくても結果が「宛先ホストに到達できません」から「要求がタイムアウトしました」に変わり,arp -aでも対象PCのIPアドレスが正しく解決されるようになりました。もちろんRustDeskも問題なく繋がりました。

常時起動のデスクトップでWi-Fiの省電力モードをONにする意味

Power Saving機能はそもそも「バッテリー駆動時に無線チップを間欠的にスリープさせて消費電力を抑える」ためのものなんですが,主目的であるバッテリー延命効果はバッテリーを持たないデスクトップには関係ありません。ネットワーク機器のようにポートがたくさんある場合は発熱を抑えるために省電力モードを使ったりするらしいですが,デスクトップ1台分のWi-Fiアダプタ程度は気にするレベルではないかと。であれば,パケット取りこぼしのリスクの方が大きいと思うので,常時起動のデスクトップ用途のWi-FiアダプタのPower Savingは,素直に無効(最大パフォーマンス)にしておくのが良さそうです。

まとめ

ただのリモートデスクトップのバグかと思ったら,思いの外奥が深かったですね。ネットワークの話も割と好きなので面白かったです。それでは。

参考