centos系统等保检查脚本

#!/usr/bin/bash
#本脚本根据等保2.0要求,用于检测linux服务器
#version:1.2
#优化:增加联通部分基线扫描项,并增加不合规修改方式
#E-mail:xiaochenlinux.cn
#Author:chenxiaojian
#Development time:2022-04-24

#检测是有存在空密码用户
empty_password()
{
    a=`awk -F ":" '($2==""){print $1}' /etc/shadow`
    if [[ `echo $a |wc -l` -gt 0 ]];then
	echo "密码为空的用户有:"
	if [ -n $a ];then
		echo "-"
	else
		echo $a
	fi
	echo "-"
	echo "-"
	
	echo "-----------------------------------------------"
    fi
}

#检测密码规则是否符合要求
password_validity_period()
{ 
    q=/etc/login.defs
    #检查密码最长有效期
    a=`cat $q | grep "^PASS_MAX_DAYS"`
    if  [[ `echo $a| awk -F " " '{print $2}'` -gt 90 ]];then
	echo "密码最长有效期大于90天"
	echo $a
	echo "不合规"
	echo "请在$q中将修改PASS_MAX_DAYS值,如:PASS_MAX_DAYS 90"
	
	echo "-----------------------------------------------"
    fi

    #检查密码长度
    b=`cat $q| grep "^PASS_MIN_LEN"`
    if [[ `echo $b | awk -F " " '{print $2}'` -lt 10 ]];then 
	echo "密码长度小于8位数"
	echo $b
	echo "不合规"
	echo "请在$q中将修改PASS_MIN_LEN值,如:PASS_MIN_LEN 8"
	
	echo "-----------------------------------------------"
    fi

    #检查密码过期提醒
    c=`cat $q| grep "^PASS_WARN_AGE"`
    if [[ `echo $c | awk -F " " '{print $2}'` -lt 7 ]];then 
	echo "密码过期提醒少于7天"
	echo $c
	echo "不合规"
	echo "请在$q中将修改PASS_WARN_AGE值,如:PASS_WARN_AGE 7"
	
	echo "-----------------------------------------------"
    fi
}

#检查是否设置登录错误锁定
user_login_error_locked()
{
    q=/etc/pam.d/system-auth
    a=`cat $q |grep "^auth" |grep "requisite" |grep "pam_tally2.so"`
    #检查登录超时是否显示root
    even=`echo $a |sed 's/ /\n/g' | grep "^even_deny_root"`
    if [[ `echo $even |wc -l` != 1 ]];then
	echo "登录超时中未对root限制,或重复设置"
	if [ -n $even ];then
		echo "-" 
	else
		echo $even
	fi
	echo "不合规"
	echo "请在检查$q,如:auth required pam_tally2.so even_deny_root"
	
	echo "-----------------------------------------------"
    fi
    #检查用户连续登陆错误的最大次数
    dey=`echo $a |sed 's/ /\n/g' | grep "^deny="`
    if [[ `echo $c |wc -l` != 1 ]];then
        echo "未设置用户连续登录错误,或重复设置"
        if [ -n $bey ];then
                echo "-"
        else
                echo $bey
        fi
        echo "不合规"
        echo "请在检查$q 如:auth required pam_tally2.so deny=3 #连续密码错误3次锁定账号"
	
        echo "-----------------------------------------------"
    fi
    #检查是否设置普通用户登录错误锁定时间
    unlock=`echo $a |sed 's/ /\n/g' | grep "^unlock_time="`
    if [[ `echo $unlock |wc -l` != 1 ]];then
        echo "未设置普通用户登录错误锁定时间,或重复设置"
        if [ -n $unlock ];then
                echo "-"
        else
                echo $unlock
        fi
        echo "不合规"
        echo "请在检查$q,如:auth required pam_tally2.so unlock_time=40 #设定用户锁定40秒后解锁"
	
        echo "-----------------------------------------------"
    fi
    #检查是否设置root登录错误锁定时间
    root_unlock=`echo $a |sed 's/ /\n/g' | grep "^root_unlock_time=40"`
    if [[ `echo $root_unlock |wc -l` != 1 ]];then
        echo "未设置root用户登录超时锁定时间,或重复设置"
        if [ -n $root_unlock ];then
                echo "-"
        else
                echo $root_unlock
        fi
        echo "不合规"
        echo "请在检查$q,如:auth required pam_tally2.so root_unlock_time=40 #设置root用户锁定40秒后解锁"
	
        echo "-----------------------------------------------"
    fi
}


