编程人 cdmana.com

shell脚本:监控httpd进程、封IP、统计普通用户数

通过shell脚本监控httpd进程数

需求:
1.每10秒检测一次httpd进程数,当大于500时需要自动重启一下Apache服务,并检测是否重启成功
2.如果重启失败,再重启一次,最大失败次数超过5次立即发邮件通知管理员,并且脚本不再继续运行
3.如果重启成功,1分钟之后再次检测httpd进程,如果正常还是继续执行之前的操作(每10秒重启一次),若进程数还是大于500,则邮件通知管理员,并且该检测脚本不再继续运行

脚本思路:

通过 pgrep -l httpd|wc -l或 ps -C httpd --no-heading|wc -l检测进程数,进行判断

#!/bin/bash
#定义重启Apache服务的脚本
function check_apache()
{
    
    count=0
    for i in `seq 1 5`
    do
	/usr/local/apache/bin/apachectl -k restart 2>/tmp/apache.err
	#如果Apache重启不成功,则计数变量加1
	if [ ! $? -eq 0 ]
	then
	    count=$[$count+1]
	else
	    break
	fi
    done
    #如果Apache重启失败5次,则发送邮件通知管理员
    if [ $count -eq 5 ]
    then
	python mail.py asnfy@qq.com "Apache进程数大于500,重启失败" "`head -1 /tmp/apache.err`" 
	exit
    fi
}

while :
do
    #每10秒检测一次httpd进程数
    n=`ps -C httpd --no-heading|wc -l`
    #如果大于500,则重启
    if [ $n -ge 500 ]
    then
	check_apache
	sleep 60
	#重启1分钟后进程数仍然大于500,则通知管理员并退出脚本
	n1=`pgrep -l httpd|wc -l`
	if [ $n1 -ge 500 ] 
	then
	    python mail.py asnfy@qq.com "Apache重启1分钟后进程数仍然大于500" "请登录服务器排查问题" 
	    exit
	fi
    fi
    sleep 10
done

通过shell脚本封请求数异常的IP

需求:
1.通过分析访问日志,将1分钟内请求超过100次的IP封掉
2.每半小时将不再请求或请求量很小的IP解封
3.访问日志路径/data/logs/access.log

访问日志示例:

192.168.234.1 - - [22/Oct/2019:20:34:07 +0800] "GET / HTTP/1.1" 200 53570 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" "-"
192.168.234.1 - - [22/Oct/2019:20:34:07 +0800] "GET /wp-includes/css/dist/block-library/style.min.css?ver=5.2.3 HTTP/1.1" 301 169 "http://www.blog.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" "-"
192.168.234.1 - - [22/Oct/2019:20:34:07 +0800] "GET /wp-includes/css/dist/block-library/theme.min.css?ver=5.2.3 HTTP/1.1" 301 169 "http://www.blog.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" "-"

脚本思路:
1.通过data命令匹配日志文件中第二列过滤出前1分钟的访问记录,将请求数大于100的IP记录到临时文件ban_ip.list中
2.通过for循环遍历临时文件ban_ip.list每行的IP地址,使用iptables禁掉
3.通过iptables -nvL INPUT命令查看第一列(pkts)被封IP发送数据包的个数,当发送的数据包小于5时,解封(每半小时执行一次)

#!/bin/bash
#定义封IP方法
function ban_ip()
{
    
    t=`date -d "-1 min" +%Y:%H:%M`
    log=/data/logs/access.log
    #当IP前一分钟请求数大于100,记录到临时文件
    egrep "$t:[0-9]+" $log|awk '{print $1}'|sort -n|uniq -c|sort -n|awk '$1>100 {print $2}' >/tmp/ban_ip.list
    #当记录IP的临时文件不为空时,开始封IP
    ban_n=`wc -l /tmp/ban_ip.list|awk '{print $1}'`
    if [ $ban_n -ne 0 ]
    then
	for ip in `cat /tmp/ban_ip.list`
	do
	  iptables -I INPUT -s $ip -j REJECT
	done
    fi
}
#定义解封IP的方法
function allow_ip()
{
    
    #将发送数据包小于5的被封IP记录到临时文件
    iptables -nvL INPUT|sed '1d'|awk '$1<5 {print $8}' >/tmp/allow_ip.list
    #当临时文件不为空时,开始解封IP
    allow_n=`wc -l /tmp/allow_ip.list|awk '{print $1}'`
    if [ $allow_n -ne 0 ]
    then
	for ip in `cat /tmp/allow_ip.list` 
	do
	  iptables -D INPUT -s $ip -j REJECT
	done
    fi
    #清空iptables计数器(记录数据包那一列的值将被清零)
    iptables -Z
}
#执行封IP操作,但每半小时才执行一次解封IP操作
d=`date +%M`
if [ $d == "00" ]||[ $d == "30" ]
then
    allow_ip
    ban_ip
else
    ban_ip
fi

补充:
1.将脚本加入crontab任务计划设置每分钟执行一次即可
2.日志文件需要每天切割一次(因为通过年:时:分的方式过滤出的结果,如日志不每天做切割,过滤出的前一分钟IP访问记录将不只是今天的数据)

统计系统中的普通用户数量

需求:
1.统计linux系统中的普通用户有多少个

脚本思路:
1.通过配置文件/etc/passwd第三列的uid判断是否为普通用户
2.在centos5/6版本中,uid大于等于500即为普通用户,centos7版本中,uid大于等于1000即为普通用户
3.通过配置文件/etc/redhat-release文件判断centos版本

#!/bin/bash
#获取centos版本号
version=`awk -F 'release ' '{print $2}' /etc/redhat-release |cut -d '.' -f1`

function user()
{
    
    if [ $1 -eq 0 ]
    then 
	echo "系统中没有普通用户"
    else
	echo "系统中普通用户数为:$1"
    fi
}

case $version in
    5|6)
	n=`awk -F ':' '$3>=500' /etc/passwd |wc -l`
	user $n
	;;
    7)
	n=`awk -F ':' '$3>=1000' /etc/passwd |wc -l`
	user $n
	;;
    *)
	echo "该脚本只支持centos5/6/7版本."
	;;
esac
Scroll to Top