不安定なSSH接続を自動的に再開するための画面など


18

信頼性の低いwifi環境では、sshを介してサーバーに接続する必要があることがよくあります。サーバーで画面を実行するので、切断された場合は、再接続して画面セッションを再開し、中断したところから再開できますが、接続の喪失は依然として大きなタイムシンクです:接続が途切れた場合サーバー上では、ターミナルウィンドウがフリーズする傾向があります。そのタブを強制終了し、新しいタブを開き、サーバーに再度sshして、画面セッションを再開する必要があります。サーバー上で画面を実行し、ローカルで画面でこれを試しました。いずれにせよ、接続が切れるとフリーズする傾向があります。

画面に似たもの、または画面自体を自動的に再接続してセッションを実行しようとする方法があるので、手動で再接続し続ける必要はありませんか?多くの場合、接続を失ったとき、それは非常に短い期間だけだと思います-1秒未満かもしれません。

Ubuntu 14.04 LTS、MATEエディションを使用しています。ありがとう


4
「シェルウィンドウがフリーズする傾向があります」というのは、ローカルsshが接続が停止していることを知らないためです。ヒット<Enter>と入力し~.、接続をドロップするようにあなたの側に伝えるために、あなたは、単に(上矢印またはで例えば再接続するには、最後のsshコマンドを繰り返すことができます!!)。
アレクシス

再接続するためのより速い方法のように聞こえる@alexis、ありがとう!私は...それは自動的にかかわらず起こるのが大好きです
マックス・ウィリアムス

回答:


23

あなたが使用して見ることができますmoshhttps : //mosh.org/

mosh接続に使用する信頼性の高いインターネット接続を使用して「ジャンプ」サーバーを設定し、ssh管理する各サーバーへのセッションを確立できます。ジャンプサーバーを使用することをお勧めする理由moshは、管理しているサーバーにインストールしたくない場合があるためです。

もう1つの利点moshは、TCPではなくUDPに基づいており、セッションがIPアドレスの変更(たとえば、WiFiからモバイルインターネット接続への変更)に耐えることができることです。

ちょうどそれを明確にするために、moshに代わるものではありませんscreenが、むしろssh。クライアントが何らかの理由で停止した場合、セッション自体にセッションに再接続する方法が提供されないため、それを使用screenすることをお勧めしますmosh


おかげで、(ほとんどの場合)ただ1つのサーバーであり、私たちはそれを所有しているので、Moshをインストールできるはずです。確かめます。
マックスウィリアムズ

