web-dev-qa-db-ja.com

-fオプションで開始されたSSHセッションを終了する方法(バックグラウンドで実行)

私はこれでかなり迷っています。 manページから:

 -f      Requests ssh to go to background just before command execution.

-fオプションを指定してSSHを開始すると、トンネルが機能します。しかし、それを使い終わった後、それをさらに操作する方法がわかりません。たとえば、SSHトンネルを閉じることができない終了すると、.

私が知っている通常の方法は機能しません。たとえば、jobsは何も返しません。 ~コマンドは認識されません(とにかく、その使用方法が正確にわかりません)。

ただし、pgrepは、SSHトンネルがまだ実行中であることを示しています(端末を閉じた後など)。どうすれば操作できますか?どうやって閉じるのですか?

59
MountainX

私はここで解決策を見つけました: http://www.g-loaded.eu/2006/11/24/auto-closing-ssh-tunnels/

最善の方法–自動クローズするトンネル

前述のように、-f -Nスイッチの組み合わせを使用する代わりに、-fを単独で使用するだけでなく、リモートマシンでコマンドを実行することもできます。しかし、トンネルを初期化するだけでよいので、どのコマンドを実行する必要がありますか?

これは、睡眠がすべての中で最も有用なコマンドになることができるときです!この特定の状況では、睡眠には2つの利点があります。

  • 何もしないので、リソースは消費されません
  • ユーザーはそれが実行される期間を指定できます

これらがsshトンネルの自動クローズにどのように役立つかを以下で説明します。

リモートマシンで10秒間スリープコマンドを実行しながら、バックグラウンドでsshセッションを開始します。秒数は重要ではありません。同時に、以前とまったく同じようにvncviewerを実行します。

[me@local]$ ssh -f -L 25901:127.0.0.1:5901 [email protected] sleep 10; \
          vncviewer 127.0.0.1:25901:1

この場合、sshクライアントは、sshセッションをバックグラウンドにフォークし(-f)、トンネルを作成し(-L 25901:127.0.0.1:5901)、リモートサーバーでスリープコマンドを10秒間実行する(スリープ) 10)。

この方法と以前の方法(-Nスイッチ)の違いは、基本的に、この場合のsshクライアントの主な目的は、トンネルを作成することではなく、sleepコマンドを10秒間実行することです。トンネルの作成は、副次的な目的のある種の副作用です。 vncviewerが使用されなかった場合、sshクライアントは、実行するジョブがなくなるため、10秒後に終了し、同時にトンネルを破壊します。

スリープコマンドの実行中に、別のプロセス(この場合はvncviewer)がそのトンネルの使用を開始し、10秒の期間を超えてそのトンネルを占有し続けると、sshクライアントがリモートジョブを終了(スリープの実行)しても、別のプロセスがトンネルを占有しているため、終了します。つまり、vncviewerも強制終了する必要があるため、sshクライアントはトンネルを破棄できません。 vncviewerがトンネルの使用を停止すると、sshクライアントもその目標をすでに達成しているため、終了します。

このように、バックグラウンドで実行されているsshプロセスはありません。

47
MountainX

スクリプトの特に優れた解決策は、master mode、制御コマンド用のソケット付き:

ssh -f -N -M -S <path-to-socket> -L <port>:<Host>:<port> <server>

もう一度閉じるには:

ssh -S <path-to-socket> -O exit <server>

これにより、プロセスIDのgreppingと、他のアプローチに関連する可能性のあるタイミングの問題の両方が回避されます。

78
Brian H

トンネルを強制終了するには、ps -C sshまたはps | grep sshまたはその他のバリアントを使用して、トンネルを実行しているsshプロセスを判別します。その後、それを殺します。

または、このポートが開いているプロセスを特定することで、プロセスを探すことができます。

netstat -lnpt | awk '$4 ~ /:1234$/ {sub(/\/.*/, "", $7); print $7}'

マシン上で(ユーザーとして)実行しているすべてのsshクライアントを強制終了する場合は、pkill sshが強制終了します。

ここで他の人が答えたように、pkill sshはそれを殺します。

戻すことができるトンネルを作成するには、-fオプションなしでscreenで開始し、Ctrl-A Dで画面を切り離します。トンネルを元に戻すには、screen -rを呼び出します。

9
Haotian Yang

私がトンネルを始めるとき:

ssh -fN -D 8080 SOME_IP_HERE -l LOGIN_NAME_HERE
  • -fコマンド実行の直前にバックグラウンドに移動するようにsshに要求します。
  • -Nリモートコマンドを実行しません。これは、ポートを転送するだけの場合に役立ちます。
  • -Dローカルの「動的な」アプリケーションレベルのポート転送を指定します。
  • -lリモートマシンと同じようにログインするユーザーを指定します。

私はそれを閉じることができます:

ps -lef | grep ssh | grep "8080" | awk "{print \$2}" | xargs kill
1
numediaweb

私はSOで堅牢なソリューションを見つけました。次を参照してください https://stackoverflow.com/a/26470428 。すべてのクレジットは@ghotiに送られます。

話全体を繰り返さなくても許されるといいのですが。これは、「高度な」SSH ControlMaster構成オプションに基づいており、~/.ssh/configファイルに最適に配置できます。これは、VNC-over-SSHの場合の方法です(私の雇用者のVPNでは、SSHとHTTPSを除くすべてのポートが閉じています)。

~/.ssh/config部分(ControlMasterおよびControlPathエントリに注意してください:

Host vnc
    HostName    my.desktop.internal.within.company
    User    laryx
    IdentityFile ~/.ssh/id_ecdsa
    LocalForward 5999 127.0.0.1:5900
    RequestTTY no
    ExitOnForwardFailure yes
    ControlMaster auto
    ControlPath ~/.ssh/control_sockets%r@%h:%p

小さなBashスクリプトで接続/切断します。

#!/bin/bash
if [ $# -lt 1 ]; then
    echo "This script creates an SSH tunnel to my desktop"
    echo "so that I can share its screen via VNC-over-SSH"
    echo "Usage: $0 start|stop"
    echo "Remember to start VPN first!"
    exit 1
fi

if [ $1 == "start" ]; then
    # Assuming that the VPN connection has been established
    # 1) Start the tunnel with
    ssh -f vnc -N
    # 2) check it
    ssh -O check vnc
    echo "Now share the screen by connecting to 'vnc://localhost:5999'"
    exit 0
fi

if [ $1 == "stop" ]; then
    ssh -O exit vnc
    echo "Now you may exit the VPN"
    exit 0
fi

トンネルはssh -Oコマンドで制御されます。

0
Laryx Decidua