Suse 系统基线加固脚本-第一弹

最近写了一些操作系统加固的脚本,操作系统包括:Centos/RedHat、Ubuntu、Suse、Debian、Solaris,本文主要是Suse的脚本,后续更新其他操作系统的脚本

「听到内心」外面太吵,要学会听见自己内心的声音

话不多说,直接上代码吧。
脚本参数说明:

#!/bin/sh    指定执行脚本的shell类型
# file: /etc/profile   脚本修改涉及到的文件
# default: umask值大于等于027   修改内容的默认值
# return: result=SUCCESS/ENOSUPPORT  脚本返回的结果
# tested: centos5 centos7 unbuntu suse12   该脚本已经在这些系统上测试过
# baseline: 检查用户缺省UMASK    该脚本对应的检查项
  1. 检查口令策略设置是否符合复杂度要求
#!/bin/sh
# file: /etc/pam.d/system-auth /etc/pam.d/common-password [ todo /etc/pam.d/passwd]
# default: password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
#          password    requisite     pam_cracklib.so try_first_pass retry=3
# return: result=SUCCESS/ENOSUPPORT
# tested: centos5 centos7 suse12
# baseline: 检查口令策略设置是否符合复杂度要求
# content: /etc/pam.d/system-auth文件中minclass大于等于2,minlen大于等于6

# write_config_file file_name key value type cmp
_write_pam_config_file_common()
{
    file_name=$1
    set_key=$2
    set_value=$3
    set_type=$4
    vul_cmp=$5

    curr_value=`cat $file_name|egrep -v "^#|^$"|grep -w "$set_key" --color=never|sed "s/^.*$set_key=//g"|sed 's/\s.*$//g'`
    
    if [ ! -n "$curr_value" ]; then
        echo "add "$set_key" to "$file_name
        sed -i "s/\(.*$set_type\)\(.*\)$/\1 $set_key=$set_value\2/g" $file_name
    else
        if [ "$vul_cmp" == "lt" ]; then
            if [ $curr_value -lt $set_value ]; then
                echo $set_key" last = "$curr_value
                echo "set "$set_key" to "$set_value
                
                sed -i "s/\(.*$set_type.*\)$set_key=[0-9]*\(.*\)/\1$set_key=$set_value\2/g" $file_name
            else
                echo $set_key " last = "$curr_value " already fix"
            fi
        elif [ "$vul_cmp" == "gt" ]; then
            if [ $curr_value -gt $set_value ]; then
                echo $set_key" last = "$curr_value
                echo "set "$set_key" to "$set_value

                sed -i "s/\(.*$set_type.*\)$set_key=[0-9]*\(.*\)/\1$set_key=$set_value\2/g" $file_name
            else
                echo $set_key " last = "$curr_value " already fix"
            fi
        fi
    fi
}

# _write_pam_config_file_cracklib_minclass conf_filename
_write_pam_config_file_cracklib_minclass()
{
    file_name=$1
    
    set_line=`grep "pam_cracklib.so" $file_name|grep --color=never "ucredit="`
    if [ ! -n "$set_line" ]; then
        echo "add ucredit to pam_cracklib.so file = "$file_name
        sed -i 's/\(.*pam_cracklib.so\)\(.*\)$/\1 ucredit=-1\2/g' $file_name
    else
        echo "ucredit already set"
    fi

    set_line=`grep "pam_cracklib.so" $file_name|grep "--color=never dcredit="`
    if [ ! -n "$set_line" ]; then
        echo "add dcredit to pam_cracklib.so file = "$file_name
        sed -i 's/\(.*pam_cracklib.so\)\(.*\)$/\1 dcredit=-1\2/g' $file_name
    else
        echo "dcredit already set"
    fi
}


