Linux基于等保的安全加固

乔克
乔克
发布于 2024-11-19 / 27 阅读
0
0

Linux基于等保的安全加固

✍ 道路千万条,安全第一条。操作不规范,运维两行泪。

一、设置密码安全策略

1、修改 vim /etc/login.defs 文件

#vim /etc/login.defs
PASS_MAX_DAYS   90         # 密码最长过期天数
PASS_MIN_DAYS   7         # 密码最小过期天数
PASS_MIN_LEN    8        # 密码最小长度
PASS_WARN_AGE   14        # 密码过期警告天数

2、修改 vim /etc/security/pwquality.conf 文件

# vim /etc/security/pwquality.conf
minlen=8                         # 密码长度
minclass=3                       # 密码策略 3 表示大小写字母、数字、字符是少 3 类

3、修改 /etc/pam.d/password-auth 和 /etc/pam.d/system-auth 文件

password    sufficient     pam_sss.so use_authtok  remember=5  # 密码最大重用次数

二、修复系统账户

1、查看是否存在特权用户,通过判断 uid 是否为 0 来查找系统是否存在特权用户

awk -F: '$3==0 {print $1}' /etc/passwd

2、查看是否存在空口令用户

awk -F: 'length($2)==0 {print $1}' /etc/shadow

三、修复系统日志

1、添加审计账户

useradd audit
usermod -G audit audit

2、开启审计服务

# 检查服务是否存在
systemctl status auditd
# 如果不存在则安装
yum -y install audit audit-libs-devel
systemctl daemon-reload
systemctl enable auditd

配置审计规则:

1)简单版本

# vim /etc/audit/rules.d/audit.rules
-a exit,always -F arch=b64 -S umask -S chown -S chmod
-a exit,always -F arch=b64 -S unlink -S rmdir
-a exit,always -F arch=b64 -S setrlimit
-a exit,always -F arch=b64 -S setuid -S setreuid
-a exit,always -F arch=b64 -S setgid -S setregid
-a exit,always -F arch=b64 -S sethostname -S setdomainname
-a exit,always -F arch=b64 -S adjtimex -S settimeofday
-a exit,always -F arch=b64 -S mount -S _sysctl
-w /etc/group -p wa
-w /etc/passwd -p wa
-w /etc/shadow -p wa
-w /etc/sudoers -p wa
-w /etc/ssh/sshd_config
-w /etc/bashrc -p wa
-w /etc/profile -p wa
-w /etc/profile.d/
-w /etc/aliases -p wa
-w /etc/sysctl.conf -p wa
-w /var/log/lastlog
# Disable adding any additional rules - note that adding *new* rules will require a reboot

2)详细版本

cat >> /etc/audit/rules.d/audit.rules <<EOF
###记录系统的日期和时间的修改
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k timechange
-a always,exit -F arch=b64 -S clock_settime -k time-change
-a always,exit -F arch=b32 -S clock_settime -k time-change
-w /etc/localtime -p wa -k time-change

####记录用户和组的修改的事件
-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/security/opasswd -p wa -k identity

####记录网络环境修改时间
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale
-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale
-w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale
-w /etc/sysconfig/network -p wa -k system-locale
-w /etc/sysconfig/network-scripts/ -p wa -k system-locale

####记录登录和登出事件
-w /var/log/lastlog -p wa -k logins
-w /var/run/faillock/ -p wa -k logins

####记录会话启动事件
-w /var/run/utmp -p wa -k session
-w /var/log/wtmp -p wa -k logins
-w /var/log/btmp -p wa -k logins

####监视对文件权限、属性、所有权和组的更改
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod

####记录未授权文件访问尝试
-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access

####收集成功挂载磁盘事件
-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts
-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mount

####收集用户的文件删除事件
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete

####收集对系统管理范围(sudoers)的更改
-w /etc/sudoers -p wa -k scope
-w /etc/sudoers.d/ -p wa -k scope

####收集内核模块加载和卸载
-w /sbin/insmod -p x -k modules
-w /sbin/rmmod -p x -k modules
-w /sbin/modprobe -p x -k modules
-a always,exit -F arch=b64 -S init_module -S delete_module -k modules

