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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355