zudo-paper

MoshiでWindowsに接続してClaude Codeする

Author: Takazudo | 作成: 2026/02/25

概要

iOSアプリのMoshiを使って、Windows上のWSL2Mosh接続し、iPhoneからClaude Codeを操作できるようにした。SSHだとネットワークが切れるとセッションが死ぬが、Moshなら接続が維持される。セットアップに注意点がいくつかあったので、そのまとめ。

Moshiの公式サイト

背景

自分はWindowsマシンを個人の開発サーバーとして使い始めている。特に最近Claude Codeをよく使うようになり、iPhoneからもターミナルを操作したいと考えた。

普通のSSH接続だと、Wi-Fiの切り替え、スリープ、移動中のネットワーク変動などで接続が切れる。接続が切れるとセッションごと消える。Claude Codeで長時間のタスクを走らせている最中にこれが起きると困る。

実際にSSHサーバーをセットアップして電車の中から使ってみたが、Xやinstagramを見てから戻ると接続が切れている。Claude Codeに大きなタスクを投げても、ちょっとアプリを切り替えただけですぐ失われてしまう。

そこでMoshiというiOSアプリに出会った。Moshプロトコルによるネットワーク耐障害性のある接続ができるアプリで、これが解決策になった。

Moshiとは

MoshiはiOS向けのターミナルアプリ。AIコーディングエージェント(Claude Codeなど)をモバイルから使うためのターミナルとして設計されている。

主な特徴は以下。

  • Moshプロトコルによるネットワーク耐障害性(Wi-Fi切替、スリープ、移動中でもセッション維持)
  • Face IDでSSHキーを保護
  • tmuxのネイティブ統合
  • タスク完了時の通知
  • Nord、Dracula、Solarizedなどのテーマ
  • Ctrl、Esc、矢印キー付きの専用キーボード
  • App Storeで4.9/5の評価、無料

WSLとWSL2の違い

まずWSLとWSL2の違いを整理しておく。名前が似ているが、内部のアーキテクチャはまったく別物。

WSL1WSL2
カーネル変換レイヤー(LinuxのシステムコールをWindows NTカーネルに変換)本物のLinuxカーネル(軽量VM上で動作)
ファイルI/OWindowsファイル(/mnt/c/)が高速Linuxファイル(~/)が高速、/mnt/c/は低速
ネットワークWindowsのネットワークスタックを直接共有独自の仮想ネットワーク(デフォルトはNAT)
互換性一部のLinuxツールが動かない完全なLinux互換

WSL2はWSL1の上に構築されたものではない。同じ「WindowsでLinuxを動かす」というコンセプトに対して、Microsoftがアプローチを置き換えたもの。WSL2が現在のデフォルトで、今「WSL」と言えばほぼWSL2を指す。

この記事で重要なのはネットワークの違い。WSL1はWindowsのネットワークをそのまま共有していたが、WSL2は軽量VM内で動くため、独自のIPアドレスを持つ。この違いがMoshのセットアップを複雑にしている。

WSL2のネットワーク構造

WSL2のネットワーク構造を理解しないと、なぜ単純にSSH接続しただけではmosh-serverが動かないのかがわからない。

デフォルトの構成(NATモード)

iPhoneやMacからWindowsのLAN IPに接続すると、Windows OpenSSH(Port 22)が応答する。ここで開くのはWindowsのシェル(PowerShellやCMD)。mosh-serverはWSL2の中にインストールされているので、Windowsのシェルからは見つからない。

さらにWSL2はデフォルトでNATの内部にいて、独自のIPアドレス(172.18.x.xなど)を持っている。外部からWSL2に直接アクセスするにはポートフォワーディングが必要だが、MoshはUDPを使うため、UDPのポートフォワーディングが面倒になる。

正しい接続構成(ミラーモード)

WSL2の.wslconfignetworkingMode=mirroredを設定すると、WSL2がWindowsと同じIPアドレスを共有する。これにより、外部からWSL2内のサービスに直接アクセスできるようになる。

WSL2内にopenssh-server(Port 2222)を設置し、そこにSSH接続する。Windows OpenSSH(Port 22)とは別のポートを使う。SSH経由でmosh-serverが起動し、以降はUDPで通信する。

Windows OpenSSHではダメなのか

