我撰写本文原来的意图是想把“复制SSH渠道”和"copy SSH Session"这样的功能从远程ssh客户端中剔除掉.因此想到可以在SSH服务端设置一下,但查阅了sshd_config的man手册,发现里面的看起来限制ssh连接数量的参数(MaxSessions ,ClientAliveCountMax等)在复制SSH渠道中并不好用,即一个远程ssh客户端可以通过这种方式几乎无限制的建立ssh会话,未免让人觉得“不爽”。
例如,我正在做一件事情,突然想出去,但我不想改变当前终端中的任何操作,也不想让别人在我出去后过来动我正在做的工作,那我可以简单的按下Ctrl+S来锁定终端数据输入输出(尽管输入并不能锁定,但输入将对用户不可见),当我回来时可以再通过按下Ctrl+Q来解除“屏幕锁定”,这样不熟悉Linux的同事就不会来干扰我的工作,而不用锁定整个系统。但自己却知道我可以通过复制SSH渠道/会话的方式来建立一个可用的新的SSH连接,而这样的操作在以后繁杂的工作中是不可能逐一去查看的,因此想直接写个shell脚本来实现这个需求。
思路还是比较简单的,代码也没有几行。首先这个脚本一定有循环,这样才能起到持续化监测的能力,通过命令不断的查询sshd端口的连接用户和每个用户的连接数量,如果数量超过我设定的最大连接数量,则再通过命令找到这些连接的会话,再通过命令结束这些会话,从而实现目的。
但这其中有几个问题需要考虑:
-
用户按键,特别是快捷键(如Ctrl+D,Ctrl+C或Ctrl+\等的处理)
-
pts的数值可能会shell脚本中的最大值,除非新登录的用户的pts数值只增加不减少
-
PAM安全模块也许有更好的解决方案(shell脚本肯定不是最佳方案)
通过测试的脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#!/bin/bash
# This shell script will knock out extra ssh connection
# max_number_of_ssh_client
max_number_of_ssh_client=3
# lsof is essential
if
[[ ! -x `
which
lsof
` ]];
then
yum
install
lsof
-y
RETVAL=$?
if
[[
"$RETVAL"
-
ne
"0"
]];
then
echo
"ERROR: can NOT use lsof command, please check your internet connection or install lsof by manual! "
exit
$RETVAL
fi
else
# TODO
# for awk, grep, etc
echo
"SUCCESS: This shell script will knock out extra ssh connection "
fi
# a main worker
# loop
while
: ;
do
ssh_port=`
netstat
-anopt |
grep
sshd |
awk
'{print $4}'
|
awk
-F
':'
'{print $2}'
|
grep
-
v
^$ |
uniq
`
ssh_clients=`
lsof
-i:$ssh_port |
grep
\> |
awk
'{print $9}'
|
awk
-F
':'
'{print $(NF-1)}'
|
uniq
|
awk
-F
'>'
'{print $2}'
`
for
ssh_client
in
$ssh_clients;
do
number_of_ssh_client=`
lsof
-i:$ssh_port |
grep
$ssh_client |
wc
-l`
if
[[ $number_of_ssh_client -gt $max_number_of_ssh_client ]];
then
number_pts=`w -hs |
grep
$ssh_client |
awk
'{print $2}'
|
awk
-F
'/'
'{print $2}'
|
awk
'BEGIN {max=0} {if ($1>max) max=$1 fi} END {print max}'
`
# TODO
# another solution maybe exist
# kill extra logins
pkill -
kill
-t pts/$number_pts
if
[[ $? -
eq
0 ]];
then
echo
"SUCCESS: extra connections $ssh_client@pts/$number_pts has been knocked out! "
else
echo
"WARNNING: can NOT knock out extra connections! "
fi
else
# TODO
# too many INFO displayed
echo
"INFO: number of ssh connections is NORMAL! "
# sleep 1
sleep
1
fi
done
done
|
注释:脚本中的几个TODO可以多考虑考虑,其次里面的蹩脚英语请自行略过,:)