このブログはURLが変更になりました

新しいブログはこちら→ https://matsuu.hatenablog.com/

OpenSSHのセッションを束ねるControlMasterの使いにくい部分はControlPersistで解決できる

OpenSSHには1本のコネクションで複数のSSHセッションを束ねて使える機能があります。例えば、~/.ssh/configに

Host example.com
  ControlMaster auto
  ControlPath ~/.ssh/mux-%r@%h:%p

と設定しておくと、最初に接続したsshセッションのコネクション(マスターコネクション)を使いまわし、複数のSSHセッションをマスターコネクションに束ねることができます*1

主なメリットは以下のとおり。

  • TCPセッションは1つなのでTCPの同時接続数が制限されているサーバでも複数sshが可能*2
  • コネクションを使いまわした場合、接続にかかる時間が短い(ssh経由で複数回に分けてコマンド投入とかで時間短縮)
  • コネクションを使いまわした場合、パスワード入力やパスフレーズ入力が不要*3

ですが、ControlMasterとControlPathの設定だけだと実は使いにくいんですね。

マスターコネクションを切ることができない

ControlMasterとControlPathだけの場合、最初に接続したSSHセッションでサーバからログアウトしてもコネクションが残ったままになってしまいます。
ctrl+cなどで強制的に切断すると、束ねている他のSSHセッションも全部落ちてしまうんですね。あーなんたるこった。使えねー。
一応ctrl+zで止めてbgでバックグラウンド動作させることもできますが、面倒だし間違えるとオジャン。これは痛い。

そこでですね、ControlPersist設定ですよ。

ControlPersist yes

Host example.com
  ControlMaster auto
  ControlPath ~/.ssh/mux-%r@%h:%p
  ControlPersist yes

と設定した場合、マスターコネクションを張ったSSHセッションを終了すると自動的にバックグラウンドで動作し続けてくれます。
ただし、すべてのSSHセッションを切断してもマスターコネクションは自動切断されません。
プロセスをkillするか、-O exitで明示的に停止させるまでずっとコネクションを張ったままになってしまいます。

そこでControlPersist (タイムアウト秒数)ですよ

ControlPersist (タイムアウト秒数)

Host example.com
  ControlMaster auto
  ControlPath ~/.ssh/mux-%r@%h:%p
  ControlPersist 10

と設定した場合、すべてのSSHセッションが切断されてから10秒間に再接続がなければマスターコネクションが自動切断されます。こ、これこそが俺の求めていたものだ!

ただし、ControlPersistが使えるのはOpenSSH 5.6以降

ControlPersistはOpenSSH 5.6で実装された機能なので、手元のsshのバージョンが5.6である必要があります。さて、あなたの環境でControlPersistは使えるでしょうか。

2012年7月7日時点でのControlPersist使用可否
OS OpenSSHのバージョン 可否 備考
Debian stable(squeeze) 5.5p1 x testing(wheezy)から可
Fedora 17 5.9p1 o 15から可
FreeBSD 9.0 5.8p2 o 8.39.0から可
Gentoo stable 5.9p1 o 2010/10/11から可
Mac OS X Lion 5.6p1 o Lionから可
RHEL 6.3 5.3p1 x
Ubuntu 12.04 5.9p1 o 11.10から可

良かったですね!意識の高いエンジニアさんがこよなく愛するOSXはLionで対応してますよ!良かったですね!
使えるOSも比較的新しいものでしか対応してないのでご注意ください。
ControlPersistはクライアント側だけの話なので、サーバ側がControlPersistに対応してなくても大丈夫です。

まとめ

ControlMasterを使うメリットはSSH接続時間の短縮だと私は思ってます。数秒程度の接続処理が短縮されて何が嬉しいんだと思われるかもしれませんが、

  • 何度もssh接続が発生するSSH越しのCVS/SVN
  • lsyncd(rsync)
  • sshfs
  • cactisshによるコマンド出力結果取得

などでその効果を存分に発揮できると思います。是非一度体験してみてはいかがでしょうか。

なお、

Host *
  ControlMaster auto
  ControlPath ~/.ssh/mux-%r@%h:%p
  ControlPersist 10

とすればすべてのSSHに適用できますが、X転送やagent転送周りに制約がある*4ので、個別にホスト単位で指定するのが無難です。

*1:ただしX11転送やssh-agent転送に制限あり

*2:ログインユーザー数はsshの数だけ増えるので注意

*3:セキュリティ上危険なのでControlPathは/tmpなどで設定しないこと

*4:他にも何か制約があるかもしれない。ないかもしれない