Dance with Agents

moshという、切れない接続

SSHで繋いでいると、こうなる

別のパソコンにSSHで接続して作業していると、だいたい次の3つに悩まされます。

  1. 移動すると切れる。 家のWi-Fiから外に出た瞬間、接続が死にます。カフェのWi-Fiに繋ぎ直したら、また最初からログインし直しです
  2. 電波が悪いと固まる。 地下に入って一瞬圏外になっただけで、接続が戻ってこない。復帰を待つより、閉じて繋ぎ直した方が早い
  3. 打った文字が、遅れて表示される。 これが地味にきつい。回線が遠いと、キーを押してから画面に文字が表示されるまでにワンテンポ空きます

3つ目は、慣れの問題ではありません。SSHは、打った文字を一度サーバまで送って、サーバからの返事を受け取ってから画面に表示するという仕組みだからです。公式サイトの言葉を借りれば「SSHはあなた自身のタイピングを表示する前に、サーバからの返事を待ちます」。物理的に遠ければ、その分だけ遅れます。

moshは、この3つをまとめて解決する

mosh(モッシュ/mobile shellの略)は、SSHの代わりに使う接続の道具です。上の3つに、それぞれこう答えます。

困りごと moshの答え
移動すると切れる 接続が自動的に付いてくる。ネットワークが変わっても繋がったまま
電波が悪いと固まる 圏外になっても接続は生きていて、電波が戻れば何事もなかったように再開する
打った文字が遅れる 打った文字をその場で画面に表示する。サーバの返事を待たない

とくに大きいのが3つ目です。 サイト管理人も外出先からMac miniに繋いで作業しますが、mosh越しだと「遠くのパソコンを触っている」という感覚がかなり薄れます。

使い方は、sshとほぼ同じ

mosh onamae@example.com

sshをmoshに置き換えるだけです。ユーザー名が同じなら省略もできます。

mosh example.com

~/.ssh/configに書いた設定は、そのまま効きます。 moshはログインの入口だけSSHを使う仕組みなので、configに短い名前を登録してあれば、その名前で呼べます。

mosh mymac

configの書き方はSSHの肝:configの中身にあります。先にconfigを整えておくと、moshの側で何も設定しなくて済みます。

SSHのポート番号を変えている場合は、こう書きます。

mosh --ssh="ssh -p 2222" example.com

aliasにすると、ぐっと楽になります

もう一段短くできます。コマンド全体にaliasで短い呼び名をつけてしまう方法です。

alias sshmini="mosh mymac"

サイト管理人はsshminiという一言で母艦のMac miniに繋いでいます。sshではなくmoshを呼ぶようにしてあるので、打つのは同じ一言のまま、中身だけがmoshになっています。

configとaliasは、短くするものが違います。

何を短くするか 書く場所
~/.ssh/config 接続先(アドレス・ユーザー名・鍵) ~/.ssh/config
alias コマンド全体(mosh本体やオプションごと) ~/.zshrcなど

moshはとくにaliasの効きがいい道具です。 ポート指定や、後述のtmux起動まで足すと、コマンドがどんどん長くなるからです。

alias sshmini="mosh mymac -- tmux attach"

ここまで書いておけば、sshminiの一言で「繋いで、前の作業の続きから」まで戻れます。毎回打つのは6文字です。

aliasの書き方と、~/.zshrcへの登録のしかたはaliasという救世主にまとめてあります。

インストール方法(両側に必要です)

ここが最初の注意点。moshは、接続する側とされる側の両方にインストールする必要があります。 手元のパソコンにだけインストールしても繋がりません。

Macならどちらも同じです。

brew install mosh

接続先がLinuxのサーバなら、そのサーバにもmoshをインストールします(aptやdnfなどで導入できます)。

iPhone・iPadの場合は、アプリが兼ねます

スマホやタブレットには、moshを単体でインストールする手順がありません。mosh対応のターミナルアプリをインストールすれば、その中にmoshのクライアントが含まれています。 後述のMT — Mosh Terminalがこれにあたります。作者ご本人もじゃが畑でこう書かれています。

そのMoshを、MTではRustでゼロから独自実装しています。一般的なアプリは既存のmosh-clientをそのまま組み込んでいますが、MTでは通信プロトコル(SSP:State Synchronization Protocol)を一から書き起こしました。

ただし「両側に必要」であること自体は変わりません。 繋ぎ先のパソコンには、やはりmoshが要ります。同じページにも、はっきりこう書かれています。

Moshはサーバー側にmosh-serverのインストールが必要。これはMoshプロトコル自体の制約です。SSH接続だけなら追加設定は不要ですが、Moshの恩恵を受けるにはサーバー側の準備が必要になります。

