免責事項
SSH接続が短時間のネットワーク停止に耐えられない場合は、他に何かが起こっておりssh
、TCPが通常の処理を行っていません。
詳細は以下をご覧ください。とにかく:
最速で最も汚れのない依存関係のないソリューション
次のようなシェルスクリプトを作成します。
#!/bin/sh -
# Tune these numbers depending on how aggressively
# you want your SSH session to get reconnected.
timeout_options='-o ServerAliveInterval=4 -o ServerAliveCountMax=2'
# 255 is the status OpenSSH uses to signal SSH errors, which
# means we want to connect. All other exit statuses suggest
# an intentional exit.
status=255
# Keep opening the SSH connection and immediately dropping into
# `screen` until an intentional exit happens.
while [ "$status" = 255 ]
do
ssh $timeout_options -t "$@" screen -dR
status=$?
# You can add a `sleep` command here or a counter or whatever
# you might need as far as rate/retry limiting.
done
exit "$status"
これは単にに接続して接続しようとする愚かな単純なループを実行ssh
しscreen
ます。ホストなど、通常ssh
はコマンドライン引数として呼び出しに渡すものを渡します。
再接続は、SSHが接続のエラーを報告するかどうかに基づいています。つまり、「文字通りWiFIがオンになっていない」などの非SSHエラーを検出するためのインテリジェンスはありませんが、それはおそらく重要ではありません君は。
ssh-agent
追加の入力なしで再接続が機能するように、パスフレーズなしのSSHキーを持っていると仮定しています。
^C
再接続中に人間が知覚できないほんのわずかな瞬間にヒット^C
すると、クライアント端末にパススルーする代わりにスクリプトを殺す可能性があるため、接続がハングする疑いがある小さな競合状態が発生します^C
熱心にマッシュしないでください。
最も単純な追加ソフトウェアソリューション
Ubuntuパッケージリポジトリで利用できるはずのプログラムautosshを試すことができます。
あなたがソースまたは監査それからビルドする必要がある場合は、依存関係などの追加のライブラリなしでコンパイルは、上記の私のハックよりも接続活気をチェック詳細知性を持っているように見えることを、単一のCプログラムです、そしてそれはまた、便利に同梱さrscreen
れた自動スクリプトコマンド-に添付しscreen
ます。
詳細
ssh
通常の回復方法
ただ確認するために、私は自分自身をチェックせずに物事を言うのが好きではないので、答える前に小さなテストを実行しました:
Linuxデバイスを使用してWiFiに接続し、LAN上の別のデバイスにSSH接続ssh
し、もう一方の端に正常に接続していることを確認して(コマンドを実行できるなど)、クライアントでWiFiを切断しました(インターフェイスが発生しました)構成解除する:IPアドレスはもうありません)、sshセッションに多くの文字を入力し(もちろん応答なし)、WiFiに再接続しました-悪い信号やその他の要因により、実際には少なくとも1回は再接続に失敗しました、最後に再接続しました:ssh
セッションが回復するまで約5秒待機しましたが、何も起こりませんでしたので、もう1つのキーを押すと、ssh
セッションはすぐに再び有効になり、切断中に入力したすべてのキーがコマンドラインに表示されました。
見て、ssh
OSが何かがおかしいと言うまで、TCPネットワークソケットへの書き込み/読み取りを行うだけで、実際にはTCPは長時間の接続切断に対して非常に寛容です。
デフォルトのカーネル設定LinuxでのTCPスタックは喜んで死んでの接続を宣言しにエラーを報告する前に、多く分間完全にサイレントに行くの接続を許容するとともに、独自のデバイスに委ねssh
、それが最終的に私たちが球場に話しているあきらめる時間で-最大30分間、または少なくとも1秒または1分間の接続中断を長引かせるのに十分な長さです。
カバーの下では、Linux TCPスタックは徐々に長い遅延でメッセージを再試行しますが、これは、接続が戻るまでに、ssh
セッションが再び「生きている」ように見える前に追加の遅延を見ている可能性があることを意味します。
これが時々壊れる理由
多くの場合、TCPスタックが許容する量よりも大幅に短い非アクティブ期間が経過すると、何らかの理由で接続がアクティブに閉じられ、その接続状態をssh
クライアントに報告できません。
候補者には次のものが含まれます。
ファイアウォールまたはNATルーターは、各ライブTCP接続を記憶するためにメモリを使用する必要があります-DOS攻撃に対する最適化および軽減策として、接続を忘れてしまい、その後のパケットを静かに無視することがあります。既存の接続が無効に見えることを覚えていない場合の接続の途中。
正常に動作するファイアウォール/ルーターはTCP RSTパケットを挿入しますが、これは通常connection reset by peer
エラーメッセージとして現れますが、リセットパケットはファイアアンドフォーゲットであるため、その時点でクライアントへの接続にまだ問題があり、パケットもリセットすると、クライアントは接続がまだ生きていると判断します。
サーバー自体には、予期しないパケットを静かにドロップするファイアウォールポリシーがあり、サーバーが接続を閉じたと判断したが、クライアントがそうしない場合にクライアントの接続再開の試行を中断します。クライアントは接続を継続しようとしますが、サーバーはこれらのパケットがサーバーのファイアウォール状態に属するライブ接続がないため、これを無視します。
Linuxを実行しているので、サーバーのiptables
/ ip6tables
(またはnft
新しいものを使用している場合)で、許可するものと削除するものを正確に確認してください。TCP SSHポートで新しい / 確立された / 関連するパケットを許可することは非常に一般的ですが、「無効な」ものは許可しません-許可されていないものをすべて静かに落とすと、この一般的なセットアップは短時間の接続問題の後にこれらの種類のフリーズを引き起こす可能性があります。
TCPまたはSSHクライアントキープアライブパケットのOpenSSHオプションのいずれかを使用して、SSHサーバー自体が一定の非アクティブ後に接続を閉じるように構成されている場合があります。これ自体では、無期限にハングアップすることはありませんが、上記の状態のいずれかになります。
ssh
セッションがハングアップした状態になった後、自分で「アンハング」するのに十分な時間を与えていない可能性があります。
<Enter>
と入力し~.
、接続をドロップするようにあなたの側に伝えるために、あなたは、単に(上矢印またはで例えば再接続するには、最後のsshコマンドを繰り返すことができます!!
)。