#检查密码复杂度策略
chack_password_Complexity_Policy()
{
    q=/etc/pam.d/system-auth
    a=`cat $q |grep "^password" |grep "requisite" |grep "pam_cracklib.so"`
    #检查登录失败尝试次数
    ret=`echo $a |sed 's/ /\n/g' | grep "^retry="`
    if [[ `echo $ret |wc -l` != 1 ]];then
	echo "未设置登录失败可重试次数,或重复设置"
        if [ -n $ret ];then
                echo "-"
        else
                echo $ret
        fi
        echo "不合规"
	echo "请在检查$q,如:password requisite pam_cracklib.so retry=3 #登录失败可重试3次"
	
	echo "-----------------------------------------------"
    fi
    #检查密码最小长度
    min=`echo $a |sed 's/ /\n/g' | grep "^minlen="`
    if [[ `echo $min |wc -l` != 1 ]];then
        echo "未否设置密码最小长度限制,或重复设置"
        if [ -n $min ];then
                echo "-"
        else
                echo $min
        fi
        echo "不合规"
        echo "请在检查$q,如:password requisite pam_cracklib.so minlen=8 #密码最小长度为8位"
	
        echo "-----------------------------------------------"
    fi
    #检查密码最少包含几个大写字母
    ucr=`echo $a |sed 's/ /\n/g' | grep "^ucredit="`
    if [[ `echo $ucr |wc -l` != 1 ]];then
        echo "未设置字母大写参数,或重复设置"
        if [ -n $ucr ];then
                echo "-"
        else
                echo $ucr
        fi
        echo "不合规"
        echo "请在检查$q,如:password requisite pam_cracklib.so ucredit=-1 #设定用户密码最少有1个大写字母"
	
        echo "-----------------------------------------------"
    fi
    #检查密码最少包含几个小写字母
    lcr=`echo $a |sed 's/ /\n/g' | grep "^lcredit="`
    if [[ `echo $lcr |wc -l` != 1 ]];then
        echo "未设置字母小写参数,或重复设置"
        if [ -n $lcr ];then
                echo "-"
        else
                echo $lcr
        fi
        echo "不合规"
        echo "请在检查$q,如:password requisite pam_cracklib.so lcredit=-1 #设定用户密码最少有1个小写字母"
	
        echo "-----------------------------------------------"
    fi
    #检查密码最少包含几个数字个数
    dcr=`echo $a |sed 's/ /\n/g' | grep "^dcredit="`
    if [[ `echo $dcr |wc -l` != 1 ]];then
        echo "未设置数字个数参数,或重复设置"
        if [ -n $bcr ];then
                echo "-"
        else
                echo $bcr
        fi
        echo "不合规"
        echo "请在检查$q,如:password requisite pam_cracklib.so dcredit=-1 #设定用户密码最少有1个数字"
	
        echo "-----------------------------------------------"
    fi
    #检查密码最少包含几个特殊字符
    ocr=`echo $a |sed 's/ /\n/g' | grep "^ocredit="`
    if [[ `echo $ocr |wc -l` != 1 ]];then
        echo "未设置特殊字符参数,或重复设置"
        if [ -n $ocr ];then
                echo "-"
        else
                echo $ocr
        fi
        echo "不合规"
        echo "请在检查$q,如:password requisite pam_cracklib.so ocredit=-1 #设定用户密码最少用1个特殊字符"
	
        echo "-----------------------------------------------"
    fi
}