つまりiPhone側はアプリをインストールするだけ、繋ぎ先のパソコン側はbrew install mosh、という分担になります。

Windowsから使いたい場合

Windows向けのネイティブ版は、現時点で存在しません。 公式サイトにも「現時点でWindows向けのネイティブなmosh実行ファイルはありません」と明記されています。

公式が案内しているのはChrome拡張版ですが、Chromeアプリという仕組み自体がすでに終了しているので、これは実質的に選べません。

WindowsからmoshしたいならWSL(Windowsの中でLinuxを動かす仕組み)をインストールすることになります。ただ、tmuxの記事でも書いたとおり、WSLをインストールする手間に見合うかどうかは、moshをどれだけ使うかで決まります。 WindowsのSSHはそのままでも十分使えるので、繋ぐ頻度が低いうちは無理に揃える必要はありません。

ポートの話——そして、Tailscaleを強くすすめる理由

moshは、まずSSHでログインしたあと、60000番から61000番のあたりのUDPポートを1つ使って通信します。自宅のパソコンに外から繋ぐ設定をしている場合、SSHの22番だけでなく、この範囲も通してやる必要があります。

ここで手が止まる人は多いと思います。 ルーターの設定画面を開いて、ポート開放(ポートフォワーディング)を設定する——という作業だからです。しかも自宅の回線には固定のアドレスが割り当てられていないことが多く、アドレスが変わるたびに繋がらなくなります。

そして何より、これはセキュリティ上あまり気持ちのいい設定ではありません。 22番を世界に向けて開けておくと、機械的なログイン試行が飛んできます。鍵を使っていれば簡単には破られませんが、そもそも開けないで済むならそのほうがいいのは間違いありません。

Tailscaleと組み合わせてください

というわけで、このサイトとしては、moshはTailscaleと一緒に使うことを強くおすすめします。 管理人の場合、順番はTailscaleが先で、moshを足したのはそのあとでした。そのおかげで、ここまで書いたポート開放の話には一度も出会っていません。 逆にすると、要らなかったはずの設定と格闘することになります。

分かりやすい到達点を挙げておきます。ベッドに寝転がったまま、スマホから自宅のパソコンにつないで開発が続けられます。 机に戻らなくていい、パソコンを開かなくていい。エージェントは指示さえ出せば手を動かしてくれるので、「寝ながら開発」が冗談ではなく成立します。 そこまで持っていくための土台がTailscaleです。

Tailscaleは、自分の持っているデバイス同士だけを、プライベートな回線でつないでしまう道具です。これをインストールすると、こうなります。

ポート開放でやっていたこと Tailscaleだと
ルーターで22番を開ける 要らない
moshのUDP 60000〜61000番も開ける 要らない
変わるアドレスを追いかける デバイスごとの固定の名前で呼べる
SSHを世界に晒す 自分のデバイス以外からは、そもそも見えない

つまり、mosh mymacが家でも、外出先でも、まったく同じように通ります。 繋ぎ方を場所によって変えなくていい、というのが実際に使ってみると一番ありがたいところです。

料金も障害になりません。公式の料金ページに、個人向けの「Personal」プランが「$0 Free forever」として載っていて、ユーザーは6人まで、デバイス数は無制限とされています。自分の持ち物をつなぐぶんには、まず足ります。

moshより先にTailscaleをインストールする、くらいの順番でちょうどいいと思います。ポート開放と格闘する時間が、まるごと要らなくなります。

Tailscaleのインストール方法と、別の使い道(作りかけのサイトをスマホから見る)はそちらの記事にまとめてあります。

弱点:スクロールバックがない

万能ではありません。moshは「今画面に見えている分」だけを同期します。 公式にも「moshは端末の可視状態のみを同期します」と書かれています。

つまり、マウスでスクロールして前の出力を遡る、ということができません。 エージェントの長い出力を上に戻って読み返したい、という場面では、これが不便になります。

解決策も公式が案内していて、接続先でtmux(またはscreen)を使うことです。tmuxの中でスクロールすれば、mosh越しでも遡れます。

mosh mymac -- tmux attach

こう書けば、繋いだ瞬間にtmuxの中につながった状態になります。moshとtmuxは、組み合わせて初めて完成する道具だと思っておくとよいです。tmuxの方はtmux――接続が切れても作業を続けられる道具からどうぞ。

実体験:iPhoneから濁点が顔文字になることが多い

ここからは、iPhoneから使う場合の各論です。日本語で使う人には、これが一番大きいかもしれません。

