テクノロジー · 実用ガイド

OpenSSH ControlMaster が固まった?ソケット削除前に停止を証明する

有効な ControlPath を解決し、マスターの生存を確認し、古いパス、停止した転送、パス障害を分離して、証明できた境界だけを修復します。

OpenSSH の有効設定から ControlPath 検証、マスター確認、安全な操作までを示すオリジナル判断図。
オリジナルのイラスト:実際の ControlPath を解決し、正確なマスターを問い合わせ、観測した境界だけを操作します。 Watch at Ease

ControlMaster の障害は一種類ではありません。パスが予期しない場所に展開される、Unix ドメインソケットの長さ制限を超える、ソケットを扱えないファイルシステムに置かれる、終了済みマスターを指す、またはローカルマスターは生きていてもリモート転送が停止している可能性があります。先にパスを消すと証拠を失い、生きたプロセスと競合します。

証拠の順で進めます。ssh -G で有効設定を固定し、非公開 ControlPath と長さを確認し、ssh -O check でそのソケットを問い合わせます。観測結果に応じて exit、unlink、配置変更、keepalive を選び、最後に二つ目のクライアントが新しいマスターを再利用することを証明します。

1. 別名と有効設定を固定する

失敗時と同じ別名と実行環境で ssh -G alias を実行し、hostname、user、port、proxyjump、controlmaster、controlpath、controlpersist を記録します。OpenSSH は通常、コマンド行、ユーザー設定、システム設定の順で最初の値を採用するため、最後の一致節だけを見ると別のソケットを調べることになります。

別の別名を手作業で展開しないでください。%h、%p、%r、%C は有効な接続から解決され、見かけが同じ名前でも別マスターになることがあります。出力全体を証拠として保存します。

2. 生存確認前にパスを検証する

解決した ControlPath が SSH ユーザー所有で他者が書けないディレクトリにあることを確認します。%h-%p-%r、長さが問題なら %C で一意にします。親の検索権限と最終ディレクトリの書込権限を確認し、欠落や権限不足を古いソケットと誤認しません。

エンコード後のパス長を測ります。Linux の pathname socket の sun_path は 108 バイトですが、より短い実装もあるため余裕を残します。短い私有ランタイムディレクトリなら深いホーム、コンテナ、CI パスを避けられます。

3. 正確なマスターに問い合わせる

固定した設定で ssh -O check alias を実行します。捕捉したパスを直接調べる場合は同じ有効ホスト、ユーザー、ポートで ssh -S "$socket" -O check host を使います。成功時は実行中のマスターと通常は PID が返るので、変更前に保存します。

全 OpenSSH で一つのエラー文を当てにしません。パスなしは展開・作成へ戻り、接続拒否は古い候補ですが、所有者、種類、別名、開いているプロセスを確認します。成功したら削除ではなく転送の健全性へ進みます。

4. 古いパスと停止した転送を分ける

マスターが応答し停止したいなら ssh -O exit alias を使い、プロセスとパスの消滅を確認します。応答中のパスを unlink すると既存クライアントを残して競合マスターを作れます。無応答、正しい所有者、対応プロセス・open socket なしを確認したときだけ証拠を保存してそのパスだけを削除します。

制御ソケットの応答はローカル制御路だけの証明です。ServerAliveInterval と ServerAliveCountMax を組み合わせると、確立済み転送でもサーバー無応答を暗号化プロトコルメッセージで検出できます。TCPKeepAlive とは境界が異なります。

5. パスとファイルシステム配置を修復する

overlay やコンテナ作業領域で作成できない場合、ローカルファイルシステムの短い私有ランタイムディレクトリで一度再現します。ControlPath を overlayfs 外へ移して成功した CI 例は配置診断であり、全 overlay の一般則ではありません。%C など宛先固有トークンを維持します。

適切な $XDG_RUNTIME_DIR 配下などユーザー所有の 0700 ディレクトリを優先します。/dev/shm を限定試験に使う場合も私有サブディレクトリを作り所有者と mode を確認し、共有書込可能な場所に予測可能な裸ソケットを置きません。ControlPersist と異常終了後の清掃も記録します。

6. 修復を証明し限界を示す

verbose 接続を一つ開始して多重化設定行を保存し、二つ目のプロセスで同じ別名を使って再利用を確認し、再度 ssh -O check を実行します。修復前後の ssh -G を比較し、非多重化への偶然のフォールバックではないことを証明します。

非公開パス作成、正確なマスター応答、二つ目の再利用、設計どおりの exit または永続化、リモートコマンド成功がそろった場合だけ受け入れます。pathname 型 ControlMaster と試したクライアントが範囲で、抽象ソケット、ランチャー、セキュリティモジュール、プロキシ、ベンダーパッチには追加証拠が必要です。

クライアント、ローカル Unix 制御ソケット、SSH マスタープロセス、リモート転送を示すオリジナル図。
オリジナルのイラスト:ローカル制御ソケットとリモート転送は別の障害境界です。 Watch at Ease