autofix()
{
    fix_minlen=0
    fix_minclass=0
    FILE_LIST="/etc/pam.d/system-auth /etc/pam.d/common-password"

    for conf_file in $FILE_LIST; do
        echo "check "$conf_file
        if [ -f $conf_file ]; then

            echo "backup..."$conf_file
            cp $conf_file $conf_file"_`date +%F_%T`.bk"

            pwquality=`grep --color=never 'pam_pwquality.so' $conf_file`
            if [ -n "$pwquality" ]; then
                echo $pwquality
                _write_pam_config_file_common $CONF_FILE minclass 2 pam_pwquality.so lt
                _write_pam_config_file_common $CONF_FILE minlen 6 pam_pwquality.so lt
                fix_minlen=1
                fix_minclass=1
            fi

            cracklib=`grep --color=never 'pam_cracklib.so --color=never' $CONF_FILE`
            if [ -n "$cracklib" ]; then
                echo $cracklib
                _write_pam_config_file_common $CONF_FILE minlen 6 pam_cracklib.so lt
                _write_pam_config_file_cracklib_minclass $CONF_FILE 
                fix_minlen=1
                fix_minclass=1
            fi
        fi
    done

    if [ $fix_minlen -eq 1 -a $fix_minclass -eq 1 ]; then
        return 0
    else
        return 1
    fi
}

autofix
nret=$?

if [ $nret -eq 0 ]; then
    echo "result=SUCCESS"
elif [ $nret -eq 2 ]; then
    echo "result=EOSMISMATCH"
else
    echo "result=ENOSUPPORT"
fi
  1. 检查是否按角色进行帐号管理 / 检查是否按用户分配账号责任到人
#!/bin/bash
# file: /etc/group /etc/passwd
# default: no
# return: result=SUCCESS
# tested: suse 11
# baseline: 检查是否按角色进行帐号管理 / 检查是否按用户分配账号责任到人

autofix(){

    if ([ `cat /etc/group | grep "AutoFixGroup" |wc -l` -eq 0 ]);then
                #创建新用户组
                groupadd -g 1111 AutoFixGroup
        else
                #已存在该用户组说明之前自动加固脚本之前已添加过,无需再次添加
                echo "autofix script has executed !!!"
        fi

        if ([ `cat /etc/passwd | grep "AutoFixUser" |wc -l` -eq 0 ]);then
                #创建所属用户
                useradd -g AutoFixGroup -u 1111 AutoFixUser
        else
                #已存在该用户说明之前自动加固脚本之前已添加过,无需再次添加
                echo "autofix script has executed !!!"
        fi

}

if ([ `cat /etc/issue|grep -i "suse" |wc -l` -ge 1 ]);then
        echo "===start autofix==="
        autofix
        if [ $? -eq 0 ]; then
            echo "result=SUCCESS"
        else
            echo "result=ENOSUPPORT"
        fi
fi
  1. 检查用户缺省UMASK
#!/bin/sh
# file: /etc/profile
# default: umask值大于等于027
# return: result=SUCCESS/ENOSUPPORT
# tested: centos5 centos7 unbuntu suse12
# baseline: 检查用户缺省UMASK

autofix()
{
    curr_set=`grep -i "umask\s*027" /etc/profile`
    if [ ! -n "$curr_set" ]; then
        echo "append umask 027"
        if echo "umask 027" >> /etc/profile; then
            return 0
        fi
    fi

    return 1
}
if autofix; then
    echo "result=SUCCESS"
else
    echo "result=ENOSUPPORT"
fi

  1. 检查是否删除或锁定无关账号
#!/bin/bash
# file: /etc/passwd /etc/shadow  accounts: lp uucp nobody games rpm smmsp nfsnobody listen gdm webservd nobody nobody4 noaccess
# default: none
# return: result=SUCCESS/ENOSUPPORT
# tested: suse11
# baseline: 检查是否删除或锁定无关账号

autofix(){

        pass=/etc/passwd
        shadow=/etc/shadow
        #备份文件
        echo echo "backup..."$pass"..."$shadow
        cp $pass $pass.`date +%F_%T`
        cp $shadow $shadow.`date +%F_%T`
        #需要删除的用户列表
        accounts="lp nobody uucp games rpm smmsp nfsnobody listen gdm webservd nobody nobody4 noaccess"

        for acc in $accounts;do
                #1、如果存在就锁定以上用户
                if [ `cat /etc/shadow |egrep -w "$acc" |wc -l` -ge 1  ];then
                        passwd -l $acc  #锁定用户,shadw密码域前面增加!符号     
                fi
                #2、将/etc/passwd文件中的shell置为/bin/false
                if [ `cat /etc/passwd |egrep -w "$acc" |wc -l` -ge 1  ];then
                        usermod -s /bin/false $acc  #修改用户shell为无效,用户不能登录
                fi
        done
}