実際、サーバーは非常に古い(または古いUbuntuを実行していると言う必要がある)ため、インストールが非常に困難であることがわかりました。:(
マックスウィリアムズ

@MaxWilliamsは何歳ですか?LTS 12.4でもサポートが終了しています。そして、なぜ自分でコンパイルしようとしないのですか?
phuclv

moshのドキュメントを読むと、リモートで管理する予定の各ホストにmosh-serverが必要です。それでも、間違いなく面白い。
ワイルドカード

1
moshを介してtmux端末に接続することは、私にとって最も安定したソリューションです。
ニモ

3

私はtmux数年前から使用していますが、私の経験では、自動的に再接続します。少なくとも接続が比較的短時間しか失敗しない場合。実際byobuにtmuxをバックエンドとして使用しています。この堅牢性がこの2つの組み合わせの特徴なのtmuxか、byobuそれとも組み合わせなのかはわかりませんが、両方試してみることをお勧めします。

ローカルのArchインストールから、VPNを介してさまざまなリモートUbuntuサーバーに接続します。リモートに接続しているときにネットワークケーブルを抜いて、今すぐテストしました。セッションはハングしましたが、ケーブルを再び接続するとすぐにシームレスに再開しました。

ただし、ルーターを再起動してテストしたところ、接続が戻りませんでした。ネットワークがダウンした時間と関係があると思いますが、数秒でダウンした場合は再接続するようです。

関係がある場合は、これをすべてterminatorターミナルエミュレータとして使用します。

これら3つはすべてUbuntuリポジトリで利用できます。

sudo apt-get install tmux terminator byobu

ただし、ssh切断の処理のどちらかtmuxまたはどちらbyobuが優れているかはまったくわかりません。私の経験では、それらはしばしば短い接続損失から戻ってくることを知っています。それは私の設定の他の側面にダウンするかもしれません。


1
ルーターを再起動すると、別のパブリックIPアドレスが与えられた可能性があり、これによりtcp接続が切断されます。私の経験sshから断続的なネットワークのドロップアウトに対して非常に回復力がありますが、これはウィンドウtmux内で使用しているという事実とは関係ないと思いsshます。
さびたシャックルフォード

3
私は同じことを言おうとしていました。プレーンSSHでも、TCP接続が切断されない限り、短時間の切断に対処できます。それはかもしれない、あなたのインターフェイスがシャットダウンを取得、または一部の熱心ルータがそれを殺す場合(NATルータが再起動時にNAT状態を忘れて、既存の接続を壊すかもしれない)、またはClientAlive/ ServerAliveトリガ、または...私は何は考えてきたんbyobuけれども、ありませんが。
-ilkkachu

はい。ただし、OPは接続障害でフリーズしているようですが、私はそうしていません。しかし、はい、あなたは正しいです、私は単純なsshとtmuxでこれを見ます。それにもかかわらず、おそらくスクリーンはそれを処理できないのですか?
テルドン

2
@MaxWilliams tmuxは、基本的には、より現代的な代替手段screenです。私が今のように仕事を始めてこの種のものが必要になったとき、私の大まかな読書はtmux最近の方が良い選択であると示唆しました。また、失われた接続をより適切に管理できるかどうかも100%確信できません。私の経験では、短時間の停止から回復することしかわかりません。それがダウンしているのか、tmux他の何かであるのかは分からない。しかし、試してみる価値があるようです:)。Byobuは基本的にscreen / tmuxのフロントエンドであり、GUI端末エミュレータではありません。しかし、非常に便利です:byobu.org
terdon

2
tmuxは、接続の中断については何もしません。sshが提供する端末デバイスで動作します。それはすべてssh接続で立ち下がります。
ジョナスシェーファー

2

sshのServerAliveオプションを使用して、接続が失敗したことを検出します。

ServerAliveCountMax
ssh(1)がサーバーから返されるメッセージを受信せずに送信されるサーバーアライブメッセージ(下記参照)の数を設定します。サーバーアライブメッセージの送信中にこのしきい値に達すると、sshはサーバーから切断し、セッションを終了します。サーバーアライブメッセージの使用はTCPKeepAlive(下記)とは非常に異なることに注意することが重要です。サーバーの生存メッセージは暗号化されたチャネルを介して送信されるため、なりすましはできません。TCPKeepAliveによって有効にされるTCPキープアライブオプションは、なりすまし可能です。接続が非アクティブになったことをクライアントまたはサーバーが知ることに依存している場合、サーバーアライブメカニズムは重要です。

デフォルト値は3です。たとえば、ServerAliveInterval(以下を参照)が15に設定され、ServerAliveCountMaxがデフォルトのままになっている場合、サーバーが応答しなくなると、sshは約45秒後に切断します。

ServerAliveInterval
サーバーからデータを受信しなかった場合、ssh(1)は暗号化されたチャネルを介してメッセージを送信し、サーバーからの応答を要求するまでのタイムアウト間隔を秒単位で設定します。デフォルトは0で、これらのメッセージがサーバーに送信されないことを示します。

したがって、ServerAliveInterval5に設定するsshと、ネットワークが15秒間フレークアウトすると自動的に切断されます。


力でSSHセッションを破る、Iプレスに~.(そして、あるいは最初の入力~.エスケープ文字:)からなる~、セッションを破るためのコマンド.
イワンZakharyaschev - IMZ

@ imz--IvanZakharyaschevこれは、接続がハングしていることがわかると仮定しています。SSHのキープアライブを使用すると、障害が自動的に検出されます。
バーマー

それは本当に便利に聞こえます、ありがとう、次回は「フレークゾーン」にいるときに間違いなく試してみます。
マックスウィリアムズ

