SSH で ControlMaster を使い、TCP セッションを集約する
通常、「3 つ同時に SSH ログインすれば 3 つの TCP セッション」が確立されます。しかし、ControlMaster という設定を行うと「同時に複数の SSH ログインを実行しても、1 つの TCP セッションだけで済む」ように出来ます。
ControlMaster を使わない場合
1 回目の SSH アクセス
パスワードを聞かれます。
| $ ssh 10.101.0.12
user@10.101.0.12's password:
Last login: Sun Oct 2 11:08:26 2016 from 10.101.0.11
$
|
2 回目の SSH アクセス
2 回目もパスワードを聞かれます。
| $ ssh user@10.101.0.12
user@10.101.0.12's password:
Last login: Sun Oct 2 11:25:09 2016 from 10.101.0.11
$
|
3 回目の SSH アクセス
3 回目もパスワードを聞かれます。
| $ ssh user@10.101.0.12
user@10.101.0.12's password:
Last login: Sun Oct 2 11:26:14 2016 from 10.101.0.11
$
|
状態確認
w を確認すると、tty が 3 つ、割り当てられています。
| $ w
11:27:04 up 2 min, 3 users, load average: 0.06, 0.08, 0.04
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
user pts/0 10.101.0.11 11:25 0.00s 0.01s 0.00s w
user pts/1 10.101.0.11 11:26 50.00s 0.00s 0.00s -bash
user pts/2 10.101.0.11 11:26 19.00s 0.00s 0.00s -bash
|
ss を見てみると 3 つの TCP セッションが張られていることが分かります。
| $ ss -t
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.101.0.12:ssh 10.101.0.11:36244
ESTAB 0 0 10.101.0.12:ssh 10.101.0.11:36246
ESTAB 0 0 10.101.0.12:ssh 10.101.0.11:36248
|
pstree で sshd(テスト時の PID は 686)のプロセスツリーは以下のようになっていました。
| $ pstree -c 686
sshd─┬─sshd───sshd───bash───pstree
├─sshd───sshd───bash
└─sshd───sshd───bash
|
ControlMaster を使った場合
ControlMaster の設定をする
~/.ssh/config へ以下のように ControlMaster の設定を実施します。
| $ cat ~/.ssh/config
Host 10.101.0.12
controlmaster auto
controlpersist 30
controlpath ~/.ssh/ControlMaster-%r-%h.%p
|
1 回目の SSH アクセス
~/.ssh ディレクトリは SSH アクセス前だと以下の状態でした(ControlMaster 〜 というファイルは存在しません)。
| $ ls -l ~/.ssh/
total 12
-rw------- 1 user user 396 Sep 29 22:32 authorized_keys
-rw------- 1 user user 104 Oct 2 11:30 config
-rw-r--r-- 1 user user 346 Oct 2 11:08 known_hosts
|
パスワードを聞かれます。
| $ ssh 10.101.0.12
user@10.101.0.12's password:
Last login: Sun Oct 2 11:26:45 2016 from 10.101.0.11
$
|
2 回目の SSH アクセス
2 回目のアクセス時にはパスワードを聞かれなくなります。
| $ ssh user@10.101.0.12
Last login: Sun Oct 2 11:35:25 2016 from 10.101.0.11
$
|
3 回目の SSH アクセス
同様に 3 回目のアクセス時にはパスワードを聞かれなくなります。
| $ ssh user@10.101.0.12
Last login: Sun Oct 2 11:37:01 2016 from 10.101.0.11
$
|
状態確認
w を確認すると、tty が 3 つ、割り当てられています。
| $ w
11:49:28 up 25 min, 3 users, load average: 0.00, 0.01, 0.04
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
user pts/0 10.101.0.11 11:35 0.00s 0.00s 0.00s w
user pts/1 10.101.0.11 11:37 12:27 0.00s 0.00s -bash
user pts/2 10.101.0.11 11:37 12:08 0.00s 0.00s -bash
|
ss を見てみると TCP セッションが 1 つしか張られていないのが分かります。
| $ ss -t
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.101.0.12:ssh 10.101.0.11:36250
|
pstree で sshd(テスト時の PID は 686)のプロセスツリーは以下のようになっていました。
| $ pstree -c 686
sshd───sshd───sshd─┬─bash───pstree
├─bash
└─bash
|
ソケットファイルの確認
SSH アクセス元(今回は 10.101.0.11)にログインし、~/.ssh 配下を確認すると ControlMaster 用ファイルが生成されています。
| $ ls -l ~/.ssh/
total 12
-rw------- 1 user user 396 Sep 29 22:32 authorized_keys
-rw------- 1 user user 104 Oct 2 11:30 config
srw------- 1 user user 0 Oct 2 11:36 ControlMaster-user-10.101.0.12.22
-rw-r--r-- 1 user user 346 Oct 2 11:08 known_hosts
|
file で確認するとソケットファイルになっているのが分かります。
| $ file ~/.ssh/ControlMaster-user-10.101.0.12.22
/home/user/.ssh/ControlMaster-user-10.101.0.12.22: socket
|
但し、全ての SSH セッションを exit しても、このソケットファイルは削除されません。また、このソケットファイルが残っている状態で再度、SSH アクセスを試みると、やはりパスワードは確認されません。
一定時間経過したソケットファイルを自動削除する(controlpersist 設定)
この挙動を避ける為には SSH アクセス元の ~/.ssh/config に controlpersist を設定しておきます。今回の例では「controlpersist 30」と設定済みですので、全ての SSH アクセスが終了してから 30 秒間、SSH アクセスが無ければ ControlMaster 用のソケットファイルが削除されます。全 SSH アクセスを切断し、30 秒経過してから ~/.ssh 配下を確認するとソケットファイルが削除されているのが分かります。
| $ sleep 30 ; ls -l ~/.ssh/
total 12
-rw------- 1 user user 396 Sep 29 22:32 authorized_keys
-rw------- 1 user user 104 Oct 2 11:30 config
-rw-r--r-- 1 user user 346 Oct 2 11:08 known_hosts
|
この状態で再度、SSH アクセスを実施すると(ソケットファイルが無く、新規の SSH アクセス扱いになるので)パスワードを聞かれます。
| $ ssh 10.101.0.12
user@10.101.0.12's password:
Last login: Sun Oct 2 11:57:12 2016 from 10.101.0.11
$
|
プロセスツリーの比較
比較の為にプロセスツリーの状態を再掲しておきます。
ControlMaster を使わない場合
| $ pstree -c 686
sshd─┬─sshd───sshd───bash───pstree
├─sshd───sshd───bash
└─sshd───sshd───bash
|
ControlMaster を使った場合
| $ pstree -c 686
sshd───sshd───sshd─┬─bash───pstree
├─bash
└─bash
|