####收集使用特权命令
-a always,exit -F path=/usr/bin/wall -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/chfn -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/chsh -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/chage -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/gpasswd -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/newgrp -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/staprun -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/mount -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/pkexec -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/umount -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/write -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/crontab -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/ssh-agent -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/passwd -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/sbin/pam_timestamp_check -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/sbin/unix_chkpwd -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/sbin/netreport -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/sbin/usernetctl -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/sbin/postdrop -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/sbin/postqueue -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/lib/polkit-1/polkit-agent-helper-1 -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/libexec/utempter/utempter -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/libexec/dbus-1/dbus-daemon-launch-helper -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/libexec/openssh/ssh-keysign -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
EOF

重新加载规则

/sbin/augenrules --load

日志赋权

chown audit:audit -R /var/log
chown root:root -R /var/log/audit

3、日志权限设置,权限不得大于 640

chmod 640 /var/log/messages
chmod 640 /var/log/secure
chmod 640 /var/log/audit/audit.log

4、日志远程存储

#vim  /etc/rsyslog.conf
*.info;mail.none;news.none;authpriv.none;cron.none /var/log/messages
*.* @@172.16.x.xx:514
*.* @172.16.x.xx:514

三、限制远程登录

1、修改 /etc/ssh/sshd_config

# vim /etc/ssh/sshd_config
PermitEmptyPasswords no         # 禁止无密码访问服务器
MaxAuthTries 4                  # 用户最大认证次数
HostbasedAuthentication no      # 关闭openssh主机认证
# SSH空闲超时配置
ClientAliveInterval 300         # 小于等于300s
ClientAliveCountMax 3           # 存活用户数小于等于3

2、配置连接超时自动退出功能

echo "TMOUT=300">>/etc/profile
source /etc/profile

四、附检查修复脚本

1、基线检查脚本

#!/bin/bash
# ################ Descripthon ################
# Date: 2020-10-12
# Auth: Joker
# Mail: jokerbaix@163.com
# Version: v1
# Attention: 阿里云云服务器基线检测
# #############################################

IP=$(ifconfig eth0 | grep -w inet | awk '{print $2}')
NOW_TIME=$(date +"%Y-%m-%d-%T")

