🪢

ssh-obi を公開しました ― SSH の切断やスリープを越えてリモートシェルを生き続けさせる軽量ツール

に公開
2

TL;DR

ssh-obi v0.1.0 を公開しました。SSH 接続が切れても、ノート PC をスリープしても、Wi-Fi と LTE を行き来しても、リモートシェルを生かし続ける小さな Rust 製ツールです。

普段の SSH 設定 (鍵、ProxyJump~/.ssh/config など) をそのまま使えます。専用のポートも、UDP も、setuid バイナリも、システム全体のデーモンも必要ありません。

Windows (クライアントのみ):

powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://obi.menhera.org/bootstrap.ps1 | iex"

または Rust ツールチェインがあれば:

cargo install ssh-obi

Unix 系 (クライアント+サーバー):

wget -O - https://obi.menhera.org/bootstrap.sh | sh -s -- --install

または:

cargo install --features=server-bin ssh-obi

接続は普段の ssh と変わりません:

ssh-obi user@example.com

リモート側のサーバーコンポーネントは、初回接続時に確認のうえ自動で ~/.ssh-obi/bin にインストールされます。root 権限は不要です。


ssh-obi とは

ssh-obi は、SSH 上のインタラクティブシェルにユーザー単位の永続化レイヤを被せるツールです。名前の obi (帯) は、着物を結ぶあの帯から来ています。リモートシェルとローカルターミナルを切れない結び目で繋いでおく、というイメージです。

設計方針はあくまで「素の SSH のように振る舞うこと」です。

  • 普段使っている宛先名・鍵・jump host・SSH config がそのまま使える
  • ローカルターミナルのスクロールバック・検索・選択・コピペが普段どおり動く
  • ネットワークが切れても、リモートシェルは生きていて、再接続すれば同じセッションに戻れる
  • 同じリモートユーザー上で複数のセッションを並行して持てる
  • インストールはユーザー単位。root デーモンも独自ポートも不要

意図的に、ターミナルウィンドウマネージャではありません。ペインもタブもインバンドのエスケープコマンドも実装しません。複数ウィンドウが必要なら tmux などをリモートシェル内で動かしてください。ssh-obi がその tmux を切断越しに生かし、tmux がペインを提供する、という分業です。

なぜ作ったのか

SSH でインタラクティブな作業をしていると、こんな経験は誰しもあるはずです。

  • 長い cargo buildmake、学習ジョブ、巨大な rsync、DB マイグレーション ― 終わるまで張り付いて見守るか、nohup / screen / tmux で防衛的に包むしかない
  • ノート PC をスリープして戻ってくると、SSH が半死状態で結局繋ぎ直し
  • テザリングが Wi-Fi と LTE を切り替える瞬間、SSH が 2 分くらい無言で固まる
  • リモートで開きっぱなしのエディタを、別のマシンに自然に持ち運ぶ手段がない

これらに対する既存解はそれぞれに良さがあります。

  • tmux / screen (リモート側) は優秀ですが、別ワークフローです。「長そうな作業の前に tmux に attach する」という意識的な習慣が必要で、キーバインドはアプリケーションや互いと衝突しがちです。
  • mosh はネットワーク移動の問題を見事に解決しますが、ターミナル画面の所有権を奪います。ローカルターミナルのスクロールバックがもはや「自分が見たもの」のソースオブトゥルースではなくなり、検索やコピペの挙動も変わります。UDP かつ非標準ポートレンジを使うため、ファイアウォールや踏み台サーバーを越えるのも面倒です。
  • Eternal Terminal (et) はシェルを生かし続けますが、サーバー側に管理者権限でインストールするシステム全体のデーモンを前提にしています。

ssh-obi はあえて狭い解です。「SSH 切断を越えてシェルとの間でバイトを流し続ける」、それだけをやります。スコープ外 (ペイン、タブ、画面再構築、別トランスポート) は他のツールに任せます。

既存ツールとの比較