if ([ `cat /etc/issue|grep -i suse |wc -l` -ge 1 ] && [ -f /etc/shadow ] && [ -f /etc/passwd ]);then
        echo "===start autofix==="
        autofix
        if [ $? -eq 0 ]; then
            echo "result=SUCCESS"
        else
            echo "result=ENOSUPPORT"
        fi
fi
  1. 检查是否设置登录超时
#!/bin/sh
# file: /etc/profile /etc/csh.cshrc
# default: none
# return: result=SUCCESS/ENOSUPPORT
# tested: suse12
# 检查是否设置登录超时

PROFILE=/etc/profile
SET_KEY=TMOUT
SET_VALUE=180
PROFILE2=/etc/csh.cshrc
SET_KEY2="set autologout="
SET_VALUE2=30

autofix(){
        echo "backup ... "$PROFILE
        cp $PROFILE $PROFILE.`date +%F_%T`
        cp /etc/csh.cshrc /etc/csh.cshrc.`date +%F_%T`

        conf_value=`cat $PROFILE |grep -nw $SET_KEY |egrep -v "#"|tail -n 1`
        line_num=`echo $conf_value |awk -F: '{print $1}'`
        if [ -n "$conf_value" ];then
                echo "modify $SET_KEY=$SET_VALUE to $PROFILE"
                sed -i "${line_num}c export\ $SET_KEY=$SET_VALUE" $PROFILE
        else
                echo "add $SET_KEY=$SET_VALUE to $PROFILE"
                echo "export $SET_KEY=$SET_VALUE" >> $PROFILE
        fi

        conf_value2=`cat $PROFILE2 |egrep -n "$SET_KEY2" |egrep -v "#"|tail -n 1`
        line_num2=`echo $conf_value2 |awk -F: '{print $1}'`
        if [ -n "$conf_value2" ];then
                echo "modify $SET_KEY2$SET_VALUE2 to $PROFILE2"
                sed -i "${line_num2}c $SET_KEY2$SET_VALUE2" $PROFILE2
        else
                echo "add $SET_KEY2$SET_VALUE2 to $PROFILE2"
                echo "$SET_KEY2$SET_VALUE2" >> $PROFILE2
        fi

}

if ([ `cat /etc/issue|grep -i suse |wc -l` -ge 1 ]);then
        echo "===start autofix==="
        autofix
        if [ $? -eq 0 ]; then
            echo "result=SUCCESS"
        else
            echo "result=ENOSUPPORT"
        fi
fi
  1. 检查是否限制root远程登录
#!/bin/sh
# file: /etc/ssh/sshd_config /etc/security/user
# default: 
# return: result=SUCCESS/ENOSUPPORT
# tested: centos5 centos7 ubuntu
# baseline: 检查是否限制root远程登录

autofix()
{
    let nret=1
    sshd_conf=/etc/ssh/sshd_config
    #新增一个账号防止远程登录失败
    useradd autofixuser
    echo "Auto0405#fixuser" | passwd --stdin autofixuser
    
    #修改配置文件   
    if [ -f $sshd_conf ]; then
        curr_set=`cat $sshd_conf|grep -v "^#"|grep PermitRootLogin|sed 's/^.*PermitRootLogin\s*//g'|sed 's/\s.*$//g'|tail -n 1`
        
        if [ ! -n "$curr_set" ]; then
            echo "append PermitRootLogin no  to "$sshd_conf
            cp $sshd_conf $sshd_conf"_`date +%F_%T`.bk"
            echo "PermitRootLogin no" >> $sshd_conf
        elif [ "$curr_set" != "no" ]; then
            echo "set PermitRootLogin no to "$sshd_conf
            cp $sshd_conf $sshd_conf"_`date +%F_%T`.bk"
            sed -i 's/^\s*PermitRootLogin\s*.*\s*$/PermitRootLogin no/g' $sshd_conf
        fi
        
        if [ $? -eq 0 ]; then
            let nret+=1
        fi
    else
        echo "no sshd config file"
    fi

    # /etc/securetty
    sec_conf=/etc/securetty
    if [ -f $sec_conf ]; then
        curr_set=`cat $sec_conf|egrep -i '^pts'|wc -l`
        if [ $curr_set -gt 0 ]; then
            echo "remove pts"
            cp $sec_conf $sec_conf"_`date +%F_%T`.bk"
            sed -i 's/^pts\(.*\)/#pts\1/g' $sec_conf
        fi
        if [ $? -eq 0 ]; then
            let nret+=1
        fi
    else
        echo "no securetty file"
    fi

    if [ $nret -eq 3 ]; then
        return 0
    fi

    return 1
}
if autofix; then
    /etc/init.d/sshd restart 2>/dev/null
    /etc/init.d/telnetd restart 2>/dev/null
    systemctl restart sshd 2>/dev/null
    systemctl restart telnetd 2>/dev/null
    
    echo "result=SUCCESS"
