Skip to content

SSH で ControlMaster を使い、TCP セッションを集約する

通常、「3 つ同時に SSH ログインすれば 3 つの TCP セッション」が確立されます。しかし、ControlMaster という設定を行うと「同時に複数の SSH ログインを実行しても、1 つの TCP セッションだけで済む」ように出来ます。

ControlMaster を使わない場合

1 回目の SSH アクセス

パスワードを聞かれます。

1
2
3
4
$ 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 回目もパスワードを聞かれます。

1
2
3
4
$ 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 回目もパスワードを聞かれます。

1
2
3
4
$ 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 つ、割り当てられています。

1
2
3
4
5
6
$ 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 セッションが張られていることが分かります。

1
2
3
4
5
$ 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)のプロセスツリーは以下のようになっていました。

1
2
3
4
$ pstree -c 686
sshd─┬─sshd───sshd───bash───pstree
     ├─sshd───sshd───bash
     └─sshd───sshd───bash

ControlMaster を使った場合

ControlMaster の設定をする

~/.ssh/config へ以下のように ControlMaster の設定を実施します。

1
2
3
4
5
$ cat ~/.ssh/config
Host 10.101.0.12
  controlmaster auto
  controlpersist 30
  controlpath  ~/.ssh/ControlMaster-%r-%h.%p

1 回目の SSH アクセス

~/.ssh ディレクトリは SSH アクセス前だと以下の状態でした(ControlMaster 〜 というファイルは存在しません)。

1
2
3
4
5
$ 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

パスワードを聞かれます。

1
2
3
4
$ 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 回目のアクセス時にはパスワードを聞かれなくなります。

1
2
3
$ ssh user@10.101.0.12
Last login: Sun Oct  2 11:35:25 2016 from 10.101.0.11
$

3 回目の SSH アクセス

同様に 3 回目のアクセス時にはパスワードを聞かれなくなります。

1
2
3
$ ssh user@10.101.0.12
Last login: Sun Oct  2 11:37:01 2016 from 10.101.0.11
$

状態確認

w を確認すると、tty が 3 つ、割り当てられています。

1
2
3
4
5
6
$ 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 つしか張られていないのが分かります。

1
2
3
$ 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)のプロセスツリーは以下のようになっていました。

1
2
3
4
$ pstree -c 686
sshd───sshd───sshd─┬─bash───pstree
                   ├─bash
                   └─bash

ソケットファイルの確認

SSH アクセス元(今回は 10.101.0.11)にログインし、~/.ssh 配下を確認すると ControlMaster 用ファイルが生成されています。

1
2
3
4
5
6
$ 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 で確認するとソケットファイルになっているのが分かります。

1
2
$ 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 配下を確認するとソケットファイルが削除されているのが分かります。

1
2
3
4
5
$ 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 アクセス扱いになるので)パスワードを聞かれます。

1
2
3
4
$ 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 を使わない場合

1
2
3
4
$ pstree -c 686
sshd─┬─sshd───sshd───bash───pstree
     ├─sshd───sshd───bash
     └─sshd───sshd───bash

ControlMaster を使った場合

1
2
3
4
$ pstree -c 686
sshd───sshd───sshd─┬─bash───pstree
                   ├─bash
                   └─bash