#检查登录超时时间
login_timed_out()
{
    a=/etc/profile
    b=`cat $a |grep "^TMOUT"`
    if [[ `echo $b |awk -F "=" '{print $2}'` -ge 300 ]];then
        echo "登录超时时间大于5分钟"
        if [ -n $b ];then
                echo "-"
        else
                echo $b
        fi
        echo "不合规"
	echo "请在检查$a,如:TMOUT=300"
        
        echo "-----------------------------------------------"
    else
	if [[ `echo $b |wc -l` -ge 1 ]];then
            echo "未设置登录超时时间"
            if [ -n $b ];then
                    echo "-"
            else
                    echo $b
            fi
            echo "不合规"
	    echo "请在检查$a,如:TMOUT=300"	
            
            echo "-----------------------------------------------"
	fi
    fi
}

#检查是否开启telnet服务
check_telnet()
{
    #systemctl status telnet.socket
    service telnet status &> /dev/null
    a=`echo $?`
    if [[ $a -eq 0 ]];then
        echo "telnet服务处于开启中"
	echo "-"
	echo "不合规"
	echo "建议关闭telnet服务,如:service telnet stop 或service xinetd stop"
        
        echo "-----------------------------------------------"	
    fi
}

#检查文件权限
check_u()
{
    if [[ `echo $u` == "rw-" ]];then
	check_g
    elif [[ `echo $u` == "r--" ]];then
	check_g	
    elif [[ `echo $u` == "---" ]];then
	check_g
    else
	echo "检查${pa}所属主权限是否正确"
        if [ -n $u ];then
                echo "-"
        else
                echo $u
        fi
        echo "不合规"
	echo "请修改为:644,如:chmod 644 文件名"
    fi
}

check_g()
{
    if [[ `echo $g` == "r--" ]];then
	check_o
    elif [[ `echo $g` == "---" ]];then
	check_o
    else
	echo "检查$pa所属组权限是否正确"
        if [ -n $g ];then
                echo "-"
        else
                echo $g
        fi
        echo "不合规"
	echo "请修改为:644,如:chmod 644 文件名"
    fi
}

check_o()
{
    if [[ `echo $o` == "r--" ]];then
	echo " " 
    elif [[ `echo $o` == "---" ]];then
	echo " "
    else
 	echo "检查$pa其它用户权限是否正确"
        if [ -n $o ];then
                echo "-"
        else
                echo $o
        fi
        echo "不合规"
	echo "请修改为:644,如:chmod 644 文件名"
    fi
}

check_file()
{
    #检查passwd权限是否正确
    pa=/etc/passwd
    a=`ls -l $pa |awk -F "." '{print $1}'`
    u=`echo $a | cut -c 2-4`
    g=`echo $a | cut -c 5-7`
    o=`echo $s | cut -c 8-10`
    if [[ `echo $a ` != "-rw-r--r--" ]];then 
	check_u
        
        echo "-----------------------------------------------"	
    fi

}

#检查是否禁止root登录
deny_root_login()
{
	a=/etc/ssh/sshd_config
	b=`cat $a |grep -E "^PermitRootLogin|^#PermitRootLogin"|grep -v "prohibit-password$"`
	if [ `echo $b |grep -E "^#|yes$" |wc -l` -ge 1 ];then
		echo "检查是否禁止root登录"
        	if [ -n "$b" ];then
                	echo "-"
        	else
                	echo $b
        	fi
        	echo "不合规"
		echo "请在$a中,将#PermitRootLogin yes 改为PermitRootLogin no"
	elif [ `echo $b |grep "^PermitRootLogin no$" |wc -l` -ge 1 ];then
		echo "检查是否禁止root登录"
        	if [[ -n $b ]];then
                	echo "-"
        	else
                	echo $b
        	fi
        	echo "达标"
			echo "-"
	else
		echo "检查是否禁止root登录"
		echo "-"
		echo "不达标"
		echo "请在$a中修改为PermitRootLogin no"
	fi
        
        echo "-----------------------------------------------"	
}

#检查是否已禁用多余和默认用户登录服务器
check_user_login(){
	#a=`cat /etc/passwd |grep -E "^games|^news|^ftp|^1p"`
	for i in `cat /etc/passwd |grep -E "^games|^news|^ftp|^1p" | sed 's/\ //g'`
	do
		echo "检查是否禁止多余用户或默认用户登录服务器"
		if [[ `echo $i  |grep "nologin$" |awk -F/ '{print $5}'` == nologin ]];then
			echo "-"
	        else
                	echo $i
		fi
        	echo "不合规"
	 	echo "请检查$i用户,是否设置为/sbin/nologin"
        
        echo "-----------------------------------------------"
	done
}

