読者です 読者をやめる 読者になる 読者になる

けつあご日記

きくちはやみのふぃくさーにしかなりたくない.ひゃっぽゆずっててんほういは,あり.

autosshがバックグラウンドで動かないときの妥協策

ネットワーク Mac CentOS ライフハック

大学のネットワークにポートフォワーディングしていたときのメモ.そのときの本筋は別記事↓

www.ketsuago.com

なので,京大のポートフォワーディングサーバに繋いでるときを想定している.他のサーバだと違うかも.また,クライアントはOSX El Capitan.


autosshというsshを自動でつなげ続けて置いてくれるツールがあることを知った.ポートフォワーディングする際に使用したいのだが,普通にやるとポートフォワーディングのプロンプトが起動したままになって,そのターミナルは使えなくなってしまう.

普通のsshのときは-fNオプションを付ければよかったのだが,autosshだとなぜかうまくいかなかった.

$ autossh -M 0 -L [ポート番号]:[IPアドレス]:ポート番号 hoge@portforwarding-server

とすれば,

Password:

とパスワードを聞かれて,入力すると,

forward%

とプロンプトが出て,接続が完了する.しかし,こちらのようにバックグラウンドで動かすためのオプション(-f)をつけると,パスワードが聞かれなくなってしまう.パスワードを聞く前にバックグラウンドに行ってしまうようだ.なんてことだ.
qiita.com

オプションの位置を色々変えてみたりしたがいずれもうまくいかなかった...少し調べてみると,autosshに-fオプションを付けるとうまくいかないときが確かにあるようだった.しかもなんかややこしい事情っぽい.
ssh - autossh in background does not work - Server Fault
macos - autossh in background does not work anymore - Ask Different

(autosshは他にも,環境変数AUTOSSH_LOGFILEを自分で決めると途端に動かなくなったりと,ナゾの挙動を示したりする.autosshで変なことが起きたら他の環境ではなくautossh自体を疑うべきかもしれない...)


別に-fでバックグラウンドにすることにこだわらないので,妥協策を考えた.今回接続しているポートフォワーディングサーバではbgコマンドが使えるので,出てくるプロンプトで"bg"と打つだけだ.これでターミナルが普通に使えるようになる.いちいち手で打つのは馬鹿らしいので,パスワード認証とまとめてシェルスクリプトにした.ポートフォワーディングサーバへの接続から,リモートサーバへの接続までをやっている.

#!/bin/bash

PW="foobar"

expect -c "
spawn autossh -M 0 -L [port num]:[IP]:[port num] hoge@portforwarding-server
expect \"Password:\"
send \"${PW}\n\"
expect \"forward%\"
send \"bg\"
"

ssh -p [port num] username@localhost

これで,autosshはバックグラウンドで動くようになるのだが,一つ問題がある.リモートサーバからログアウトしたあとにautosshとsshのプロセスが残ってしまうのだ.

$ ./sshauto.sh  
spawn autossh -M 0 -L [port num]:[IP]:[port num] hoge@portforwarding-server
Password: 
forward% Last login: Mon Dec 12 14:37:08 2016 from portforwarding-server
[user@remote ~]$ logout
Connection to localhost closed.
[/Users/hkikuchi]
$ ps -A | grep ssh
 1019 ??         0:00.20 /usr/bin/ssh-agent -l
 1253 ttys000    0:00.00 grep --color ssh
 1247 ttys001    0:00.00 autossh -M 0 -L [port num]:[IP]:[port num] hoge@portforwarding-server
 1250 ttys001    0:00.02 /usr/bin/ssh -L [port num]:[IP]:[port num] hoge@portforwarding-server

ポートフォワーディングのプロンプトから普通にexitしたときはちゃんと消えるのだが...多少気持ち悪いが,どうせ一度つなげばいいだけなので,気にするほどのことではないと判断した.

どうしても気持ち悪い場合は,切断したあとに

$ pkill -9 autossh

としてautosshを強制終了すれば良い.ここで普通のkillを使っていないのは,autosshの実態はシェルスクリプトであり,killでは消えないような書き方がしてあるから(ssh - How to stop/kill an autossh tunnel? - Super User).


絶対もっといい方法があるが,とりあえずこれで妥協した.もしどなたかいい方法をご存知でしたらコメントください.



↓アフィカスリンク

ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識

ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識