自动化运维安全篇(0)_批量检测服务器异常进程

目标

定期或者不定期的批量检测线上所有服务器的进程,发现异常进程后自动将各台服务器对应的异常进程发邮件到管理员的邮箱。
构建原理:saltstackshell脚本、sendEmail。基于saltstack的配置下发执行功能,批量搜集异常进程,搜集到的异常进程用sendEmail发送邮件到管理员邮箱。
构建过程:saltstack机器以下称为master,待检测的机器称为a、b、c、d、e,发送邮件的机器称为mail。

功能脚本

异常进程的检测都是由a、b、c、d、e各自检测完成后将检测结构反馈给master(大大降低了master的负载和检测时间),然后master统一整理后下发给mail,然后由mail将每次的结果发送给管理员。 a、b、c、d、e的自检测脚本processmonitor.sh由master每次检测前重新下发。检测脚本内容如下(用了comm命令比diff简洁)

1
2
3
4
5
6
7
#!/bin/bash 

ps -ef|awk '{$1="";$2="";$3="";$4="";$5="";$6="";$7="";print $0}'|sed 's/^\s*//'|sort|uniq > /srv/salt/process.tmp
cat /srv/salt/process.white | sort > /srv/salt/white.tmp
comm -3 /srv/salt/process.tmp /srv/salt/white.tmp | grep -v "^\s"
rm -f /srv/salt/process.tmp
rm -f /srv/salt/white.tmp

该脚本每次检测时都由master重新下发一次,防止其被篡改,master下发和检测的sls文件分别如下:

1
2
3
4
5
6
7
8
9
10
11
$ cat syncfile.sls 
/srv/salt/processmonitor.sh:
file:
- managed
- source: salt://security/conf/process/processmonitor.sh
- user: root
- group: root
- mode: 700
$ cat checkproc.sls
/srv/salt/processmonitor.sh:
cmd: - run

白名单每次检测前用salt-cp命令来下发一次,也是为了防止其被篡改。主要的检测脚本如下(用到了salt-key、salt、salt-cp等关键性的命令):

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
50
51
52
53
54
55
56
57
58
59
60
61
$ cat checkprocess.sh 
#!/bin/bash

MASDIR="/srv/salt-zabbix/salt/security/conf/process"
MINDIR="/srv/salt"
LISTDIR="$MASDIR/list"
CMD="ps -ef"
HOSTS=`salt-key -L | grep -v 'Keys'

update() {
mkdir -p $LISTDIR > /dev/null 2>&1
for minion in $HOSTS; do
(
salt $minion cmd.run "$CMD"|grep -v "$minion:"|awk '{$1="";$2="";$3="";$4="";$5="";$6="";$7="";print $0}'|sed 's/^\s*//'|sort|uniq > $LISTDIR/$minion
echo 'awk {$1="";$2="";$3="";$4="";$5="";$6="";$7="";print $0}' >> $LISTDIR/$minion
echo 'sed s/^\s*//' >> $LISTDIR/$minion
echo -e "sort\nuniq" >> $LISTDIR/$minion
echo "/bin/bash /srv/salt/processmonitor.sh" >> $LISTDIR/$minion
)&
done
wait
}
check() {
for minion in $HOSTS; do
(
survive=`salt $minion test.ping`
if [ "$survive" == "" ]; then {
echo "\*\*\*\*\*\*salt-minion timeout!\*\*\*\*\*\*$minion"
exit 1
} fi
salt-cp $minion $MASDIR/list/$minion $MINDIR/process.white > /dev/null
salt $minion state.sls security.check.process.syncfile > /dev/null salt $minion
state.sls security.check.process.checkproc > $MASDIR/$minion.tmp
flag=`grep "stdout:" $MASDIR/$minion.tmp|awk '{$1="";print $0}'| grep -v "^$"|sed 's/^\s*//'|grep -v "rsync -artzI -R"`
revalue=`grep -v '^ ' $MASDIR/$minion.tmp|grep -v '^-'|grep -v '^$'|grep -v 'Summary'|grep -v 'Succeeded'|grep -v 'Failed'|grep -v 'Total'|grep -v "$minion"| grep -v "rsync -artzI -R"`
if [ "$flag" == "" ]; then
echo "Process OK!******$minion"
else {
echo "Process Warning!******$minion"
echo "$flag"
if [ "$revalue" != "" ]; then
echo "$revalue"
fi
}
fi
rm -f $MASDIR/$minion.tmp
)&
done
wait
}

case "$1" in
update)
update
;;
check)
check
;;
*)
echo $"Usage:{update|check}"
esac

脚本中的check()函数用来检测异常进程,update()函数主要用来更新某个时间点认为安全的进程,即用来自动更新白名单的啦。

联动脚本

所有功能性的脚本都已经具备了,现在将这些脚本联动起来。master上负责执行检测和下发检测结果并记录日志的脚本:

1
2
3
4
5
6
7
8
9
#!/bin/bash 
DATE=`date "+%Y-%m-%d %H:%M"`
cd /opt/monitor/check/
./checkprocess.sh check > proessreport.tmp
echo $DATE >> logs/checkproess.log
cat proessreport.tmp >> logs/checkproess.log
echo "" >> logs/checkproess.log
/usr/bin/salt-cp mail-key proessreport.tmp /opt/monitor/salt_check/proessreport.tmp
rm -f proessreport.tmp

发送邮件的mail-key主机的邮件发送脚本就不写了,敏感信息太多。sendEmail邮件发送脚本是一个通用的perl脚本,网上搜搜就能找到了。只要将各个脚本的执行时间耦合好,就能愉快的正常执行和检测异常进程了。

----------------本文结束 感谢阅读----------------