@Barmarはい、本当です。また、接続が本当にハングしているかどうかを判断する問題についても考えました。何かを押すと、誤ってこれらのキーがリモート側に送信される可能性があります...そして、良い解決策がわかりません。
imz-イヴァンザカリヤシェフ

2

同様の条件では、eshellEmacs内で(ssh経由で)TRAMP を使用する傾向があります。TRAMPは、リモートシェルに必要なコマンドを提供するのに大きなトラブルを引き起こすことなく、必要に応じて再接続を処理します。

ただし、eshellは端末としては適切ではありません。つまり、端末で特別な処理を行うコマンドを実行したり、長時間(連続的に)何かを出力したりするコマンドを実行するのには適していません。

基本的に、TRAMPを使用してEmacsで使用を開始するのは非常に簡単です。

M-x eshell
cd /user@host:

1

免責事項

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"

これは単にに接続して接続しようとする愚かな単純なループを実行sshscreenます。ホストなど、通常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セッションはすぐに再び有効になり、切断中に入力したすべてのキーがコマンドラインに表示されました。

見て、sshOSが何かがおかしいと言うまで、TCPネットワークソケットへの書き込み/読み取りを行うだけで、実際はTCPは長時間の接続切断に対して非常に寛容です。

デフォルトのカーネル設定LinuxでのTCPスタックは喜んで死んでの接続を宣言しにエラーを報告する前に、多く分間完全にサイレントに行くの接続を許容するとともに、独自のデバイスに委ねssh、それが最終的に私たちが球場に話しているあきらめる時間で-最大30分間、または少なくとも1秒または1分間の接続中断を長引かせるのに十分な長さです。

カバーの下では、Linux TCPスタックは徐々に長い遅延でメッセージを再試行しますが、これは、接続が戻るまでに、sshセッションが再び「生きている」ように見える前に追加の遅延を見ている可能性があることを意味します。

これが時々壊れる理由

多くの場合、TCPスタックが許容する量よりも大幅に短い非アクティブ期間が経過すると、何らかの理由で接続がアクティブに閉じられ、その接続状態をsshクライアントに報告できません。

候補者には次のものが含まれます。

  1. ファイアウォールまたはNATルーターは、各ライブTCP接続を記憶するためにメモリを使用する必要があります-DOS攻撃に対する最適化および軽減策として、接続を忘れしまい、その後のパケットを静かに無視することがあります。既存の接続が無効に見えることを覚えていない場合の接続の途中。

  2. 正常に動作するファイアウォール/ルーターはTCP RSTパケットを挿入しますが、これは通常connection reset by peerエラーメッセージとして現れますが、リセットパケットはファイアアンドフォーゲットであるため、その時点でクライアントへの接続にまだ問題があり、パケットもリセットすると、クライアントは接続がまだ生きていると判断します。

  3. サーバー自体には、予期しないパケットを静かにドロップするファイアウォールポリシーがあり、サーバーが接続を閉じたと判断したが、クライアントがそうしない場合にクライアントの接続再開の試行を中断します。クライアントは接続を継続しようとしますが、サーバーはこれらのパケットがサーバーのファイアウォール状態に属するライブ接続がないため、これを無視します。

    Linuxを実行しているので、サーバーのiptables/ ip6tables(またはnft新しいものを使用している場合)で、許可するものと削除するものを正確に確認してください。TCP SSHポートで新しい / 確立された / 関連するパケットを許可することは非常に一般的ですが「無効な」ものは許可しません-許可されていないものをすべて静かに落とすと、この一般的なセットアップは短時間の接続問題の後にこれらの種類のフリーズを引き起こす可能性があります。

  4. TCPまたはSSHクライアントキープアライブパケットのOpenSSHオプションのいずれかを使用して、SSHサーバー自体が一定の非アクティブ後に接続を閉じるように構成されている場合があります。これ自体では、無期限にハングアップすることはありませんが、上記の状態のいずれかになります。

  5. sshセッションがハングアップした状態になった後、自分で「アンハング」するのに十分な時間を与えていない可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.