SSHler 注目

リモートファイルをSFTPで閲覧し、ブラウザ上でtmuxセッションにアクセスできるローカル専用Web UI。Vue 3 SPA、WebSocketターミナル、モバイルファースト入力バー、リモート側へのインストール不要。232テスト。

役割: メイン開発者 @ 個人プロジェクト
期間: 2025年4月

SSHler

リモートファイルを SFTP で閲覧し、ブラウザ上で tmux セッションにアクセスできるローカル専用 Web UI。エージェントもデーモンも、リモートホストへのインストールも不要。SSH 設定を指定するだけですぐに使えます。


なぜ SSHler?

複数のマシンがあります。ワークステーション、ホームサーバー、いくつかの VPS。常にマシン間を行き来しています;ターミナルを開き、プロジェクトディレクトリに移動し、ファイルを確認し、サービスを再起動する。ワークフローは反復的です:SSH 接続、cd で正しい場所に移動、tmux attach、作業、デタッチ、別のマシンに切り替え、繰り返し。

VS Code Remote は VS Code に住んでいるなら対応できます。でもフル IDE が不要な時もある;ターミナルでファイルをちょっと確認したいだけの時に。JuiceSSH はモバイルで優秀ですが Android 限定でファイルブラウジングができない。「フル IDE」と「生の SSH」の間に、きれいに埋めるものが何もありません。

SSHler はそのギャップに位置します。pip install 一発、コマンド一つでブラウザが開き、すべての SSH ホストが表示されます。ボックスをクリックし、ファイルを閲覧し、ターミナルを開く。ターミナルはリモートホスト上の tmux を WebSocket + xterm.js で橋渡し;ブラウザを閉じても、ページをリロードしても、ネットワークが途切れてもセッションは維持されます。

適している用途: マルチマシンワークフロー、実用的なターミナルでのモバイル SSH アクセス、ファイルシステムをマウントせずにリモートファイルを閲覧、複数のボックスで LLM エージェントを実行、「フル IDE」なしで「素早いアクセス」が欲しい場面。


クイックスタート

pip install sshler
sshler serve

ブラウザで http://127.0.0.1:8822/app/ が開きます。~/.ssh/config を自動的に読み取り、すべての Host エントリがボックスとして表示されます。


アーキテクチャ

ブラウザ (Vue 3 SPA)

  ├── REST API ──→ FastAPI ──→ asyncssh ──→ SFTP (ファイル操作)

  └── WebSocket ──→ FastAPI ──→ asyncssh ──→ tmux (ターミナル)

                              SSH コネクションプール
                              (ボックスごと、アイドルタイムアウト)

バックエンドは単一の FastAPI プロセス。ファイル操作は asyncssh の SFTP クライアントを経由。ターミナルセッションはリモートホストで tmux new -As <session> -c <dir> を開き、stdin/stdout を WebSocket で生バイトとしてパイプします。ローカルボックスは SSH をバイパス;サブプロセス tmux、直接ファイルシステムアクセス。


機能

ファイルブラウザ

プレビュー、編集、削除、アップロード、「ここでターミナルを開く」機能を備えた Vue ベースのファイルブラウザ:

  • ドラッグ&ドロップアップロード - 進捗インジケーター付き
  • 一括操作 - マルチセレクト(Shift+Click、Cmd/Ctrl+Click)
  • アーカイブサポート - コンテキストメニューから .tar.gz.zip の作成・展開
  • コンテンツ検索 - リモートファイルに対する grep、クリック可能な結果
  • インライン名前変更 (F2)、コンテキストメニュー、パンくずナビゲーション
  • ファイルプレビュー - CodeMirror、マークダウンレンダリング、行番号、ワードラップ切替
  • Git ブランチ表示 - パンくずバーに表示

ターミナル

リモートホスト上の tmux による WebSocket ターミナル:

  • マルチペインレイアウト - 水平、垂直、グリッドに分割
  • セッション永続化 - レイアウトを localStorage に保存、リロード時に復元
  • ボックス別テーマ - 環境ごとにターミナルを色分け(本番=赤、ステージング=緑)
  • コマンドスニペット - よく使うコマンドをボックスごとまたはグローバルに保存
  • ポートフォワーディング UI - ボックスごとの SSH トンネル管理を視覚的に操作
  • セッションスイッチャー - ボックスごとのアクティブ tmux セッション一覧
  • デスクトップ通知 - タブが非表示のときにベルと OSC 777 で通知

モバイルターミナル

モバイルキーボードで入力困難なキー用のカスタム入力バーを備えたタッチ最適化ターミナル:

ボタンキー用途
矢印キーナビゲーションメニュー操作、vim、Claude Code
Enter確定コマンド送信
Tabオートコンプリートシェル補完
Escapeキャンセルエージェントターンの中断
Ctrl+C強制終了プロセス停止(赤)
スクロールモードCtrl+B [tmux コピーモード(オレンジ)
PgUp/PgDnスクロールコピーモード内のナビゲーション
Ctrl+DEOF優雅な終了(ティール)

14px 超薄型ヘッダーに CPU/MEM のライブ統計。最大限のターミナルスペース。

セキュリティ

  • セッション Cookie(httpOnly、Secure、SameSite=Lax)と Argon2id パスワードハッシュ
  • CSRF 保護 - 状態変更リクエストに対する Origin ヘッダー検証
  • パストラバーサル防止 - すべてのファイル操作で
  • レート制限 - 認証エンドポイントにロックアウト付き
  • デフォルトでループバックのみ - 127.0.0.1 にバインド;TLS 付きリバースプロキシで公開

正直な制限事項

  • シングルユーザー - localhost で一人用に設計。マルチテナントサービスではない。
  • インメモリセッション - セッションストアは再起動後に維持されず、複数インスタンス間で動作しない。シングルプロセスデプロイでは問題なし。
  • ファイル同期なし - 閲覧と編集は可能だが、双方向同期はなし。rsync や git を使用してください。
  • tmux 必須 - ターミナルセッションは tmux。リモートホストに tmux がなければターミナルは使えない。
  • 大規模ディレクトリ - バーチャルスクロールで 10K+ ファイルに対応するが、10 万エントリのディレクトリに対する SFTP readdir は依然として遅い。

はじめる

pip install sshler                # または: uv add sshler
sshler serve                      # ブラウザが自動で開きます
sshler serve --no-browser         # ヘッドレス / systemd

Python 3.12+ · リモートホストに tmux(ローカルボックスにはローカル tmux)。

uv run pytest                     # 232 テスト(バックエンド 167 + フロントエンド 65)