#检查是否限制用户su到root
chack_su(){
	q=/etc/pam.d/su
	a=`cat $q |grep "^auth" |grep "sufficient" |grep "pam_rootok.so"`
	gro=`echo $a |sed 's/ /\n/g' | grep "^group=wheel"`
	if [[ `echo $gro |wc -l` != 1 ]];then
		echo "未否设置除wheel组之外的用户su到root,或重复设置"
        	if [ -n $gro ];then
                	echo "-"
        	else
                	echo $gro
        	fi
        	echo "不达标"
		echo "请检查$q,如:auth required pam_wheel.so group=wheel #表明只有wheel组的成员可以使用su命令成为root用户,可以使用:usermog -g wheel username #把用户添加到wheel组"
	fi
        
        echo "-----------------------------------------------"
}

#检查文件、目录缺省权限和命令行界面超时时间
chack_umask(){
	q=/etc/profile
	a=`cat $q |grep "^    umask" |tail -1`
	echo "检查umsak设置是否达标"
	um=`echo $a |awk -F " " '{print $2}'`
	if [[ `echo $um` != "027" ]];then
		echo $um
		echo "不达标"
		echo "请检查$q,如:umask 027"
	fi
	
        echo "-----------------------------------------------"
	echo "检查命令行超时时间是否达标"
	ex=`cat $q |grep "^export" |grep "TMOUT="`
        if [ -n $ex ];then
              	echo "-"
		echo "不达标"
		echo "请检查$q,是否设置命令行超时时间,或设置大于5分钟,如:export TMOUT=300 #超时时间为300秒"
        else
               	echo $ex
		if [[ `echo $ex |wc -l` == 1 ]];then
			if [[ `echo $ex |awk -F= '{print $2}'` -gt "300" ]];then
				echo "不达标"
				echo "请检查$q,是否设置命令行超时时间,或设置大于5分钟,如:export TMOUT=300 #超时时间为300秒"
			fi
		else
			echo "不达标"
			echo "请检查$q,是否设置命令行超时时间,如:export TMOUT=300 #超时时间为300秒"
		fi
	fi
	
       	echo "-----------------------------------------------"
}

#检查ftp
chack_ftp(){
	echo "检查是否禁止匿名用户登录"
	if [ -f /etc/vsftpd.conf ];then
		a=/etc/
		ano=`cat $a/vsftpd.conf |grep "^anonymous_enable"`
        	if [ -n $ano ];then
                	echo "-"
        	else
                	echo $ano
        	fi
		if [[ `echo $ano | awk -F= '{print $2}'` != "NO" ]];then
			echo "不达标"
			echo "请检查$a,是否禁止匿名用户登录,如:anonymous_enable=NO"
		fi
	elif [ -f /etc/vsftpd/vsftpd.conf ];then
		a=/etc/vsftpd/
		ano=`cat $a/vsftpd.conf |grep "^anonymous_enable"`
        	if [ -n $ano ];then
                	echo "-"
        	else
                	echo $ano
        	fi
		if [[ `cat $ano | awk -F= '{print $2}'` != "NO" ]];then
			echo "不达标"
			echo "请检查$a,是否禁止以免用户登录,如:anonymous_enable=NO"
		fi
	else
		a="未安装ftp"
		echo $a
		echo "已达标"
		echo "-"
	fi
		
       	echo "-----------------------------------------------"
	echo "检查是否已禁止root登录ftp"
	if [[ `echo $a` != "未安装ftp" ]];then 
		roo=`cat $a/ftpusers |grep "^root$"`
		if [ `cat $roo |wc -l` -lt 1 ];then
			echo $roo
			echo "已达标"
			echo "-"
		fi
	else
		echo $a
		echo "已达标"
		echo "-"
	fi
		
       	echo "-----------------------------------------------"
}