else
    echo "result=ENOSUPPORT"
fi
  1. 检查是否非活动时断线
#!/bin/bash
# file: /etc/ssh/sshd_config
# default: none
# return: result=SUCCESS/ENOSUPPORT
# tested: suse11
# baseline: 检查是否非活动时断线
autofix()
{
        SSHD_FILE=/etc/ssh/sshd_config
        SET_KEY1=ClientAliveCountMax
        SET_VALUE1=0
        SET_KEY2=ClientAliveInterval
        SET_VALUE2=300
        FLAG1=100
        FLAG2=200
        echo "backup ... "$SSHD_FILE
        cp $SSHD_FILE $SSHD_FILE.`date +%F_%T`

        conf_value1=`cat $SSHD_FILE|grep -nw $SET_KEY1 |egrep -v "#"|tail -n 1`
        line_num1=`echo $conf_value1 |awk -F: '{print $1}'`
        conf_value2=`cat $SSHD_FILE|grep -nw $SET_KEY2 |egrep -v "#"|tail -n 1`
        line_num2=`echo $conf_value2 |awk -F: '{print $1}'`

        if [ -n "$conf_value1" ];then
                echo "modify $SET_KEY1 $SET_VALUE1 to $SSHD_FILE"
                sed -i "${line_num1}c $SET_KEY1\ $SET_VALUE1" $SSHD_FILE
                FLAG1=0
        else
                echo "add $SET_KEY1 $SET_VALUE1 to $SSHD_FILE"
                echo "$SET_KEY1 $SET_VALUE1" >> $SSHD_FILE
                FLAG1=0
        fi
        if [ -n "$conf_value2" ];then
                echo "modify $SET_KEY2 $SET_VALUE2 to $SSHD_FILE"
                sed -i "${line_num2}c $SET_KEY2\ $SET_VALUE2" $SSHD_FILE
                FLAG2=0
        else
                echo "add $SET_KEY2 $SET_VALUE2 to $SSHD_FILE"
                echo "$SET_KEY2 $SET_VALUE2" >> $SSHD_FILE
                FLAG2=0
    fi
        #重启sshd服务
        /etc/init.d/ssh restart 2>/dev/null
        if [ $FLAG1 -eq 0 -a $FLAG2 -eq 0  ];then
                return 0
        else
                return 1
        fi
}

if ([ `cat /etc/issue|grep -i suse |wc -l` -ge 1 ] && [ -f /etc/ssh/sshd_config ]);then
        echo "===start autofix==="
        autofix
        if [ $? -eq 0 ]; then
            echo "result=SUCCESS"
        else
            echo "result=ENOSUPPORT"
        fi
fi
  1. 检查登录提示-是否设置登录成功后警告
#!/bin/sh
# file: /etc/motd
# default: none
# return: result=SUCCESS/ENOFILE_xxx
# tested: suse12
# baseline: 检查登录提示-是否设置登录成功后警告

MOTD_FILE=/etc/motd
BANNER_CONTENT="Authorized users only. All activity may be monitored and reported"

autofix()
{
    if [ ! -f MOTD_FILE ]; then
        echo $BANNER_CONTENT > $MOTD_FILE
    else
        if [ `cat $MOTD_FILE|wc -l` == 0 ]; then
            echo "fix MOTD banner..."
            echo $BANNER_CONTENT >> $MOTD_FILE
        fi
    fi

    return 0
}

if ([ `cat /etc/issue|grep -i suse |wc -l` -ge 1 ]);then
        echo "===start autofix==="
        autofix
        if [ $? -eq 0 ]; then
            echo "result=SUCCESS"
        else
            echo "result=ENOSUPPORT"
        fi
