SSHポート転送接続を維持します


3

SSHを介して永続的なポート転送を行っています。基本的には

while true; do
        ssh <somewhere> \
                -R <dst-port>:localhost:<src-port> \
                -N -n -o ExitOnForwardFailure=yes
        sleep 10
done

ただし、それはあまり信頼できません。ポートがまったく転送されない場合があります(接続が正常に動作しているかどうかはわかりませんが、クライアントでプロセスを確認でき、数時間既に実行されています)。ネットワークインターフェースはダウンしています)が、タイムアウトするのに非常に長い(場合によっては30〜60分)時間がかかります。

どうすれば信頼性を高めることができますか?たぶん1分のタイムアウトが必要です。


この非常に関連性のある/類似した質問を見つけました ただし、最初の答えはそれExitOnForwardFailureを解決する必要があることを示していますが、私はすでにそれを持っていますが、そうではありません(sshこのオプションで実行中のプロセスをすぐに見ることができますが、ポートは転送されません)。

回答:


4

これらをSSHクライアントconfigファイルに入れます。

ServerAliveInterval = 60
ServerAliveCountMax = 3

または、これらのオプションはsshを介してコマンドラインで渡すことができます-o

モバイルデバイス用のさまざまな貧弱なクライアントなど、一部のクライアントにはこの構成制御がありません。その場合、接続先の各サーバーでグローバルに設定することは可能ですが、もちろんサーバーマシンでの権限が必要です。OpenSSHDの実装には、ユーザーがサーバーパラメーターをカスタマイズする方法がないようです(~/.ssh/sshd_config選択したパラメーターをサーバー側からカスタマイズできるファイルは読み込まれません)。


3

作業マシンで次のようなautosshを使用して、リモートWeb開発用にセットアップします。

autossh -M0 -N -R \*:8080:localhost:80 -R \*:5051:localhost:22 home

autosshは、「kill -9」以外の理由でクラッシュまたは停止した場合にsshを再起動し続けるプログラムです。上記のコマンドは2つのトンネルを設定します。1つは作業マシンのポート80を自宅のマシンの8080に転送し、もう1つは作業マシンのsshサーバーを自宅のマシンにトンネルします。ポートの前にある*は、localhostだけでなく、任意のホスト名でこれを機能させます。ただし、sshd_configで「GatewayPorts yes」を設定する必要がある場合があります。これをさらに透明にするために、ホームマシンの〜/ .ssh / configおよび/ etc / hostsにホストがあります。他のシステムでは、ProxyCommand(http://sshmenu.sourceforge.net/articles/transparent-mulithop.html)を使用する必要がありますが、現時点では、このコマンドを使用して電源を入れたホストを取得できません。

〜/ .ssh / config:

Host work
    hostname localhost
    port 5051

それはただ

autossh -M0 -t home 'ssh work'

接続する任意のホストから。


すでにautossh前に読みました。しかし、私は以前とまったく同じ問題を抱えています。接続は停止しますが、autossh認識されません。
アルバート

1

このバージョンは、いくつかのデータをサーバーに頻繁に送信します。接続が切断された場合、パイプは遅かれ早かれ壊れるはずです。

while true; do
        { while true; do echo echo ping; sleep 10; done } | \
        ssh <somewhere> \
                -R <something> \
                -o ExitOnForwardFailure=yes \
                >/dev/null
        sleep 10
done

0

SSHコマンドを次のように変更してみてください。

ssh SOMEWHERE -R DSTPORT:localhost:SRCPORT -n -o ExitOnForwardFailure=yes \
    "while true; do echo ping; sleep 10; done" >/dev/null

これにより、TCP接続を介して10秒ごとに少量のデータが送信されます(その期間は自由に変更できます)。接続を維持するにはこれで十分かもしれません。


実際に試してみましたか?私はいくつかの同様のハックについて考えていましたが、そうでなければタイムアウトがないとは本当に信じられませんでしたので、私はまだ試してさえいませんでした。
アルバート

はい、そのトリックをプラスの効果に使用しました。
フラン

今すぐ試しました。動作せず、接続は静かに終了し、認識されません。
アルバート

その後、TCPタイムアウト以外の何かが原因で接続が失敗します。通常、マシンにSSHでwhile接続し、シェルプロンプトからそのループを実行しても、切断されますか?その場合、ネットワークに問題があります。
フラン

接続が失われたということをサーバーが送信していない場合、クライアントはどうすればよいでしょうか?クライアントが常に何かを送信している(そしてSSHプロトコルが何らかの形式のackを取得する必要がある)わずかに異なるバリアントを作成しました。私自身の答えをご覧ください。
アルバート

0

Kazが以前に引用したように、接続はキープアライブのために明示的なトラフィックを必要としないようです。何かのようなもの:

ssh you@there 'read ANYTHING' < $PIPE

ただ動作します。$ PIPEは、完了時に書き込む名前付きパイプです。

さて、明示的にしましょう-$ PIPEは 'read anything'よりも複雑で、冗長な例に値します。以下は、直接アクセスできないネットワーク内のマシンをrdesktopするために使用するコードです。

p_user=myself
p_bridge=me@there
p_host=192.168.xxx.yyy
p_port=9999

p_size=100%      # or: p_size=1280x1024
p_trace=stderr   # or: p_trace=null

s_trace() {  echo "$*" > /dev/$p_trace; }

PIPE=$TEMP/${0##*/}.$$
mkfifo $PIPE.0
mkfifo $PIPE.1

trap 'rm $PIPE.0 $PIPE.1' 0

# ----------------------------------------------------
ssh $p_bridge \
    -L $p_port:$p_host:3389 \
    'read CONNECT; date; read QUIT' \
  < $PIPE.1 \
  > $PIPE.0 \
  & 
# ----------------------------------------------------

# note: "type -p" is somehow required with xinit
# note: "-p -" reads password from stdin
DESKCMD="$(type -p rdesktop) -P -z -u $p_user -p - -g $p_size localhost:$p_port"

{
  echo connect >&3; read CONNECT <&4; s_trace "CONNECTED: $CONNECT"
  $DESKCMD -f    # or: xinit $DESKCMD -- :1
  echo quit >&3
} \
  3> $PIPE.1 \
  4< $PIPE.0

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