linux巡检脚本,系统基本信息巡查,系统安全配置巡查,系统服务巡查,通用压缩备份,中间件版本巡查等。
0readme
#服务器巡检脚本
##功能简介
巡检linux服务器相关信息并发送邮件通知
##主要功能
1.服务基本信息检查
检查cpu,磁盘,内存,网络等信息
2.服务应用信息检查
检查各中间件版本信息
3.服务安全校验检查
检查linux系统各项安全配置
4.服务器日志备份灵活配置
配置日志通用备份及应用灵活备份
##配置区域
check.sh 开头配置区域
##启动方式:
#检查所有信息及发送邮件
sh sendMail.sh
#检查所有信息不发送邮件
sh inspection_check_tool.sh
#检查安全信息
sh check.sh
1.inspection_check_tool.sh 基本信息检查脚本
#!/bin/bash
date=date +%Y%m%d;
time=date +%H%M%S;
CHECK_ERROR_LOG=“./log/KaTeX parse error: Expected group after '_' at position 7: {date}_̲{time}_check.log”
if [ -n “$1” ]; then
CHECK_ERROR_LOG=“(cat /proc/cpuinfo | grep “physical id”|sort | uniq | wc -l);
logic_cpu_num=(cat /proc/cpuinfo | grep “cores”|uniq|awk -F: '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 2}̲'); cpu_freq=(cat /proc/cpuinfo | grep MHz | uniq | awk -F: '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 2}̲'); system_core…(uname -r);
system_versinotallow=(hostname | awk '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 1}̲'); systemc_env…(env | grep PATH);
mem_free=(df -h);
system_uptime=(cat /proc/loadavg);
system_ip=$(ip addr | grep 'inet ’ | grep -v 127.0.0.1 | awk '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 2}̲' | cut -f1 -d'…(/usr/sbin/dmidecode | grep -A 16 “Memory Device”|grep -E “Size|Locator”|grep -v Bank);
mem_total=(date +%Y);
day02=(date +%d);
df -hiP | sed ‘s/Mounted on/Mounted/’ > /tmp/inode;
df -hTP | sed ‘s/Mounted on/Mounted/’ > /tmp/disk ;
diskdata=$(df -TP | sed ‘1d’ | awk '(echo “$diskdata” | awk '{total+=KaTeX parse error: Expected 'EOF', got '}' at position 2: 3}̲END{print total…(echo “$diskdata” | awk '{total+=KaTeX parse error: Expected 'EOF', got '}' at position 2: 4}̲END{print total…((disktotal-diskused));
diskusedpercent=$(echo $disktotal $diskused | awk '{if($10){printf 100}else{printf “%.2f”,$2*100/KaTeX parse error: Expected 'EOF', got '}' at position 2: 1}̲}'); inodedata…(df -iTP | sed ‘1d’ | awk '(echo “$inodedata” | awk '{total+=KaTeX parse error: Expected 'EOF', got '}' at position 2: 3}̲END{print total…(echo “$inodedata” | awk '{total+=KaTeX parse error: Expected 'EOF', got '}' at position 2: 4}̲END{print total…((inodetotal-inodeused));
inodeusedpercent=$(echo $inodetotal $inodeused | awk '{if($10){printf 100}else{printf “%.2f”,$2*100/KaTeX parse error: Expected 'EOF', got '}' at position 2: 1}̲}'); report_Dis…((disktotal/1024/1024))“GB”;
report_DiskFree=diskusedpercent”“%”;
report_InodeTotal=((inodefree/1000))“K”;
report_InodeUsedPercent=“$inodeusedpercent”“%”;OS_Versinotallow=$(awk '{print KaTeX parse error: Expected 'EOF', got '}' at position 7: (NF-1)}̲' /etc/redhat-r…(cat /etc/redhat-release 2>/dev/null)
Kernel=(uname -o)
Hostname=(/usr/sbin/sestatus | grep "SELinux status: " | awk '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 3}̲') LastReboot=(who -b | awk '{print $3,KaTeX parse error: Expected 'EOF', got '}' at position 2: 4}̲') uptime=(uptime|exec awk ‘{ print $3 }’)echo -e -n ;
#echo -e 主机名:“\t"KaTeX parse error: Undefined control sequence: \t at position 35: …echo -e 服务器IP:"\̲t̲"system_ip;
#echo -e 系统内核:”\t"KaTeX parse error: Undefined control sequence: \t at position 32: …cho -e 操作系统版本:"\̲t̲"system_version;
echo -e “系统:Release”
echo -e “内核:Hostname”
echo -e “SELinux:default_LANG”
echo -e “当前时间:LastReboot”
echo -e “运行时间:$uptime”echo -e 磁盘使用情况: “\t”“\t”" “; join /tmp/disk /tmp/inode | awk '{print $1,$2,”|“,$3,$4,$5,$6,”|“,$8,$9,$10,$11,”|“,$12}'| column -t;
echo -e -n “硬盘总容量(GB) $report_DiskTotal”;
echo -e “硬盘剩余(GB) $report_DiskFree”;
echo -e “硬盘使用率% $report_DiskUsedPercent”;
echo -e “Inode总量 $report_InodeTotal”;
echo -e “Inode剩余 $report_InodeFree”;
echo -e “Inode使用率% KaTeX parse error: Undefined control sequence: \t at position 42: …echo -e CPU核数:"\̲t̲"cpu_core_num;
echo -e 物理CPU个数:”\t"KaTeX parse error: Undefined control sequence: \t at position 29: …ho -e 逻辑CPU个数:"\̲t̲"logic_cpu_num;
echo -e 系统环境变量:”\t"" “KaTeX parse error: Undefined control sequence: \t at position 49: …cho -e CPU的主频:"\̲t̲"cpu_freq;
echo -e 内存总大小:”\t"KaTeX parse error: Undefined control sequence: \t at position 30: …cho -e 内存空闲空间:"\̲t̲"mem_free;
echo -e 时间/系统运行时间/当前登陆用户/系统过去1分钟/5分钟/15分钟内平均负载/“\t”"\n"KaTeX parse error: Undefined control sequence: \t at position 79: …个数/最大的pid值线程/ "\̲t̲""\n"system_load;
if [[ (systemctl list-unit-files --type=service --state=enabled --no-pager | grep “enabled”)
process=KaTeX parse error: Expected 'EOF', got '#' at position 85: …p ".service") #̲ report informa…(echo “KaTeX parse error: Expected 'EOF', got '#' at position 23: … wc -l)" #̲自启动服务数量 report…(echo “$process” | wc -l)” #运行中服务数量
echo “自启动服务数量 $report_SelfInitiatedService”
echo "运行中服务数量 (/sbin/chkconfig | grep -E “:on|:启用”)
process=KaTeX parse error: Expected 'EOF', got '#' at position 71: …unning|正在运行") #̲ report informa…(echo “KaTeX parse error: Expected 'EOF', got '#' at position 23: … wc -l)" #̲自启动服务数量 report…(echo “$process” | wc -l)” #运行中服务数量
echo “自启动服务数量 $report_SelfInitiatedService”
echo “运行中服务数量 $report_RuningService”
ficnotallow=KaTeX parse error: Expected group after '^' at position 11: (grep -v "^̲#" /etc/rc.d/rc…/d’)
echo “$conf”report information#自启动程序数量
report_SelfInitiatedProgram=“$(echo $conf | wc -l)”
echo “自启动程序数量 $report_SelfInitiatedProgram”
#网络信息
echo “网络信息”
if [[ $OS_Version < 7 ]];then
/sbin/ifconfig -a | grep -v packets | grep -v collisions | grep -v inet6
else
for i in $(ip link | grep BROADCAST | awk -F: ‘{print $2}’);do ip add show $i | grep -E “BROADCAST|global”| awk '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 2}̲' | tr '\n' ' '…(ip route | grep default | awk '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 3}̲'|uniq) DNS=(grep nameserver /etc/resolv.conf| grep -v “#” | awk ‘{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 2}̲' | tr '\n' ','…//’)
echo “”
MAC=$(ip link | grep -v “LOOPBACK|loopback” | awk ‘{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 2}̲' | sed 'N;s/\n…//’)
echo -e "IP地址 "“MAC”
echo "默认网关 "“DNS”#端口信息
TCPListen=$(netstat -ntulp | column -t)
if [[ (ss -an | awk 'NR>1 {++s[KaTeX parse error: Expected 'EOF', got '}' at position 3: 1]}̲ END {for(k in …(ss -tan | awk 'NR>1 {++s[KaTeX parse error: Expected 'EOF', got '}' at position 3: 1]}̲ END {for(k in …TCPListen"
echo “------------------------------------------------------------------”
echo “$AllConnect”report information
report_Listen_num=“TCPListen”| sed ‘1d’ | awk ‘/tcp/ {print $4}’ | awk -F: '{print KaTeX parse error: Expected 'EOF', got '}' at position 3: NF}̲' | sort | uniq…(netstat -ntulp | column -t| awk ‘/tcp/ {print $4}’ | awk -F: ‘{print $NF}’|sort|uniq|tr “\n” " “)”
echo " "
echo " TCP 开放端口 $report_Listen"
echo " TCP 端口数 $report_Listen_num"#计划任务信息
Crnotallow=0
for shell in $(grep -v “/sbin/nologin” /etc/shells);do
for user in shell" /etc/passwd | awk -F: ‘{print $1}’);do
crontab -l -u KaTeX parse error: Expected 'EOF', got '&' at position 19: …r >/dev/null 2>&̲1 status=?
if [ user"
echo “-------------”
crontab -l -u (crontab -l -u $user | wc -l)
echo “”
fi
done
donescheduled task
find /etc/cron* -type f | xargs -i ls -l {} | column -t
let Crnotallow=Crontab+$(find /etc/cron* -type f | wc -l)report information
echo “计划任务数 $Crontab”
#sudoer权限
cnotallow=KaTeX parse error: Expected group after '^' at position 11: (grep -v "^̲#" /etc/sudoers…/d’)
echo “/etc/sudoers用户权限设置如下”
echo “$conf”#安装信息
echo “近期安装软件包信息”
echo “------------”
rpm -qa --last | head | column -tif [ $(ps -ef | grep defunct | grep -v grep | wc -l) -ge 1 ];then
echo “”
echo “zombie process”;
echo “--------”
ps -ef | head -n1
ps -ef | grep defunct | grep -v grep
fi
echo “”
echo “MEM 使用 TOP10”
echo “-------------”
echo -e “PID %MEM RSS COMMAND
$(ps aux | awk ‘{print $2, $4, $6, $11}’ | sort -k3rn | head -n 10 )”| column -t
echo “”
echo “cpu 使用 TOP10”
echo “------------”
top b -n1 | head -17 | tail -11#登录信息
echo “近期登陆信息”
echo “------------”
#last 不同系统版本格式不统一,此处不做格式化处理日期
last | head
#服务检查
echo “服务信息检查”
echo “------------”
sh ./check.sh $CHECK_ERROR_LOG
echo -e ‘************************************************************************************************************************’
2.check.sh 服务检查脚本
#!/bin/bash
#加载配置文件
#"-------------------------------------配置项开始------------------------------------------"
#是否开通用启日志备份
LOG_BAK=false
#是否启用应用备份
APP_BACK=false
#应用备份目录,支持多目录,将自动过滤不存在目录及文件
BACK_DIR='/opt/workspace/ferry_web_bak0423/ /opt/workspace/ferry/fadsfsaf '
#内存百分比
MEM_CONFIG=80
#CPU百分比
CPU_CONFIG=90
#不达标的磁盘百分比
DISK_CONFIG=80
#合格的openssl版本
#OPENSSL_CONFIG=(1.1.1k 1.1.1j 1.1.1q)
#openssl版本配置,支持正则,无则无需修改
OPENSSL_CONFIG=(1.1.1c 1.1.1b 1.1.1a 3.0.8)
#nginx版本配置,支持正则,无则无需修改
NGINX_VERSION_CONFIG=(1.22.0 1.22.1 1.18.0)
#NGINX_VERSION_CONFIG=(1.22.0 1.22.1 1.18.0)
#tomcat版本配置,支持正则,无则无需修改
TOMCAT_VERSION_CONFIG=(8.51.88.0 8.5.76)
#activemq版本配置,支持正则,无则无需修改
ACTIVEMQ_VERSION_CONFIG=(5.15.4 5.18.8)
#rabbitmq版本配置,支持正则,无则无需修改
RABBITMQ_VERSION_CONFIG=(3.8.1)
#zookeeper版本配置,支持正则,无则无需修改
ZOOKEEPER_VERSION_CONFIG=(3.8.1)
#mongo版本配置,支持正则,无则无需修改
MONGO_VERSION_CONFIG=(v4.41.212 v4.0.23)
#jetty版本配置,支持正则,无则无需修改
JETTY_VERSION_CONFIG=(9.4.22.v20191022)
#redis版本配置,支持正则,无则无需修改
REDIS_VERSION_CONFIG=(6.2.7)
#jdk版本配置,支持正则
JAVA_VERSION_CONFIG=(1.8.0_202)
#MONGO_VERSION_CONFIG=(v4.4.21 v4.0.23)
#日志备份的日志大小高于剩余空间的百分比时不进行备份
DISK_RANGE_PERCENT=80
#触发备份的文件大小
LOG_BAK_SIZE=20M
#需要备份的文件类型
LOG_BAK_TYPE='-name "*.log" -o -name "*.out"'
#备份的日志目录
LOG_BASE_CHECK_DIR=/opt
#可执行文件检查目录
EXECUTABLE_FILE_CHECK_DIR=/opt
#check需要输出日志的存放文件
mkdir -p ./log
#nginx日志100000行命中次数
ATTACK_NUMBER=6000
#tomcat关键日志截取,错误日志,不区分大小写
ERROR_LOG_KEY_WORK="OutOfMemoryError|PermGen space|StackOverflowError|TimeoutException|Java heap space|GC overhead limit exceeded|IOException|IllegalStateException|IllegalArgumentException|NullPointerException|NoClassDefFoundError|ClassNotFoundException|SocketTimeoutException|ConnectException|Connection timed out|net.TimeoutException|faFlsj"
#"-------------------------------------配置项结束------------------------------------------"
date=`date +%Y%m%d`;
time=`date +%H%M%S`;
CHECK_ERROR_LOG="./log/${date}_${time}_check.log"
if [ -n "$1" ]; then
CHECK_ERROR_LOG="$1"
fi
echo -e "巡检时间:$date $time"
#服务巡检项
inspectionItems=(
'内存情况'
'磁盘情况'
'CPU检查'
'防火墙开启情况'
'检查密码策略'
'检查空口令'
'缺省目录权限'
'潜在危险文件检查'
'环境变量检查'
'suid_guid授权检查'
'可执行文件检查权限检查'
'检查进程启动用户'
'检查tomcat指标'
'UIDS超级用户检查'
'nginx日志检查'
'openssl版本检查'
'nginx版本检查'
'tomcat版本检查'
'mongo版本检查'
'jetty版本检查'
'redis版本检查'
'activemq版本检查'
'rabbitmq版本检查'
'zookeeper版本检查'
'jdk版本检查'
)
echo -e "检查项\t\t\t是否符合要求\t\t\t备注"
#内存情况
MEM=`free -m | sed -n "2p" | awk '{printf $3/$2*100}'` ;
#磁盘情况
asc=`df -Ph |grep -v Filesystem | grep -v 文件系统| grep -v Filesystem | awk '{print $5,$6}' |awk -v var=$DISK_CONFIG -F '%' '{if($1>=var){print $1}}'`
passmax=`cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v ^# | awk '{print $2}'`
passlen=`cat /etc/login.defs | grep PASS_MIN_LEN | grep -v ^# | awk '{print $2}'`
#CPU检查
CPU=`top -bn 1 -c | sed -n '3p' | awk -F ':' '{print $2}'| awk '{printf $1}'`
passcheck=`sudo cat /etc/shadow | awk -F: '($2 == "" ) { print $1 }'`;
umask1=`cat /etc/profile | grep umask | grep -v ^# | awk '{print $2}'`;
umask2=`cat /etc/csh.cshrc | grep umask | grep -v ^# | awk '{print $2}'`;
umask3=`cat /etc/bashrc | grep umask | grep -v ^# | awk 'NR!=1{print $2}'`;
if [ ` echo "$MEM>=$MEM_CONFIG"|bc` -eq "1" ];
then echo -e "${inspectionItems[0]}\t\t不合格\t\t请检查内存是否超过$MEM_CONFIG"
else
echo -e "${inspectionItems[0]}\t\t合格"
fi
#磁盘情况
if test -n $asc
then echo -e "${inspectionItems[1]}\t\t合格"
else
echo -e "${inspectionItems[1]}\t\t不合格\t\t请确保磁盘空间占用$DISK_CONFIG以下"
fi
#CPU检查
if [ ` echo "$CPU<=$CPU_CONFIG"|bc ` -eq "1" ]
then echo -e "${inspectionItems[2]}\t\t\t合格"
else
echo -e "${inspectionItems[2]}\t\t\t不合格\t\t请检查CPU是否超过$CPU_CONFIG"
fi
#防火墙检查
if systemctl is-active --quiet iptables || systemctl is-active --quiet firewalld
then echo -e "${inspectionItems[3]}\t\t合格"
else
echo -e "${inspectionItems[3]}\t\t不合格\t\t请检查firewalld或iptables防火墙是否开启"
fi
#检查密码策略
if [ $passmax -le 90 -a $passmax -gt 0 -a $passlen -ge 8 ]
then echo -e "${inspectionItems[4]}\t\t合格"
else
echo -e "${inspectionItems[4]}\t\t不合格\t\t请检查/etc/login.defs是否设置密码策略"
fi
#检查空口令
if test -z $passcheck
then echo -e "${inspectionItems[5]}\t\t合格"
else
echo -e "${inspectionItems[5]}\t\t不合格\t\t请检查/etc/shadow是否存在空口令账号"
fi
#缺省目录权限
flags=0;
for i in $umask1 ;
do
if [ $i != "027" ];
then flags=1; break;
fi
done;
flags1=0;
for j in $umask2;
do
if [ $j != "027" ];
then flags1=1; break ;
fi
done ;
flags2=0;
for k in $umask3;
do
if [ $k != "027" ];
then flags2=1; break ;
fi
done ;
if [ $flags == 0 -a $flags1 == 0 -a $flags2 == 0 ];
then echo -e "${inspectionItems[6]}\t\t合格";
else
echo -e "${inspectionItems[6]}\t\t不合格\t\t请检查/etc/profile,etc/csh.cshrc,etc/bashrc是否均已设置umask";
fi
#潜在危险文件检查
if [ $( find / -maxdepth 3 -name "*.hosts.equiv" -or -name "*.rhosts" -or -name "*.netrc" -or -name "*id_rsa" 2>/dev/null | wc -l ) -eq 0 ] ;
then echo -e "${inspectionItems[7]}\t合格";
else
echo -e "${inspectionItems[7]}\t不合格\t\t请检查服务器是否存在.hosts.equiv,.rhosts,.netrc,*id_rsa类文件";
fi
#root用户环境变量的安全性
dirPri=$(find $(echo $PATH | tr ':' ' ') -type d \( -perm -0777 \) 2> /dev/null);
if [ -z "$dirPri" ] ;
then echo -e "${inspectionItems[8]}\t\t合格";
else
echo -e "${inspectionItems[8]}\t\t不合格\t\t请检查环境变量是否存在777权限目录";
fi
#suid_guid授权检查
if [ $( find / -perm -4000 -o -perm -2000 ! -user root -type f -print 2>/dev/null| wc -l ) -eq 0 ] ;
then echo -e "${inspectionItems[9]}\t合格";
else
echo -e "${inspectionItems[9]}\t不合格\t\t请检查是否存在非root认证的suid和guid文件";
fi
#可执行文件检查权限检查
if [ $( find $EXECUTABLE_FILE_CHECK_DIR -type f -executable \( -name "*.exe" -o -name "*.sh" -o -name "*.py" -o -name "*.coff" -o -name "*.elf" \) -exec ls -l {} \; | awk '$1 ~ /x$/{ print $0}' | wc -l ) -eq 0 ] ;
then echo -e "${inspectionItems[10]}\t合格";
else
echo -e "${inspectionItems[10]}\t不合格\t\t请检查 $EXECUTABLE_FILE_CHECK_DIR 目录下是否存在*.exe,*.sh,*.py,*.coff,*.elf类可执行(-executable)文件权限";
fi
#检查进程启动用户
if [ $(lsof -i -P -n | grep LISTEN | grep -v 'ssh\|rpc\|agen\|master' | awk '$3 ~ /root$/{print}'|wc -l) -eq 0 ] ;
then echo -e "${inspectionItems[11]}\t合格";
else
echo -e "${inspectionItems[11]}\t不合格\t\t请检查是否存在root用户启动的进程";
fi
#版本比较方法 version_elements:可用版本,支持正则,check_v:当前版本
function check_version {
#获取${!1} 第一个参数所对应变量的值为供选择的版本数组,第二个参数$2为需要检查的版本
local version_elements=("${!1}")
local check_v=$2
for i in "${version_elements[@]}"; do
if [[ "$check_v" =~ "$i" ]] ;
then
return 0
fi;
done
return 1
}
#检查tomcat指标
for tomcat_process in $(pgrep -f "catalina.home");
do
tomcat_path=$(ps -p $tomcat_process -o args= | grep -E -o "catalina.home=.* " | cut -d "=" -f2 | sed 's/.$//'| awk '{print $1}') ;
tomcat_conf="${tomcat_path}/conf/server.xml"
tomcat_port="lsof -i -P -n | grep $tomcat_process | grep -v 8005|head -n 1 | awk '{print $9}' | cut -d ':' -f 2"
version_path="${tomcat_path}/bin/version.sh"
tomcat_version=`$version_path | grep 'Server number'| cut -d ' ' -f 4`
flag="true";
echo -e "检查tomcat:${tomcat_path}" >> $CHECK_ERROR_LOG;
echo -e "--------------------------------\n" >> $CHECK_ERROR_LOG;
if grep -q 'user username="admin" password=' $tomcat_path/conf/tomcat-users.xml; then
echo -e "${inspectionItems[12]}:不合格; tomcat位置:$tomcat_path;Tomcat 启用了默认用户及密码. 请删除默认用户或修改默认密码." >> $CHECK_ERROR_LOG
flag=false;
fi
if [ $(cat $tomcat_conf | grep 'shutdown="SHUTDOWN"'|wc -l) -eq 0 ] ;
then echo -e "${inspectionItems[12]}\t\t合格\t\t tomcat位置:$tomcat_path" >> $CHECK_ERROR_LOG;
else
echo -e "${inspectionItems[12]}:不合格; tomcat位置:$tomcat_path;配置文件启用了SHUTDOWN来关闭程序" >> $CHECK_ERROR_LOG;
flag=false
fi;
if grep -q 'SSLEnabled="true"' $tomcat_path/conf/server.xml; then
echo "Tomcat is running with SSL enabled." >>$CHECK_ERROR_LOG;
fi
if curl -sSf "http://localhost:$TOMCAT_PORT/" 2>&1>/dev/null;
then
:
else
flag=false;
echo "Tomcat($tomcat_path) 服务无响应,请检查服务是否正常">> $CHECK_ERROR_LOG;
fi
#tomcat文件权限检查
if [[ $(find $tomcat_path \( -path $tomcat_path/logs -o -path $tomcat_path/conf \) -prune -o -type f -perm -744 ! -perm 744 -print |wc -l) -eq 0 ]]
then
:
echo ""
else
flag=false;
echo "Tomcat($tomcat_path) 文件权限应设置小于等于744,请设置:find $tomcat_path \( -path $tomcat_path/logs -o -path $tomcat_path/conf \) -prune -o -type f -perm -744 ! -perm 744 -print -exec chmod 744 {} \; ">> $CHECK_ERROR_LOG;
fi
#tomcat目录权限检查
if [[ $(find $tomcat_path \( -path $tomcat_path/logs -o -path $tomcat_path/conf \) -prune -o -type d -perm -644 ! -perm 644 -print |wc -l) -eq 0 ]]
then
:
else
flag=false;
echo "Tomcat($tomcat_path) 目录权限应设置小于等于644,请设置:find $tomcat_path \( -path $tomcat_path/logs -o -path $tomcat_path/conf \) -prune -o -type d -perm -644 ! -perm 644 -print -exec chmod 644 {} \; ">> $CHECK_ERROR_LOG;
fi
#tomcat日志权限检查
if [[ $(find $tomcat_path/logs/* $tomcat_path/conf/* -type f -perm -600 ! -perm 600 |wc -l) -eq 0 ]]
then
:
else
flag=false;
echo "Tomcat($tomcat_path/log $tomcat_path/conf/) 目录权限应设置小于等于600,请设置:find $tomcat_path/logs/* $tomcat_path/conf/* -type f -perm -600 ! -perm 600 -exec chmod 600 {} \; ">> $CHECK_ERROR_LOG;
fi
#禁用tomcat版本号
if [ -n "$tomcat_version" ];
then
flag=false;
echo "请禁用$tomcat_path版本号 vim $tomcat_path/lib/catalina.jar then search 'ServerInfo.properties' to edit set server.number='' " >> $CHECK_ERROR_LOG;
fi
if [[ "$flag" == "true" ]];
then
echo -e "${inspectionItems[12]}\t\t合格\t\t tomcat位置:$tomcat_path";
echo -e "${inspectionItems[12]}\t\t合格" >> $CHECK_ERROR_LOG;
echo " " >> $CHECK_ERROR_LOG;
else
echo -e "${inspectionItems[12]}\t\t不合格\t\t tomcat位置:$tomcat_path,详细请看 $CHECK_ERROR_LOG 日志文件";
echo -e "${inspectionItems[12]}\t\t不合格" >> $CHECK_ERROR_LOG;
echo " " >> $CHECK_ERROR_LOG;
fi
echo "------$tomcat_path 相关错误日志----------" >> $CHECK_ERROR_LOG
echo "关键字:$ERROR_LOG_KEY_WORK" >> $CHECK_ERROR_LOG
#tomcat 日志分析
#截取10日内日志文件1000000行分析,(没做日志切割的则是查的1000000行分析)关键错误日志前后20行,采用正则匹配
find $tomcat_path/logs/ -type f -mtime -10 -name "*catalina*" -exec tail -n 100000 {} \;| grep -E -i -A 20 -B 20 "$ERROR_LOG_KEY_WORK" >> $CHECK_ERROR_LOG;
#grep -E -i -A 20 -B 20 $ERROR_LOG_KEY_WORK >> $CHECK_ERROR_LOG;
echo "--------------------------------------------------------------" >> $CHECK_ERROR_LOG
done;
#if [ $flag = "true" ];
# then echo -e "${inspectionItems[12]}\t\t合格";
#else
# echo -e "${inspectionItems[12]}\t\t不合格";
#fi
#UIDS检查,是否存在除root外的超级用户
flag=true;
UIDS=`awk -F[:] 'NR!=1{print $3}' /etc/passwd`;
for i in $UIDS;
do if [ $i = 0 ];
then echo flag=false;break;
fi;
done;
if [ $flag = "true" ];
then echo -e "${inspectionItems[13]}\t合格";
else
echo -e "${inspectionItems[13]}\t不合格\t\t请检查/etc/passwd是否存在除root外的超管用户";
fi
#nginx相关检查
nginx_pids=`ps -ef|grep nginx | grep master| grep -v grep | awk '{print $2}'`;
for nginx_pid in ${nginx_pids[@]};do
nginxexe=`ls -l /proc/$nginx_pid/ |grep exe |awk '{print $11}'`;
openssl_v=`$nginxexe -V 2>&1 | tr '[:upper:]' '[:lower:]'| grep -o "openssl.*" |head -n 1|awk '{print $2}'`;
nginx_v=`$nginxexe -v 2>&1 | cut -d '/' -f 2`;
#nginx日志检查
nginx_log=$(
for log_path in $(ls -l /proc/$nginx_pid/fd/ |grep .log|grep -v error | awk '{print $11}' |uniq);
do
recent_access=$(tail -n 100000 $log_path);access_count=$(echo "$recent_access" | awk '{print $1}' | sort | uniq -c) ;
echo "$access_count" | while read line;
do
count=$(echo "$line" | awk '{print $1}'); ip=$(echo "$line" | awk '{print $2}');
if [ $count -gt $ATTACK_NUMBER ];
then echo "Warning: IP $ip has $count requests in the last $threshold lines;当前时间:`date`rrrr" ;
fi;
done;
done);
#openssl日志检查
if [ $(echo $nginx_log|awk 'BEGIN{RS="rrrr"} {print}' |sed '/^$/d'|wc -l) -eq 0 ] ;
then echo -e "${inspectionItems[14]}\t\t合格\t\t nginx位置:$nginxexe";
else
echo -e "${inspectionItems[14]}\t\t不合格\t\t nginx位置:$nginxexe;请检查是否近期是否存在访问超过$ATTACK_NUMBER次上的IP地址";
fi
#openssl版本检查
if check_version "OPENSSL_CONFIG[@]" "$openssl_v";
#if [[ "${OPENSSL_CONFIG[*]}" =~ "$openssl_v" ]] ;
then echo -e "${inspectionItems[15]}\t\t合格\t\t nginx位置:$nginxexe";
else
echo -e "${inspectionItems[15]}\t\t不合格\t\t nginx位置:$nginxexe;当前版本:$openssl_v,请安装指定版本:${OPENSSL_CONFIG[*]}";
fi;
#nginx版本检查
if check_version "NGINX_VERSION_CONFIG[@]" "$nginx_v";
#if [[ "${NGINX_VERSION_CONFIG[*]}" =~ "$nginx_v" ]] ;
then echo -e "${inspectionItems[16]}\t\t合格\t\t nginx位置:$nginxexe";
else
echo -e "${inspectionItems[16]}\t\t不合格\t\t nginx位置:$nginxexe;当前版本:$nginx_v,请安装指定版本:${NGINX_VERSION_CONFIG[*]}";
fi;
#nginx日志输出
echo "------$nginxexe 相关日志----------" >> $CHECK_ERROR_LOG
echo -e "匹配条件:同一IP在最近100000行内出现超过 $ATTACK_NUMBER 次" >> $CHECK_ERROR_LOG
echo -n $nginx_log|awk 'BEGIN{RS="rrrr"} {print}' |sed '/^$/d' >> $CHECK_ERROR_LOG
echo "--------------------------------------------------------------" >> $CHECK_ERROR_LOG
done
#tomcat版本检查
for tomcat_process in $(pgrep -f "catalina.home");
do
tomcat_path=$(ps -p $tomcat_process -o args= | grep -E -o "catalina.home=.* " | cut -d "=" -f2 | sed 's/.$//'| awk '{print $1}') ;
version_path="${tomcat_path}/bin/version.sh"
#version_path=$(ps -p $tomcat_process -o args= | grep -E -o "catalina.home=.* " | cut -d "=" -f2 | sed 's/.$//'| awk '{print $1"/bin/version.sh"}')
#tomcat_path=$(ps -p $tomcat_process -o args= | grep -E -o "catalina.home=.* " | cut -d "=" -f2 | sed 's/.$//'| awk '{print $1"/conf/server.xml" }') ;
tomcat_version=`$version_path | grep 'Server number'| cut -d ' ' -f 4`
#如果tomcat版本号显示被禁用,可以使用此项查看版本号
tomcat_version_r=`cat $tomcat_path/RELEASE-NOTES |grep "Tomcat Version"|awk '{print $4}'`
if check_version "TOMCAT_VERSION_CONFIG[@]" "$tomcat_version" -o check_version "TOMCAT_VERSION_CONFIG[@]" "$tomcat_version_r" ;
#if [[ "${TOMCAT_VERSION_CONFIG[*]}" =~ "$tomcat_version" ]] ;
then echo -e "${inspectionItems[17]}\t\t合格\t\t tomcat位置:$tomcat_path";
else
echo -e "${inspectionItems[17]}\t\t不合格\t\t tomcat位置:$tomcat_path;当前版本:$tomcat_version,请安装指定版本:${TOMCAT_VERSION_CONFIG[*]}";
fi;
done;
#mongodb版本检查
for mongo_pid in $(pgrep -f "mongo");
do
mongo_exe=`ls -l /proc/$mongo_pid/ | grep exe | awk '{print $11}'`
mongo_v=`$mongo_exe --version | head -n 1 | awk '{print $3}'`
if check_version "MONGO_VERSION_CONFIG[@]" "$mongo_v";
#if [[ "${MONGO_VERSION_CONFIG[*]}" =~ "$mongo_v" ]] ;
then echo -e "${inspectionItems[18]}\t\t合格\t\t mongo位置:$mongo_exe";
else
echo -e "${inspectionItems[18]}\t\t不合格\t\t mongo位置:$mongo_exe;当前版本:$mongo_v,请安装指定版本:${MONGO_VERSION_CONFIG[*]}";
fi;
done
# head -n 1 /opt/workspace/jetty-distribution-9.4.22.v20191022/VERSION.txt | awk '{print $1}'
for jetty_pid in $(pgrep -f "jetty");
do
jetty_path=`ls -l /proc/$jetty_pid/ | grep cwd | awk '{print $11}'`
jetty_v=`head -n 1 $jetty_path/VERSION.txt | awk '{print $1}'|cut -d '-' -f 2`
if check_version "JETTY_VERSION_CONFIG[@]" "$jetty_v";
#if [[ "${JETTY_VERSION_CONFIG[*]}" =~ "$jetty_v" ]] ;
then echo -e "${inspectionItems[19]}\t\t合格\t\t jety位置:$jetty_path";
else
echo -e "${inspectionItems[19]}\t\t不合格\t\t jety位置:$jetty_path;当前版本:$jetty_v,请安装指定版本:${JETTY_VERSION_CONFIG[*]}";
fi;
done
for redis_pid in $(pgrep -f "redis-server");
do
redis_exe=`ls -l /proc/$redis_pid/ | grep exe | awk '{print $11}'`
redis_v=`$redis_exe -v | awk '{print $3}' | cut -d '=' -f 2`
if check_version "REDIS_VERSION_CONFIG[@]" "$redis_v";
#if [[ "${REDIS_VERSION_CONFIG[*]}" =~ "$redis_v" ]] ;
then echo -e "${inspectionItems[20]}\t\t合格\t\t redis位置:$redis_exe";
else
echo -e "${inspectionItems[20]}\t\t不合格\t\t redis位置:$redis_exe;当前版本:$redis_v,请安装指定版本:${REDIS_VERSION_CONFIG[*]}";
fi;
done
#检查activemq版本
for activemq_process in $(pgrep -f "Dactivemq.home");
do
activemq_path=$(ps -p $activemq_process -o args= | grep -E -o "Dactivemq.home=.* " | cut -d "=" -f2 | sed 's/.$//'| awk '{print $1}') ;
version_path="${activemq_path}/bin/activemq"
activemq_v=`$version_path --version|grep ActiveMQ | awk '{print $2}'`
if check_version "ACTIVEMQ_VERSION_CONFIG[@]" "$activemq_v";
#if [[ "${ACTIVEMQ_VERSION_CONFIG[*]}" =~ "$activemq_v" ]] ;
then echo -e "${inspectionItems[21]}\t合格\t\t activemq位置:$activemq_path";
else
echo -e "${inspectionItems[21]}\t不合格\t\t activemq位置:$activemq_path;当前版本:$activemq_v,请安装指定版本:${ACTIVEMQ_VERSION_CONFIG[*]}";
fi;
done;
#检查 rabbitmq版本
rabbitmq_pid=`pgrep rabbitmq|head -n 1`
if [ -n "$rabbitmq_pid" ]; then
rabbitmq_v=`rabbitmqctl status | grep RabbitMQ | awk '{print $3}' 2>/etc/null`
rabbitmq_path=`ps -p $rabbitmq_pid -o args= | awk '{print$2}'`
if check_version "RABBITMQ_VERSION_CONFIG[@]" "$rabbitmq_v";
#if [[ "${RABBITMQ_VERSION_CONFIG[*]}" =~ "$rabbitmq_v" ]] ;
then echo -e "${inspectionItems[22]}\t合格\t\t rabbitmq位置:$rabbitmq_path";
else
echo -e "${inspectionItems[22]}\t不合格\t\t rabbitmq位置:$rabbitmq_path;当前版本:$rabbitmq_v,请安装指定版本:${RABBITMQ_VERSION_CONFIG[*]}";
fi;
fi
#检查zookeeper版本
for zookeeper_pid in $(pgrep -f "zookeeper");
do
zookeeper_exe=`ll /proc/$zookeeper_pid/ | grep cwd | awk '{print $11}'`;
zookeeper_v=`$zookeeper_exe/zkServer.sh version 2>/etc/null | grep version | awk '{print $4}'`;
if check_version "ZOOKEEPER_VERSION_CONFIG[@]" "$zookeeper_v";
#if [[ "${ZOOKEEPER_VERSION_CONFIG[*]}" =~ "$zookeeper_v" ]] ;
then echo -e "${inspectionItems[23]}\t合格\t\t zookeeper位置:$rabbitmq_path";
else
echo -e "${inspectionItems[23]}\t不合格\t\t zookeeper位置:$zookeeper_exe;当前版本:$zookeeper_v,请安装指定版本:${ZOOKEEPER_VERSION_CONFIG[*]}";
fi;
done
#检查jdk版本
java_v=`java -version 2>&1 | grep version | awk '{print $3}' | tr -d \"`
if [ -n "$java_v" ]; then
if check_version "JAVA_VERSION_CONFIG[@]" "$java_v";
#if [[ "${JAVA_VERSION_CONFIG[*]}" =~ "$java_v" ]] ;
then echo -e "${inspectionItems[24]}\t\t合格";
else
echo -e "${inspectionItems[24]}\t\t不合格\t\t\t 当前版本:$java_v,请安装指定版本:${JAVA_VERSION_CONFIG[*]}";
fi;
fi
#是否开启通用日志备份功能
if [[ "$LOG_BACK" = "true" ]];then
echo "通用备份日志"
echo "------------"
#此处禁止缩进
readarray -t files <<EOF
$(find $LOG_BASE_CHECK_DIR -type f \( -name "*.log" -o -name "*.out" \) -size +$LOG_BAK_SIZE -exec du -cb {} +)
EOF
need_space=`for file in "${files[@]}"; do echo $file ; done | grep total | cut -d ' ' -f 1`;
if [ "${#files[@]}" -ne 0 -a -n "$need_space" ] ;then
disk_free=`df --output=avail /opt/ | tail -n 1| awk -v var=$DISK_RANGE_PERCENT '{printf "%d\n", $1*1024*var/100}'`;
if [ ` echo "$disk_free > $need_space"|bc ` -eq "1" ]; then
date=`date +%Y%m%d`;
time=`date +%H%M%S`;
mkdir -p /opt/bak/$date;
#压缩日志
for file in "${files[@]}"; do echo $file ; done | grep -v total|awk '{print $2}' | xargs tar --absolute-names -czvf /opt/bak/$date/archive_${time}.tar.gz >/dev/null 2>&1 ;
#清空日志
for file in "${files[@]}"; do echo $file ; done |grep -v "total" | awk '{system("echo '' >" $2)}';
echo -e "$LOG_BASE_CHECK_DIR目录下所有$LOG_BAK_TYPE类型 日志备份完成,备份文件:/opt/bak/$date/archive_${time}.tar.gz";
echo -e "如需要还原备份日志请使用 tar -zxvf /opt/bak/$date/archive_${time}.tar.gz --absolute-names 命令,命令将解压备份日志到原来目录并覆盖掉现有日志,请确认后使用"
else
echo -e "opt可用磁盘空间不足,需要空间$need_space,所需空间$disk_free,无法压缩日志";
fi ;
else
echo -e "$LOG_BASE_CHECK_DIR目录无可压缩日志($LOG_BAK_TYPE)文件";
fi;
fi;
#备份
if [[ "$APP_BACK" = "true" ]];then
echo "应用服务备份\n备份目录$BACK_DIR"
echo "------------"
echo $BACK_DIR | awk '{system("ls -d " $0) }' 2>&1 >/dev/null|awk '{print $4 "目录不存在,将忽视此目录备份"}'
FILTING_DIR=`echo $BACK_DIR | awk '{system("ls -d " $0) }' 2>/dev/null`
need_space=`du -scb $FILTING_DIR | grep total | awk '{print $1}'`
disk_free=`df --output=avail /opt/ | tail -n 1| awk -v var=$DISK_RANGE_PERCENT '{printf "%d\n", $1*1024*var/100}'`;
if [ ` echo "$disk_free > $need_space"|bc ` -eq "1" ]; then
date=`date +%Y%m%d`;
time=`date +%H%M%S`;
mkdir -p /opt/bak/$date;
#压缩备份
tar --absolute-names -zcvf /opt/bak/$date/apps_${time}.tar.gz $FILTING_DIR >/dev/null 2>&1
echo -e " $BACK_DIR目录备份完成,备份文件:/opt/bak/$date/apps_${time}.tar.gz";
echo -e "如需要还原备份日志请使用 tar -zxvf /opt/bak/$date/apps_${time}.tar.gz --absolute-names 命令,命令将解压备份日志到原来目录并覆盖掉现有日志,请确认后使用"
else
echo -e "opt可用磁盘空间不足,需要空间$need_space,所需空间$disk_free,无法压缩日志";
fi ;
fi
3.邮件发送脚本
sendMail.sh
#/bin/bash
date=date +%Y%m%d;
time=date +%H%M%S;
Hostname=(ip addr | grep 'inet ’ | grep -v 127.0.0.1 | awk '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 2}̲' | cut -f1 -d'…{date}{date}KaTeX parse error: Expected 'EOF', got '#' at position 21: …}_inspect.log" #̲MAIL_CONTENT=`s…CHECK_ERROR_LOG"`
#echo Hostname 服务器巡检报告" -a CHECK_ERROR_LOG" > “Hostname ($system_ip) 服务器巡检报告” -a $CHECK_ERROR_LOG -a $CHECK_INSPECT_LOG xxx@qq.com bbb@qq.com