機能 ssh-obi mosh Eternal Terminal tmux/screen 単体
ネットワーク切断を生き残る SSH リトライと組み合わせれば
ローカル端末がスクロールバックを所有 ❌ (mosh が画面を再描画)
素の SSH のみ (追加ポート/UDP 不要) ❌ (UDP・カスタムポートレンジ) ❌ (独自 TCP ポート)
ユーザー単位インストール (管理者権限不要) だいたい ✅ ❌ (システムサービス)
ウィンドウ/ペイン管理が不要 ✅ (tmux と併用)
1 ユーザーあたり複数の永続セッション

トレードオフもあります。ssh-obi は画面を所有しないため、再接続時に容量制限のあるバッファをリプレイする際、切断直前にすでに表示されていた出力が重複して再描画されることがあります。これは許容しています ― ローカルのスクロールバックには元のコピーがすでにあり、重複したバイトは流れていくだけです。代替案 (mosh 風の画面再構築) も検討しましたが、ネイティブのスクロールバックを失うほうが、たまの数行の重複を許容するより悪いトレードだと判断しました。

クイックスタート

クライアントをローカルにインストール (上記 TL;DR のワンライナー参照)。

接続:

ssh-obi user@example.com

初回接続時、クライアントが小さなサーバーコンポーネントを ~/.ssh-obi/bin に入れていいか確認します。root 権限は不要、システム全体には何も触れません。

以降の ssh-obi 起動時の挙動はこうなります。

  • 空きセッションなし → 新規セッションを作って attach
  • 空きセッションがちょうど 1 つ → 自動で attach
  • 空きセッションが複数 → ローカルでピッカーが出て、初期化時刻、最終 detach 時刻、現在実行中のコマンド (best-effort 推定: bashvim notes.mdcargo watch など) を表示

明示的に新規作成する、一覧する、特定セッションに attach する、attach 中のクライアントを蹴る:

ssh-obi --new user@example.com
ssh-obi --list user@example.com
ssh-obi --session abc123 user@example.com
ssh-obi --detach --session abc123 user@example.com

リモートシェル内から、シェルを殺さずクリーンに detach する:

ssh-obi-server --detach

これは「クライアントだけ落として、シェルは生かしておけ」という指示です。一方、ノート PC の蓋を閉じる、Wi-Fi が切れる、ローカル SSH プロセスを kill するといったケースはクライアントから見れば曖昧な切断なので、自動で再接続を試みます。

スコープと非ゴール

これらは「いずれやる」ではなく「やらない」と決めている設計コミットメントです。

  • ウィンドウ/ペイン管理はしない。ローカル TTY とリモート PTY の 1:1 フォワーディングのみ。多重化が欲しければ tmux を併用してください。
  • インバンドのエスケープシーケンスを実装しない。入力したバイトはそのままリモートシェルに届きます。Detach は魔法のキーコンボではなく ssh-obi-server --detach という明示的なコマンドで行います。
  • 画面状態のレプリケータではない。再接続時にリプレイするのは有界の最近出力バッファだけです。それより古い履歴はローカルターミナルのスクロールバックの仕事 ― それが本来あるべき場所です。
  • Windows はクライアント専用。リモートサーバーは Unix 系のみ。Windows サーバーを出す予定はありません。

プラットフォームサポート

ローカルクライアント: Linux、macOS、Windows x86_64、および FreeBSD/NetBSD/illumos (リリースアーカイブが公開されている範囲)。クライアントは動作する ssh バイナリを必要とします。ssh-obi は SSH を再実装していません。

リモートサーバー: Linux、macOS、FreeBSD、NetBSD、illumos。systemd 系ディストリビューションをサポートしますが、systemd は前提ではありません ― デーモンは普通のユーザープロセスで、システムサービスマネージャに依存しません。

リリースアーカイブは https://obi.menhera.org/ から以下のターゲット向けに配布しています:

  • release-x86_64-unknown-linux-musl.tar.gz
  • release-aarch64-unknown-linux-musl.tar.gz
  • release-riscv64gc-unknown-linux-musl.tar.gz
  • release-powerpc64le-unknown-linux-musl.tar.gz
  • release-s390x-unknown-linux-musl.tar.gz
  • release-x86_64-apple-darwin.tar.gz
  • release-aarch64-apple-darwin.tar.gz
  • release-x86_64-unknown-freebsd.tar.gz
  • release-x86_64-unknown-netbsd.tar.gz
  • release-x86_64-unknown-illumos.tar.gz
  • release-x86_64-pc-windows-msvc.tar.gz (クライアント専用)

