私はこれでかなり迷っています。 manページから:
-f Requests ssh to go to background just before command execution.
-f
オプションを指定してSSHを開始すると、トンネルが機能します。しかし、それを使い終わった後、それをさらに操作する方法がわかりません。たとえば、SSHトンネルを閉じることができない終了すると、.
私が知っている通常の方法は機能しません。たとえば、jobs
は何も返しません。 ~
コマンドは認識されません(とにかく、その使用方法が正確にわかりません)。
ただし、pgrep
は、SSHトンネルがまだ実行中であることを示しています(端末を閉じた後など)。どうすれば操作できますか?どうやって閉じるのですか?
私はここで解決策を見つけました: 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プロセスはありません。
スクリプトの特に優れた解決策は、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と、他のアプローチに関連する可能性のあるタイミングの問題の両方が回避されます。
トンネルを強制終了するには、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
を呼び出します。
私がトンネルを始めるとき:
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
私は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
コマンドで制御されます。