SSHのリバースポートフォワーディングの強化
unit
- TOP
- Old Archives
- SSHのリバースポートフォワーディングの強化
以前かなり入念に設定して外出中もSSHでログインできるようにしたはずだったのだが、実際に試してみるとうまくいかないケースがあった。
もちろん、前回の設定で、SSHが死ねば再度コネクションを貼り直すようにしたし、サーバーから一定時間応答がなければ死んだとみなすようになっていた。 これで万全のはずだった。
ところが、サーバーからPONGは届いているにもかかわらず、ポートフォワーディングは死んでいる…という事態に遭遇したのだ。
これでは困る。 なぜそんなことになるというのか。
しかし発生するものは仕方ない。 実際にログインできない場合には無理やり貼り直すことにしよう。
方法としては割と単純で、自分自身に対するものではあるが、一旦サーバーにSSHで接続し、そこからSSHで手元のコンピュータに対してログインしコマンドを実行する。 これに失敗すればコネクションが切れているとみなす。
ProxyCommand
を使う必要はなく、単純にsshのコマンドとしてsshを含めればいい。
ssh serverhost ssh mycomputer true
新しく鍵を作ってサーバーに登録する。
サーバーで実行するコマンドはsshである。
また、逆にサーバーでも新しい鍵を作って手元コンピュータに登録する。つまり、互いにコマンド実行用の鍵を登録することになる。
サーバー側で結びつけるコマンドはsshである。
このSSHで~/.ssh/config
によってターゲットコンピュータに対してログインするホストを指定する。
Host target-pc-connection-check
User jrh
Port 2222
Hostname localhost
IdentityFile ~/.ssh/target-pc-connection-check_rsa
サーバー側で鍵に結びつけるコマンドはssh target-pc-connection-check
である。
ターゲット側では次のように登録する。
Host target-pc-connection-check-via-server
User jrh
Port 22
Hostname serverhost.example.com
IdentityFile ~/.ssh/target-pc-connection-check-via-server_rsa
これでターゲットコンピュータがこの鍵でサーバーにログインすると自動的にサーバーはSSHを実行しターゲットコンピュータにSSHポートフォワーディングを介して接続しようとする。 自動化のためそれぞれの鍵にはパスワードはかけない。
ターゲット側で鍵に結びつけるコマンドはtrue
でも良いと思うが、echo OK
あたりでも良いだろう。
これでターゲット側から
ssh target-pc-connection-check-via-server | grep -qF OK
とすれば、コネクションが到達するかどうかをチェックできる。
Systemdユニットに組み込むと面倒なことになるので、システムトレイアプリに組み込む。
#!/usr/bin/zsh
unitname="sshreverse.service"
systemctl start --user $unitname
while systemctl status --user $unitname | grep -F "active (running)"
do
(
while sleep 300
do
if ssh target-pc-connection-check-via-server | grep -qF OK
then
:
else
systemctl restart --user $unitname
fi
done
) > /dev/null &
typeset -i checkpid=$!
yad --notification --image="network-vpn" --title="Reverse Forwarding is Now Active"
if yad --title="Stop Reverse Forwarding" --image dialog-question --button=gtk-yes:0 --button=gtk-no:1 --text="Really stop reverse for
warding?"
then
kill $checkpid
systemctl stop --user $unitname
fi
done