#检查全部linux系统基线
check_all(){
	empty_password
	password_validity_period
	user_login_error_locked
	login_timed_out
	check_telnet
	check_file
	deny_root_login
	check_user_login
	chack_password_Complexity_Policy
	chack_su
	chack_umask
	chack_ftp
}

#获取服务器IP
check_ip(){
	a=/etc/redhat-release
	if [ `cat $a |sed 's/ /\n/g' |grep "^6" |wc -l` -ge 1 ];then
		cen6=`ifconfig -a |grep "inet" |grep -e '[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}'|grep -v "127.0.0" |awk -F " " '{print $2}' |awk -F: '{print $2}' |head -1`
		echo "$cen6"
	elif [ `cat $a |sed 's/ /\n/g' | grep "^7" |wc -l` -ge 1 ];then
		cen7=`ifconfig -a |grep "inet" |grep -e '[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}'|grep -v "127.0.0" |awk -F " " '{print $2}' |head -1`
		echo "$cen7"
	else
		echo "此脚本仅支持cento6、7"
		echo "运行异常"
	fi
}



##定义脚本所在路径
current_path=$(cd $(dirname $0); pwd)
##定义日期变量
CDATE=`date '+%Y-%m-%d-%H-%M-%-S'`

#输入参数,用于检测linux重保项
echo "==================================================================="
echo "|                                                                  |"
echo "|                    请输入所要检查的项:                          |"
echo "|                                                                  |"
echo "|                输入 1 检查  空 密 码  用户                       |"
echo "|                输入 2 检查   密  码   规则                       |"
echo "|                输入 3 检查是否配置登录规则                       |"
echo "|                输入 4 检查  登录超时  时间                       |"
echo "|                输入 5 检查   telnet   服务                       |"
echo "|                输入 6 检查   passwd   权限                       |"
echo "|                输入 7 检查  root有无  禁止                       |"
echo "|              输入 8 检查是否禁用默认用户登录                     |"
echo "|                输入 9 检查 密码复杂度 策略                       |"
echo "|               输入 10 检查是否限制用户su到root                   |"
echo "|             输入 11 检查umask权限和命令行超时时间                |"
echo "|          输入 12 检查ftp是否禁用匿名用户和禁止root登录           |"
echo "|            输入 20 完整对linux系统进行基线扫描                   |"
echo "|                                                               |"
echo "================================================================="

read -p "请输入您的检查项:" choice
case $choice in
1)
    empty_password > `check_ip`_empty_password_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_empty_password_$CDATE.txt"
;;
2)
    password_validity_period > `check_ip`_password_validity_period_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_password_validity_period_$CDATE.txt"
;;
3)
    user_login_error_locked > `check_ip`_user_login_error_locked_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_user_login_error_locked_$CDATE.txt"
;;
4)
    login_timed_out > `check_ip`_login_timed_out_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_login_timed_out_$CDATE.txt"
;;
5)
    check_telnet > `check_ip`_check_telnet_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_check_telnet_$CDATE.txt"
;;
6)
    check_file > `check_ip`_check_file_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_check_file_$CDATE.txt"
;;
7)
    deny_root_login > `check_ip`_deny_root_login_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_deny_root_login_$CDATE.txt"
;;
8)
    check_user_login > `check_ip`_check_user_login_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_check_user_login_$CDATE.txt"
;;
9)
    chack_password_Complexity_Policy > `check_ip`_check_password_Complexity_Policy_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_check_password_Complexity_Policy_$CDATE.txt"
;;
10)
    chack_su > `check_ip`_check_su_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_chack_su_$CDATE.txt"
;;
11)
    chack_umask > `check_ip`_check_umask_$CDATE.txt
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_chack_umask_$CDATE.txt"
;;
12)
   chack_ftp > `check_ip`_check_ftp_$CDATE.txt
   echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_chack_ftp_$CDATE.txt"
;;
20)
    check_all > `check_ip`_all_$CDATE.txt 
    echo "检查完成,文件在以下位置,以内网IP开头:`pwd`/`check_ip`_all_$CDATE.txt"
;;
*)
    echo "选择错误,请重新运行脚本,选择所需服务"
    exit
esac