iPhoneのSSHアプリから繋いで日本語を打つと、濁点(゛)を打ったつもりが^_^のような文字になってしまう、という現象に長く悩まされました。毎回ではありません。ちゃんと濁点として反映されることもあるのですが、しばしば顔文字に化けます。 「が」と打ちたいだけなのに入力が崩れるので、日本語で指示を出すのが現実的でなくなります。

管理人はSSHアプリをいくつも試しましたが、どれでも起きました。 tmux側でescape-timeを縮める設定も加えてみましたが、これでも直りませんでした。

収まったのは、次の節で紹介するMT — Mosh Terminalに移ってからです。 それ以降、この現象は起きていません。

なぜ顔文字になるのか

現象の入り口は、iOSの日本語かな入力(テンキー配列)の左下にあるキーです。あれは状況によって役割が変わります。

  • 入力中の文字があるとき → 小゛゜(濁点・半濁点・小文字)
  • 何も入力されていないとき → ^_^(顔文字)

つまり「が」を打つ操作は、「か」が変換前の入力中の文字としてiOS側に見えていることを前提に成り立っています。この状態が崩れると、同じキーが顔文字として働きます。毎回ではなく「しばしば」なのも、崩れるかどうかが一定でないから、と考えると筋は通ります。

何が解決をもたらしたのかは、切り分けていません

MTに移ったとき、変わったものが2つありました。

  • アプリの日本語入力の実装 — MTは変換中の文字の状態を明示的に管理している、と作者が書いています(次の節に引用があります)
  • 接続がmoshになったこと — MTはmoshが前提のアプリです。moshは打った文字をその場で表示するので、SSHより遅延が少なくなります

この2つを別々に試したわけではないので、どちらがどれだけ寄与したのかは分かりません。 両方が寄与している可能性が高いと思っています。日本語入力の作り込みは作者が意図してやっている部分ですし、遅延が減ること自体も、入力中の状態がずれにくくなる方向に働くはずです。

言えるのは、mosh対応で、かつ日本語入力を作り込んであるアプリに替えたら収まった、というところまでです。

結論として

スマホからエージェントに日本語で指示を出したいなら、ターミナルアプリの選択がここで結果を分けます。 同じ症状に心当たりがあるなら、アプリを見直してみると早いかもしれません。

iPhoneから使うなら:MT — Mosh Terminal

アプリ選びについても書いておきます。管理人は無料・有料あわせて複数のターミナルアプリを試し、利用してきました。 そのうえで最終的に落ち着いたのがMT — Mosh Terminal(Jaga Studio)です。

App Storeのページによると、iOS 18.0以降に対応し、価格は無料(アプリ内課金「MT Pro」が¥2,000)。iPadやMac、Apple Visionにも対応しています。名前のとおりmoshが主役ですが、SSHにも対応しています。

前節の顔文字に悩まされることがなくなり、管理人はスマホではいつもこのMTで作業しています。 日本語入力をどう作り込んであるかは、作者ご本人がじゃが畑で詳しく書かれています。変換中の文字の扱い、JISキーボードの自動検出、tmuxのプレフィックスキーと日本語変換がぶつかる問題まで触れられているので、興味のある方はそちらをどうぞ。

無料で試せるので、試用をお勧めします。

それでも、iPhoneはバックグラウンドで切れます

ここまで持ち上げておいて言うのも何ですが、iPhoneでは他のアプリに切り替えたりロックしたりすると、程なくmoshの接続も切れます。 moshが弱いわけではなく、バックグラウンドに回ったアプリの通信をOS側が止めるという、iOS全般の制約によるものです。ターミナルアプリに限った話ではありません。

ただし、これはそこまで痛くありません。 tmuxを使っていれば、作業そのものは接続先のパソコン側で生き続けているからです。切れても、MTで繋ぎ直せば同じ場にすぐ戻れます。「接続が切れる」と「作業が消える」は別、というのが、ここでも支えになります。

体感としては、繋ぎ直しの手間がほぼゼロになる、というくらいの差です。ゼロにはなりませんが、フルでログインし直すのに比べれば誤差です。

いつインストールするか

外から自分のパソコンに繋ぐようになったらが目安です。自分の机の前で作業しているだけなら、moshの出番はありません。

逆に、外出先や別の部屋から繋ぐことが増えてきたら、真っ先に役立つ道具のひとつです。そのときはTailscaleを先にインストールしておくのがおすすめです。 順番を逆にすると、要らなかったはずのポート開放と格闘することになります。

長い接続コマンドはaliasで短くしてしまうと、さらに楽になります。

リモート開発環境の記事

リモート開発環境のページへ →