dash_line="------------------------------------------------------------------"
# 绿色字体输出检测通过
pass=$(($pass + 1))
print_pass() {
    echo -e "\033[32m++> PASS \033[0m"
    echo "++> PASS" >>"$file"
}
# 红色字体输出检测失败FAIL
fail=$(($fail + 1))
print_fail() {
    echo -e "\033[31m--> FAIL \033[0m"
    echo "--> FAIL" >>"$file"
}
# 黄色字体输出需手工再检查的项
print_manual_check() {
    echo -e "\033[33m##> Manual \033[0m"
    echo "##> Manual" >>"$file"
}
# 蓝色字体输出补充
print_info() {
    echo -e "\033[34m$1 \033[0m"
}
# 紫色字体输出检测项
print_check_point() {
    echo ""
    echo -e "\033[35m[No."$1"] "$2" \033[0m"
    echo "[$1]"" $2" >>"$file"
}
print_dot_line() {
    echo "$dash_line"
}
print_summary() {
    # 输出显示
    print_info "---------------------------- Summary -----------------------------"
    echo -e "\033[35m全部检测项: $1 \033[0m"
    echo -e "\033[32m通过检测项: $2 \033[0m"
    echo -e "\033[31m失败检测项: $3 \033[0m"
    echo -e "\033[33m手工检测项: $4 \033[0m"
    print_info "检测结果将写入文件 $file中..."
    print_info "$dash_line"
    # 写入文件
    echo "---------------------------- Summary -----------------------------" >>"$file"
    echo "全部检测项: $1" >>"$file"
    echo "通过检测项: $2" >>"$file"
    echo "失败检测项: $3" >>"$file"
    echo "手工检测项: $4" >>"$file"
    echo "$dash_line" >>"$file"
}
# ====================================
function check() {
    begin_msg="-------------------- 正在执行操作系统基线检查 --------------------"
    print_info "$begin_msg"
    index=0  # 检测项编号
    pass=0   # 通过的检测项数
    fail=0   # 未通过的检测项数
    manual=0 # 需手工复核的检测项数
    file="baseline_check_result.txt"

    echo "$begin_msg" >"$file"

    check_point="帐号管理-1:检查是否设置除root之外UID为0的用户"
    index=$(($index + 1))
    print_check_point $index "$check_point"

    print_info "'任何UID为0的帐户都具有系统上的超级用户特权,只有root账号的uid才能为0'"
    print_dot_line

    result=$(/bin/cat /etc/passwd | /bin/awk -F: '($3 == 0) { print $1 }')
    print_info "UID为0的用户如下:"
    print_info "[ $result ]"

    if [ "root" = $result ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi


    check_point="口令策略-1:检查是否设置口令生存周期 "
    index=$(($index + 1))
    print_check_point $index "$check_point"
    passmax=$(cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v ^#)
    print_info "'PASS_MAX_DAYS 应介于1~90'"
    print_dot_line
    print_info "$passmax"
    if [ -n "$passmax" ]; then
        days=$(echo $passmax | awk '{print $2}')
        if [ "$days" -gt 90 ]; then
            fail=$(($fail + 1))
            print_fail
        else
            pass=$(($pass + 1))
            print_pass
        fi
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="口令策略-2:检查是否设置口令更改最小间隔天数 "
    index=$(($index + 1))
    print_check_point $index "$check_point"
    passmin=$(cat /etc/login.defs | grep PASS_MIN_DAYS | grep -v ^#)
    print_info "'PASS_MIN_DAYS 应大于等于 7'"
    print_dot_line
    print_info "$passmin"
    if [ -n "$passmin" ]; then
        days=$(echo $passmin | awk '{print $2}')
        if [ "$days" -lt 7 ]; then
            fail=$(($fail + 1))
            print_fail
        else
            pass=$(($pass + 1))
            print_pass
        fi
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="口令策略-3:检查是否设置口令过期前警告天数  "
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_info "'口令过期前告警天数PASS_WARN_AGE应设置为 7'"
    print_dot_line
    pass_age=$(cat /etc/login.defs | grep PASS_WARN_AGE | grep -v ^#)
    print_info "$pass_age"
    if [ -n "$pass_age" ]; then
        days=$(echo $pass_age | awk '{print $2}')
        if [ "$days" -eq 7 ]; then
            pass=$(($pass + 1))
            print_pass
        else
            fail=$(($fail + 1))
            print_fail
        fi
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="口令策略-4:检查设备密码复杂度策略"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_info "'系统应设置密码复杂度策略,避免设置账号弱口令'"
    print_dot_line
    print_info "'密码长度>=8,且至少包含一个大写字母、小写字母、数字、特殊字符(可自定义密码复杂度策略)'"
    print_dot_line
    flag=0
    # 以下检查/etc/security/pwquality.conf文件中的内容
    # minlen为密码字符串长度,minclass为字符类别,至少包含小写字母、大写字母、数字、特殊字符等4类字符中等3类或4类
    print_info "检查/etc/security/pwquality.conf,如下:"
    line_minlen=$(cat /etc/security/pwquality.conf | grep minlen | grep -v ^#)
    line_minclass=$(cat /etc/security/pwquality.conf | grep minclass | grep -v ^#)

    if [ -n "$line_minlen" ] && [ -n "$line_minclass" ]; then
        minlen=$(echo "$line_minlen" | awk -F "=" '{print $2}' | awk '{gsub(/^\s+|\s+$/, "");print}')
        minclass=$(echo "$line_minclass" | awk -F "=" '{print $2}' | awk '{gsub(/^\s+|\s+$/, "");print}')
        if [ "$minlen" -ge 8 ] && [ "$minclass" -ge 4 ]; then
            print_info "minlen =>"" [ $minlen ]"
            print_info "minclass =>"" [ $minclass ]"
            flag=1
        fi
    fi
    if [ "$flag" -eq 1 ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="口令策略-5:检查是否存在空口令账号"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_info "'不允许存在空口令的账号'"
    print_dot_line
    tmp=$(/bin/cat /etc/shadow | /bin/awk -F: '($2 == "" ) { print "user " $1 " does not have a password "}')
    print_info '空口令账号:'"[ $tmp ]"
    if [ -z "$tmp" ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="口令策略-6:检查密码重复使用次数限制"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    line=$(cat /etc/pam.d/system-auth | grep password | grep sufficient | grep pam_unix.so | grep remember | grep -v ^#)
    print_info "'口令重复使用限制次数 remember >=5'"
    print_dot_line
    print_info "[ $line ]"
    if [ -n "$line" ]; then
        times=$(echo $line | awk -F "remember=" '{print $2}')
        if [ $times -ge 5 ]; then
            pass=$(($pass + 1))
            print_pass
        else
            fail=$(($fail + 1))
            print_fail
        fi
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="口令策略-7:检查账户认证失败次数限制"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_dot_line
    print_info "登录失败限制可以使用pam_tally2或pam.d,请手工检测/etc/pam.d/login和/etc/pam.d/sshd"
    print_info "建议配置:auth required pam_tally2.so deny=3 unlock_time=300 even_deny_root root_unlock_time=10"
    manual=$(($manual + 1))
    print_manual_check

    check_point="日志审计-1:检查是否对登录进行日志记录"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_info "'设备应配置日志功能,对用户登录进行记录,记录内容包括用户登录使用的账号,登录是否成功,登录时间,以及远程登录时,用户使用的IP地址'"
    tmp=$(cat /etc/rsyslog.conf | grep /var/log/secure | egrep 'authpriv'.\('info|\*'\) | grep -v ^#)
    print_dot_line
    print_info "/etc/rsyslog.conf 文件中 authpriv 的配置如下所示:"
    print_info "[ $tmp ]"
    if [ -n "$tmp" ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="口令策略-8:检测是否允许空密码登录"
    index=$(($index+1))
    print_check_point $index "$check_point"
    print_info "应该禁止SSH空密码用户登录"
    print_dot_line
    tmp=`cat /etc/ssh/sshd_config | grep PermitEmptyPasswords | grep -v ^#`
    print_info "/etc/ssh/sshd_config中是否允许空密码登录配置如下所示:"
    print_info "$tmp"
    if [ -n "$tmp" ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="日志审计-2:检查日志文件权限设置"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    messages=$(stat -c %a /var/log/messages)
    dmesg=$(stat -c %a /var/log/dmesg)
    maillog=$(stat -c %a /var/log/maillog)
    secure=$(stat -c %a /var/log/secure)
    wtmp=$(stat -c %a /var/log/wtmp)
    cron=$(stat -c %a /var/log/cron)
    print_info "'设备应配置权限,控制对日志文件读取、修改和删除等操作'"
    print_info "推荐的文件权限:(不大于左侧值)"
    print_info "600 /var/log/messages"
    print_info "600 /var/log/secure、"
    print_info "600 /var/log/maillog、"
    print_info "600 /var/log/cron"
    print_info "644 /var/log/dmesg"
    print_info "664 /var/log/wtmp"
    print_dot_line
    print_info "目前的文件权限如下:"
    print_info $messages' /var/log/messages'
    print_info $dmesg' /var/log/dmesg  '
    print_info $maillog' /var/log/maillog  '
    print_info $secure' /var/log/secure  '
    print_info $wtmp' /var/log/wtmp  '
    print_info $cron' /var/log/cron  '
    if [ "$messages" -le 600 ] && [ "$secure" -le 600 ] && [ "$maillog" -le 600 ] && [ "$cron" -le 600 ] && [ "$dmesg" -le 644 ] && [ "$wtmp" -le 664 ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="日志审计-3:检查安全事件日志配置"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_info "'设备应配置日志功能,记录对与设备相关的安全事件'"
    print_dot_line
    tmp=$(cat /etc/rsyslog.conf | grep /var/log/messages | egrep '\*.info;mail.none;authpriv.none;cron.none' | grep -v ^#)
    print_info "/etc/rsyslog.conf 文件中 /var/log/messages 的配置如下所示:"
    print_info "$tmp"
    if [ -n "$tmp" ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="日志审计-4:检查SSH的日志级别"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_info "'确保SSH LogLevel设置为INFO,记录登录和注销活动'"
    print_dot_line
    tmp=$(cat /etc/ssh/sshd_config | grep LogLevel | grep -v ^#)
    print_info "/etc/ssh/sshd_config文件中SSH的日志级别配置如下所示:"
    print_info "$tmp"
    if [ -n "$tmp" ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="文件权限-1:检查重要目录或文件权限设置"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    passwd=$(stat -c %a /etc/passwd)
    shadow=$(stat -c %a /etc/shadow)
    group=$(stat -c %a /etc/group)
    print_info "'在设备权限配置能力内,根据用户的业务需要,配置其所需的最小权限'"
    print_info "建议文件权限:(不大于左侧值)"
    print_info "644 /etc/passwd"
    print_info "400 /etc/shadow"
    print_info "644 /etc/group"
    print_dot_line
    print_info "实际检测值为:"
    print_info "$passwd"" /etc/passwd"
    print_info "$shadow"" /etc/shadow"
    print_info "$group"" /etc/group"
    if [ "$passwd" -le 644 ] && [ "$shadow" -le 400 ] && [ "$group" -le 644 ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    check_point="其他配置-1:检查是否设置命令行界面超时退出"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_info "'命令行界面超时自动登出时间TMOUT应不大于300s'"
    print_dot_line
    TMOUT=$(cat /etc/profile | grep -i TMOUT | grep -v ^#)
    if [ -z "$TMOUT" ]; then
        print_info "没有设置超时时间TMOUT"
        fail=$(($fail + 1))
        print_fail
    else
        TMOUT=$(cat /etc/profile | grep -i TMOUT | egrep -v ^\# | awk -F "=" '{print $2}')
        if [ "$TMOUT" -gt 300 ]; then
            print_info "TMOUT值过大:""$TMOUT"
            fail=$(($fail + 1))
            print_fail
        else
            print_info "TMOUT:""$TMOUT"
            pass=$(($pass + 1))
            print_pass
        fi
    fi

    check_point="其他配置-2:检查SSH最大密码尝试失败次数"
    index=$(($index + 1))
    print_check_point $index "$check_point"
    print_info "'设置最大密码尝试失败次数3-6,建议为4'"
    print_dot_line
    tmp=$(cat /etc/ssh/sshd_config | grep MaxAuthTries | grep -v ^#)
    print_info "/etc/ssh/sshd_config文件中SSH的最大密码尝试失败次数配置如下所示:"
    print_info "$tmp"
    if [ -n "$tmp" ]; then
        pass=$(($pass + 1))
        print_pass
    else
        fail=$(($fail + 1))
        print_fail
    fi

    print_summary $index $pass $fail $manual
}

# 开始检测并生成报告
check

2、基线修复脚本

#!/bin/bash
# ################ Descripthon ################
# Date: 2020-10-15
# Auth: Joker
# Mail: jokerbaix@163.com
# Version: v1
# Attention: 阿里云云服务器基线检测修复
# #############################################


# 修复前先备份所有配置文件
function backup() {
    now_time=$(date +%Y%m%d%H%M)
    cp /etc/login.defs /etc/login.defs.bak.${now_time}
    cp /etc/security/pwquality.conf /etc/security/pwquality.conf.bak.${now_time}
    cp /etc/pam.d/password-auth /etc/pam.d/password-auth.bak.${now_time}
    cp /etc/pam.d/system-auth /etc/pam.d/system-auth.bak.${now_time}
    cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.${now_time}
    cp /etc/profile /etc/profile.bak.${now_time}
}

# 修改口令相关策略
function repair_pwd_policy() {
    # 更改口令最小间隔数
    grep '^PASS_MIN_DAYS   7' /etc/login.defs &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^PASS_MIN_DAYS/ d" /etc/login.defs
        echo 'PASS_MIN_DAYS   7' >>/etc/login.deeefs
        chage --mindays 7 root
    fi

    # 更改口令生存时间
    grep '^PASS_MAX_DAYS   90' /etc/login.defs &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^PASS_MAX_DAYS/ d" /etc/login.defs
        echo 'PASS_MAX_DAYS   90' >>/etc/login.deeefs
        chage --maxdays 90 root
    fi

    # 修改口令过期警告时间
    grep '^PASS_WARN_AGE   7' /etc/login.defs &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^PASS_WARN_AGE/ d" /etc/login.defs
        echo 'PASS_WARN_AGE   7' >>/etc/login.defs
    fi

    # 修改密码复杂度
    grep '^minlen=10' /etc/security/pwquality.conf &>/dev/null
    a=$?
    grep '^minclass=3' /etc/security/pwquality.conf &>/dev/null
    b=$?
    if [[ $a -ne 0 ]] && [[ $b -ne 0 ]]; then
        sed -i "/^minlen/ d" /etc/security/pwquality.conf
        sed -i "/^minclass/ d" /etc/security/pwquality.conf
        echo "minlen=10" >>/etc/security/pwquality.conf
        echo "minclass=3" >>/etc/security/pwquality.conf
    fi

    # 修改密码重用次数
    for file in /etc/pam.d/password-auth /etc/pam.d/system-auth; do
        grep 'password' $file | grep sufficient | grep remember &>/dev/null
        if [[ $? -ne 0 ]]; then
            grep 'use_authtok' $file &>/dev/null
            if [[ $? -eq 0 ]]; then #这行存在则末尾加字符
                sed -i 's/use_authtok$/& remember=5/' $file
            fi
        fi
    done
}

# 修改ssh参数
function repair_ssh() {
    ssh_config=/etc/ssh/sshd_config

    # 不允许空密码登录
    grep "^PermitEmptyPasswords no" $ssh_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^PermitEmptyPasswords/ d" $ssh_config
        echo "PermitEmptyPasswords no" >>$ssh_config
    fi

    # 修改最大尝试次数
    grep "^MaxAuthTries 4" $ssh_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^MaxAuthTries/ d" $ssh_config
        echo "MaxAuthTries 4" >>$ssh_config
    fi

    # 修改ssh远程协议
    grep "^Protocol 2" $ssh_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^Protocol/ d" $ssh_config
        echo "Protocol 2" >>$ssh_config
    fi

    # 其他参数修改
    grep "^X11Forwarding no" $ssh_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^X11Forwarding/ d" $ssh_config
        echo "X11Forwarding no" >>$ssh_config
    fi
    grep "^IgnoreRhosts yes" $ssh_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^IgnoreRhosts/ d" $ssh_config
        echo "IgnoreRhosts yes" >>$ssh_config
    fi
    grep "^HostbasedAuthentication no" $ssh_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^HostbasedAuthentication/ d" $ssh_config
        echo "HostbasedAuthentication no" >>$ssh_config
    fi
}

# 修改/etc/profile中的配置
function repair_profile() {
    profile_config=/etc/profile
    # 设置命令行界面超时退出
    grep "^TMOUT=300" $profile_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^TMOUT/ d" $profile_config
        echo "TMOUT=300" >>$profile_config
    fi

    # 设置历史命令显示条数
    grep "^HISTFILESIZE=5" $profile_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^HISTFILESIZE/ d" $profile_config
        echo "HISTFILESIZE=5" >>$profile_config
    fi
    grep "^HISTSIZE=5" $profile_config &>/dev/null
    if [ $? -ne 0 ]; then
        sed -i "/^HISTSIZE/ d" $profile_config
        echo "HISTSIZE=5" >>$profile_config
    fi
}

function main() {
    echo "===========  开始修复  ==========="
    # 备份需修改的文件
    backup
    # 修改口令策略
    repair_pwd_policy
    # 修改ssh配置文件
    repair_ssh
    # 修改环境变量
    repair_profile

    # 重启ssh
    # service sshd restart
    # source /etc/profile
    echo "===========  修复完成  ==========="
}

main

评论