セキュリティモデルについて

ssh-obi は SSH のセキュリティモデルを変更しません。トランスポートはお手元の ssh バイナリがネゴシエートするものそのままです ― 同じ鍵、同じ known_hosts、同じ ProxyJump、同じ MFA プロンプト。永続サーバーは権限のないリモートユーザーとして動作し、/tmp/ssh-obi-<uid>/ 配下の UNIX ドメインソケット (mode 0700、再利用時に所有権チェック、NFS/SMB 上では起動拒否) でのみ通信を受け付け、SSH 越しにしか話しかけられません。

setuid バイナリなし、ユーザー間の状態共有なし、リモートに新たな TCP/UDP ポートを開かない、システムサービスとして管理者の監査対象になることもなし。リモートアカウントが侵害された場合に攻撃者が得るアクセスは、素の ssh 経由で得られるものと同じです ― ssh-obi は被害範囲を広げません。

v0.1.0 の自動インストールブートストラップは、追加の署名検証なしに HTTPS でリリースアーカイブをダウンロードします。MVP としては HTTPS を信頼することにしており、1.0 までに署名検証を追加する予定です。今すぐ強い保証が欲しい方は、リモートで cargo install ssh-obi --features=server-bin を使えば crates.io のサプライチェーン経由になります。

ステータス

v0.1.0 が初の公開リリースです。動きますし、ドキュメントもありますが、まだ若いです。CLI のサーフェス (ssh-obissh-obi-server) はユーザー向けのコントラクトとして安定を保つつもりです。クライアント・サーバー間のワイヤプロトコルは、バージョン番号のバンプではなくケイパビリティネゴシエーションで前方互換を取ります ― 一度出したケイパビリティのメッセージ形式は永久に固定し、新機能は新しいケイパビリティ文字列として追加します。ライブラリ API (ssh_obi を crate 依存として使う場合) は未安定です。

バグ報告・フィードバック・プルリクエストは https://github.com/menhera-org/ssh-obi で歓迎します。

なぜ日本の非営利団体がこれを公開しているのか

Menhera.org (一般社団法人生活情報基盤研究機構, Human-life Information Platforms Institute) は、IT システム・インフラ・プロトコルなどを設計することで個人により多くの自由を、というミッションを掲げる、日本で法人化された非営利団体です。インターネットの研究用自律システムとして AS63806 を運用しており、プライバシーやプロトコル領域の仕事に注力しています。

私たちの日々の運用は、複数マシンにまたがる長時間タスクを SSH 越しに対話的に動かすことが中心です。シェル永続化の既存オプションには、それぞれ私たちが払い続けたくないトレードオフがありました ― ターミナル画面を奪うか、管理者によるシステム全体のインストールを要求するか、あるいは普段の SSH や踏み台と同じファイアウォールを通らない別トランスポートを導入するか。だから自分たちが欲しかったツールを作りました。同じものを欲しがっていた人がほかにもいるだろうと思い、公開します。

ソフトウェアは利用者の選択により Apache-2.0 または MPL-2.0 のデュアルライセンスです。自由に使い、フォークし、ディストリビューションでパッケージし、再配布してください。

ライセンス

利用者の選択により以下のいずれか:

  • Apache License, Version 2.0
  • Mozilla Public License, Version 2.0

リンク


一般社団法人生活情報基盤研究機構は、日本で法人化された非営利団体です (法人番号: 7050005013201)。本ソフトウェアは当法人のミッションに沿った公益として提供されています。明示・黙示を問わず保証はありません。利用は各自の判断でお願いします。


この記事の初稿は Claude Opus 4.7 (LLM) によって作成され、その後人間による大幅なレビューと修正を経ています。内容についての責任は著者にあります。

2
一般社団法人生活情報基盤研究機構

Discussion

ログインするとコメントできます
2