Windows OpenSSH(Port 22)はデフォルトでWindowsのシェル(PowerShell/CMD)を開く。mosh-serverはWSL2内のLinuxバイナリなので、Windowsのシェルからは見つからない。これが「Failed to start Mosh on server」エラーの原因。

別のアプローチとして、Windows OpenSSHのデフォルトシェルをWSL2に変更する方法もある。PowerShell(管理者)で以下を実行する。

New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\wsl.exe" -PropertyType String -Force

こうするとWindows OpenSSH経由でもWSL2のシェルが開くので、mosh-serverが見つかる。WSL2内に別途openssh-serverをインストールする必要がなくなる。

ただし、この方法はそのWindowsマシンへの全SSH接続のデフォルトシェルが変わる。PowerShellでSSHしたい場合に不便になるので、WSL2専用にSSHを使う場合向け。この記事ではWSL2内にopenssh-server(Port 2222)を別途設置する方法を採用している。

Moshの通信フロー

MoshはSSHを最初の認証に1回だけ使う。mosh-serverが起動したらSSH接続は切断され、以降はクライアントとmosh-serverがUDPで直接通信する。このUDP通信がネットワーク変動に強い。

セットアップ手順

前提条件

  • Windows + WSL2(Ubuntu 24.04)
  • WSL2内にmoshがインストール済み(sudo apt install mosh
  • Windows OpenSSHが動作中(Port 22)
  • iOSにMoshiアプリをインストール済み

Step 1: WSL2のネットワークをミラーモードにする

Windows側のC:\Users\takaz\.wslconfigに以下を作成する。

[wsl2]
networkingMode=mirrored

これによりWSL2がWindowsと同じIPアドレスを共有する。デフォルトのNATモードではUDPポートフォワーディングが困難なため、これが最もシンプルな解決策。

Step 2: WSL2にopenssh-serverをインストール

sudo apt update && sudo apt install -y openssh-server

Windows OpenSSHが既にPort 22を使用しているため、WSL2のSSHはPort 2222に変更する。

sudo sed -i 's/^#Port 22$/Port 2222/' /etc/ssh/sshd_config

SSHサーバーを起動する。

sudo service ssh start

WSL2はデフォルトではサービスを再起動後に維持しない。wsl --shutdownやPC再起動のたびにsshdが止まる。自動起動させるには、Step 1の.wslconfigとは別に、WSL2内の/etc/wsl.confに以下を追加する。

[boot]
command=service ssh start

Step 3: SSH公開鍵の設定

Windows OpenSSH用の公開鍵はWSL2には自動的に共有されない。Windows側の管理者用authorized_keysからWSL2にコピーする。

cp /mnt/c/ProgramData/ssh/administrators_authorized_keys ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Step 4: Windowsファイアウォール設定

PowerShell(管理者)で以下を実行する。

New-NetFirewallRule -DisplayName "WSL2 SSH" -Direction Inbound -Protocol TCP -LocalPort 2222 -Action Allow
New-NetFirewallRule -DisplayName "Mosh UDP range" -Direction Inbound -Protocol UDP -LocalPort 60000-60010 -Action Allow

TCPの2222(SSH)とUDPの60000-60010(Mosh)の2つを開ける必要がある。

Step 5: WSLを再起動

PowerShellで以下を実行する。

wsl --shutdown

その後WSLターミナルを再度開く。ミラーモードの設定を反映するには再起動が必要。

Step 6: Moshiアプリの設定

Moshiアプリで以下を設定する。

  • Host: WindowsマシンのLAN IP
  • SSH Port: 2222
  • Username: takazudo(WSL2のユーザー名)
  • Auth: SSHキー
  • Mosh port range: 60000-60010

これで接続できた。後述のtmuxを使えば切れても途中からまた再開される。

iPhoneのMoshiアプリからWSL2上のClaude Codeに接続した様子

トラブルシューティング

セットアップ中に遭遇したエラーと対処法をまとめておく。

"Failed to start Mosh on server"

SSH接続がWindows OpenSSH(Port 22)に向いていたのが原因。Windowsのシェルにはmosh-serverが存在しないので、mosh-serverの起動に失敗する。

解決策: WSL2内にopenssh-server(Port 2222)を設置し、そちらに接続する。

"Authentication failed"

WSL2の~/.ssh/authorized_keysが存在しなかったのが原因。Windows OpenSSH用の鍵とWSL2の鍵は別管理になっている。Windowsに公開鍵を登録してあっても、WSL2には自動で共有されない。

解決策: /mnt/c/ProgramData/ssh/administrators_authorized_keysからWSL2にコピーする。

Mac moshで "Address already in use"

MoshのUDPポートは1セッション1ポート。iOSのMoshiセッションが60001を使用中だと、Macから同じポートは使えない。

解決策: ポートレンジ(60000-60010)を使い、自動で空きポートを選択させる。--portを指定しなければ自動選択される。

Macからの接続

Macからも同じWSL2にMoshで接続できる。

brew install mosh  # 未インストールの場合
mosh --ssh="ssh -p 2222" takazudo@<WindowsのLAN IP>

--portを省略すれば60000-61000の空きポートを自動選択する。

tmuxとの組み合わせ

なぜtmuxが必要か

Moshとtmuxは守っている範囲が違う。

  • Moshは「接続」を維持する。ネットワーク変更、スリープに耐える。ただし「プロセス」は維持しない。mosh-serverが終了すればセッションは消える
  • tmuxは「セッション」を維持する。切断しても、再起動しても、tmuxセッション内のプロセスは生き続ける

Mosh + tmuxを組み合わせると、ネットワークの切断にも、mosh-serverの再起動にも耐えられる。

セッション共有

tmuxセッションは同一マシン上の全接続で共有可能。iPhoneのMoshiとMacのmoshから同じtmuxセッションにattachすると、リアルタイムで同じ画面を見ることができる。スクリーンシェアのような感じ。

別々のワークスペースが欲しい場合は別セッションを作成する。

tmux new -s ios
tmux new -s mac

Mac、iPhone、iPadなど複数デバイスからtmuxセッションを共有できる。同じセッションにattachすれば同じ画面、別セッションを使えば別作業。

Moshの仕組み Q&A

MoshはSSHの上に乗る技術?

いいえ。MoshはSSHを最初の認証時に1回だけ使う。その後SSHは切断され、実際のセッションはUDPで通信する。SSHの上位レイヤーではなく、認証後は完全に別のプロトコルになる。

SSHとの違い

SSH(TCP)は順序付き・信頼性のあるストリーム。パケットロスが発生するとすべてが再送待ちになる。接続が断たれるとセッションが死亡する。

Mosh(UDP)はステートレスなデータグラム。各パケットが現在のスクリーン状態を含んでいる。パケットロスが起きても、次のパケットが最新の状態を持ってくる。

Moshのほうがデータ量が多い?

逆。MoshはSSHよりも効率的。

SSHはすべてのバイトを順番に送信する。10,000行のログ出力があれば全行送信される。途中でパケットロスが発生するとストールする。

Moshは最新のスクリーン状態のみ送信する。中間フレームはスキップする。画面に表示されている内容だけを同期すればいいので、大量のログ出力中でも帯域を圧迫しない。

ただしスクロールバックはMosh単体では不可能。中間のデータをスキップしているため。ここでtmuxが活躍する。tmuxがサーバー側で全出力をキャプチャしているので、tmuxのスクロール(Ctrl+b [)を使えば過去の出力を遡れる。

tmuxのスクロールはMosh経由で動く?

動く。tmuxはサーバー側で完全に動作する。tmuxでスクロール(Ctrl+b [)すると、tmuxが画面表示を更新し、Moshはその画面状態をクライアントに同期するだけ。Moshはあくまでスクリーンの差分を送るトランスポート層であり、tmuxは端末の中で動くアプリケーション。両者は独立して動いているが、組み合わせるとうまくいく。

まとめ

Moshi + Mosh + tmuxの組み合わせにより、iPhoneからWindows WSL2上のClaude Codeを操作できる環境ができた。ネットワークの切断を気にせず、移動中でもAIエージェントと対話できる。Mac、iPhone、iPadなど複数デバイスからtmuxセッションを共有できるのも良い。

セットアップの手順は多いが、WSL2のネットワーク構造さえ理解すれば一つ一つは難しくない。注意が必要なのはWSL2のミラーモード設定と、Windows OpenSSH / WSL2 openssh-serverの使い分け。