fi
  1. 检查日志文件权限设置
#!/bin/sh
# file: /etc/syslog.conf /etc/rsyslog.conf /etc/rsyslog.conf
# default: none
# return: result=SUCCESS/ENOSUPPORT
# tested: centos5 centos7 suse12 ubuntu
# 检查日志文件权限设置

fix_logfile_priv()
{
    for file in $1; do
        if [ -f $file ]; then
            echo $file" chmod g-rwx o-rwx"
            chmod g-rwx $file
            chmod o-rwx $file
        fi
    done
}

autofix()
{
    if [ -f  /etc/syslog.conf ];
        then SYSLOGCONF=/etc/syslog.conf;
        LOGDIR=`cat $SYSLOGCONF |sed '/^#/d' |sed '/^$/d' |awk '(($2!~/@/) && ($2!~/*/) && ($2!~/-/)) {print $2}'`;
        file_list=`ls -l $LOGDIR|awk '{print $NF}'`
        fix_logfile_priv "$file_list"
    fi
    
    if [ -f  /etc/rsyslog.conf ];
        then SYSLOGCONF=/etc/rsyslog.conf;
        LOGDIR=`cat $SYSLOGCONF |sed '/^#/d' |sed '/^$/d' |awk '(($2!~/@/) && ($2!~/\*/) && ($2!~/-/)) {print $2}'`;
        file_list=`ls -l $LOGDIR|awk '{print $NF}'`
        fix_logfile_priv "$file_list"
    fi
    
    if [ -f  /etc/syslog-ng/syslog-ng.conf ];
        then SYSLOGCONF=/etc/syslog-ng/syslog-ng.conf;
        LOGDIR=`cat /etc/syslog-ng/syslog-ng.conf|grep "^destination"|grep file|cut -d\" -f2`;
        file_list=`ls -l $LOGDIR|awk '{print $NF}'`
        fix_logfile_priv "$file_list"
    fi

    if [ -f /etc/rsyslog.d/50-default.conf ];
        then LOGDIR=`cat /etc/rsyslog.d/50-default.conf |sed '/^#/d' |sed '/^$/d' |awk '(($2!~/@/) && ($2!~/\*/) && ($2!~/-/)) {print $2}'`;
        file_list=`ls -l $LOGDIR|awk '{print $NF}'`
        fix_logfile_priv "$file_list"
    fi              
}

autofix

echo "result=SUCCESS"
  1. 检查是否禁止icmp重定向
#!/bin/bash
# file: /etc/sysctl.conf
# default:
# return: result=SUCCESS/ENOSUPPORT
# tested: suse11sp3 suse12
# baseline: 检查是否禁止icmp重定向

CONF_FILE=/etc/sysctl.conf
# set_commonfile_key_value file_name key value
set_commonfile_key_value()
{
    file_name=$1
    set_key=$2
    set_value=$3

    if [ ! -f $file_name ]; then
        return 0
    fi

    conf_value=`cat $file_name|egrep -v "^#|^$"|grep -w "$set_key"|sed "s/^.*$set_key=\s*//g"|sed 's/\s.*$//g'|tail -n 1`
    if [ ! -n "$conf_value" ]; then
        echo $set_key"="$set_value >> $file_name
    elif [ ! $conf_value -eq $set_value ]; then
        echo "set "$set_key" to "$set_value
        sed -i "s/\(^$set_key\s*\)=\s*[0-9]/\1=$set_value/g" $file_name
    fi

}

autofix()
{
    echo "backup..."$CONF_FILE
    cp $CONF_FILE $CONF_FILE.`date +%F_%T`

    sysctl net.ipv4.conf.all.accept_redirects=0

    set_commonfile_key_value $CONF_FILE "net.ipv4.conf.all.accept_redirects" 0
}

if ([ `cat /etc/issue|grep -i suse |wc -l` -ge 1 ] && [ -f /etc/ssh/sshd_config ]);then
        echo "===start autofix==="
        autofix
        if [ $? -eq 0 ]; then
            echo "result=SUCCESS"
        else
        echo "result=ENOSUPPORT"
        fi
fi

还有其他的脚本,考虑到篇幅限制,可以参考下篇

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。