该脚本用于自动检查并配置系统基线,主要功能有:自动禁止root远程登录、设置密码最小长度和复杂度、口令生存周期、命令行界面超时时间,检查或修改MASK设置等。
仅在Redhat/CentOS环境中通过测试,请仔细阅读说明并自行测试后再用于生产环境。
#!/bin/bash sshconfig="/etc/ssh/sshd_config" pamfile1="/etc/pam.d/common-password" pamfile2="/etc/pam.d/system-auth" pamfile3="/etc/pam.d/login" logindef="/etc/login.defs" sysctlcfg="/etc/sysctl.conf" umask1="/etc/profile" umask2="/etc/csh.cshrc" umask3="/etc/bashrc" prfile="/etc/profile" basdir="/opt/baseline" bakdir="${basdir}/bak" bllogs="${basdir}/baseline.log" # 检查操作系统版本 osversion=`cat /etc/redhat-release | sed 's/[^0-9]//g'` osversion=${osversion:0:1} [ ! -d "${basdir}" ] && mkdir ${basdir} if [ "${osversion}" -lt 6 ] || [ -z "${osversion}" ] then echo "########本脚本仅适合Redhat6/CentOS6或更新版本的操作系统########" > ${bllogs} exit 0 else echo -e "############开始执行脚本调整系统基线############\n>>>>>>>>>> `date "+%Y年%m月%d日%H时%M分%S秒"` <<<<<<<<<<" > ${bllogs} fi # 备份并配置基本环境 echo "# 备份并配置基本环境 #" >> ${bllogs} if [ -d "${bakdir}" ] then cd ${basdir} tar -czPvf bak.`date "+%Y%m%d%H%M%S"`.tar.gz ${bakdir} --remove-files echo "> 已经打包备份旧目录文件" >> ${bllogs} fi mkdir -p ${bakdir} # 请调整需要备份的文件 for bfile in $sshconfig $pamfile1 $pamfile2 $logindef $sysctlcfg $prfile do [ -e ${bfile} ] && cp ${bfile} ${bakdir} && echo "> 备份文件${bfile}" >> ${bllogs} done # 锁定额外的用户账号 LOCKUSER () { echo "# 锁定无用的系统账号 #" >> ${bllogs} for username in ${lockusers[@]} do sysuser=`cat /etc/passwd | awk '{print $1}' | grep -w "${username}"` [ -n "${sysuser}" ] && usermod -L ${username} && echo "> 已锁定账号${username}" >> ${bllogs} || echo "> 无效的账号${username}" >> ${bllogs} done } # 禁止root用户远程登录 BANROOTRLOGIN () { echo "# 禁止root用户远程登录 #" >> ${bllogs} # 在CentOS8或OpenSSH8版本中,已移除pam_securetty.so,好在仍然可以用 shversion=`ssh -V 2>&1 | awk -F'[_,]' '{print $2}'` shversion=${shversion:0:1} [ -z ${shversion} ] && shversion=0 if [ "${osversion}" -le 8 ] && [ "${shversion}" -le 8 ] then pamlogin=`grep ^auth ${pamfile3} | grep -w 'pam_securetty.so'` if [ -z "${pamlogin}" ] then insline=`grep -n ^auth ${pamfile3} | head -n 1` eval sed -i '${insline}s/$/&\ pam_securetty.so' ${pamfile3} echo '> 已添加配置禁止root远程telnet登录' >> ${bllogs} else echo '> 系统已禁止root远程telnet登录,无需修改' >> ${bllogs} fi fi sshlogin=`grep ^PermitRootLogin ${sshconfig} | awk '{print $2}'` if [ -z "${sshlogin}" ] then echo 'PermitRootLogin no' >> ${sshconfig} echo -e '! 已添加配置禁止root远程ssh登录\n! 请确保有其他可远程登录的账号或途径' >> ${bllogs} elif [ "${sshlogin}" = "yes" ] then sed -i '/^PermitRootLogin/s/yes/no/g' ${sshconfig} echo -e '! 已修改配置禁止root远程ssh登录\n! 请确保有其他可远程登录的账号或途径' >> ${bllogs} else echo '> 系统已禁止root远程ssh登录,无需修改' >> ${bllogs} fi [ ${erstsshd} -eq 1 ] && service sshd restart && echo '! 已重启sshd服务,须再三确认后方可退出' >> ${bllogs} } # 对IP登录的设备禁用telnet协议 REMOVETELNET () { echo "# 对IP登录的设备禁用telnet协议 #" >> ${bllogs} cktelnet=`rpm -qa telnet` ckxinetd=`rpm -qa xinetd` xinetdcfg="/etc/xinetd.d/telnet" if [ -z "${cktelnet}" ] then echo '> 本机未安装telnet,无需修改' >> ${bllogs} else if [ -z "${ckxinetd}" ] then if [ "${rmtelnet}" -eq 1 ] || [ "${osversion}" -lt 7 ] then rpm -e `rpm -qa telnet` --nodeps echo '> 用户选择或者系统版本太低,已经卸载telnet' >> ${bllogs} else yum -y install xinetd echo 'disable = yes' > ${xinetdcfg} service xinetd start echo '> 已安装xinetd并禁用telnet协议' >> ${bllogs} fi else if [ -e "${xinetdcfg}" ] then cftelnet=`grep -v '^#' ${xinetdcfg} | grep disable | sed 's/\ //g' | awk -F= '{print $2}'` if [ "${cftelnet}" = yes ] then echo '> 系统已经禁用telnet协议,无需修改' >> ${bllogs} elif [ "${cftelnet}" = no ] then sed -i '/disable/s/no/yes/g' ${xinetdcfg} echo '> 已经修改配置禁用telnet协议' >> ${bllogs} elif [ -z "${cftelnet}" ] then echo 'disable = yes' > ${xinetdcfg} service xinetd restart echo '> 已经添加配置禁用telnet协议' >> ${bllogs} else echo -e "! 系统存在异常的telnet配置\n! 请检查文件${xinetdcfg}" >> ${bllogs} fi else echo 'disable = yes' > ${xinetdcfg} service xinetd restart echo '> 已经创建配置禁用telnet协议' >> ${bllogs} fi fi fi } # 设置口令最小长度 SETPWDMINLEN () { echo "# 设置口令最小长度 #" >> ${bllogs} if [ -e ${pamfile1} ] then pamcompwd=`grep '^password' ${pamfile1} | grep required | grep pam_cracklib.so | grep minlen` if [ -n "${pamcompwd}" ] then pwdminlen=`echo "${pamcompwd}" | awk -F'=' '{print $2}'` if [ ${pwdminlen} -ge ${pwdminlennew} ] then echo '> 当前口令最小长度符合要求,无需修改' >> ${bllogs} else eval sed -i '/minlen/s/${pwdminlen}/${pwdminlennew}/g' ${pamfile1} echo "> 已经将参数minlen的值由${pwdminlen}修改为${pwdminlennew}" >> ${bllogs} fi else pamcompwd=`grep '^password' ${pamfile1} | grep required | grep pam_cracklib.so` if [ -z "${pamcompwd}" ] then insline=`grep -n ^password ${pamfile1} | awk -F: '{print $1}' | tail -n 1` eval sed -i '${insline}a\password\ \ \ \ required\ \ \ \ \ \ pam_cracklib.so\ minlen=${pwdminlennew}' ${pamfile1} echo "> 已添加参数pam_cracklib.so minlen=${pwdminlennew}" >> ${bllogs} else eval sed -i '/pam_cracklib.so/s/$/&\ minlen=${pwdminlennew}/g' ${pamfile1} echo "> 已追加参数minlen=${pwdminlennew}" >> ${bllogs} fi fi else echo "> 找不到文件${pamfile1}" >> ${bllogs} fi if [ -e ${pamfile2} ] then pamcompwd=`grep '^password' ${pamfile2} | grep required | grep pam_cracklib.so | grep minlen` if [ -n "${pamcompwd}" ] then pwdminlen=`echo "${pamcompwd}" | awk -F'=' '{print $2}' | awk '{print $1}'` if [ ${pwdminlen} -ge ${pwdminlennew} ] then echo '> 当前口令最小长度符合要求,无需修改' >> ${bllogs} else eval sed -i '/minlen/s/${pwdminlen}/${pwdminlennew}/g' ${pamfile2} echo "> 已经将参数minlen的值由${pwdminlen}修改为${pwdminlennew}" >> ${bllogs} fi else pamcompwd=`grep '^password' ${pamfile2} | grep required | grep pam_cracklib.so` if [ -z "${pamcompwd}" ] then insline=`grep -n ^password ${pamfile2} | awk -F: '{print $1}' | tail -n 1` eval sed -i '${insline}a\password\ \ \ \ required\ \ \ \ \ \ pam_cracklib.so\ minlen=${pwdminlennew}' ${pamfile2} echo "> 已添加参数pam_cracklib.so minlen=${pwdminlennew}" >> ${bllogs} else eval sed -i '/pam_cracklib.so/s/$/&\ minlen=${pwdminlennew}/g' ${pamfile2} echo "> 已追加参数minlen=${pwdminlennew}" >> ${bllogs} fi fi else echo "> 找不到文件${pamfile2}" >> ${bllogs} fi if [ -e ${logindef} ] then pamcompwd=`grep '^PASS_MIN_LEN' ${logindef} | awk '{print $2}'` if [ ${pamcompwd} -ge ${pwdminlennew} ] then echo '> 密码长度配置正确,无需修改' >> ${bllogs} else eval sed -i '/^PASS_MIN_LEN/s/${pamcompwd}/${pwdminlennew}/g' ${logindef} echo "> 已修改密码最小长度为${pwdminlennew}" >> ${bllogs} fi else echo "> 找不到文件${logindef}" >> ${bllogs} fi } # 设置密码复杂度 SETPWDCOMPLEX () { echo "# 设置密码复杂度 #" >> ${bllogs} if [ -e ${pamfile2} ] then pwdcpxlen=`egrep 'ucredit|lcredit|dcredit|ocredit' ${pamfile2} | tr " " "\n" | egrep 'ucredit|lcredit|dcredit|ocredit' | awk 'END{print NR}'` if [ -z ${pwdcpxlen} ] || [ ${pwdcpxlen} -eq 0 ] then sed -i '/pam_cracklib.so/s/$/&\ ucredit=-1\ lcredit=-1\ dcredit=-1/g' ${pamfile2} echo '> 已添加参数 ucredit=-1 lcredit=-1 dcredit=-1' >> ${bllogs} elif [ ${pwdcpxlen} -ge 3 ] then echo '> 当前密码复杂度符合要求,无需修改' >> ${bllogs} else echo -e "! 当前密码复杂度不符合要求\n! 请修改${pamfile2}\n! 添加以下参数中的至少3种:\n! ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1" >> ${bllogs} fi else echo "> 找不到文件${pamfile2}" >> ${bllogs} fi } # 设置口令生存周期 SETPWDLIFE () { echo "# 设置口令生存周期 #" >> ${bllogs} if [ -e ${logindef} ] then pwdlife=`grep '^PASS_MAX_DAYS' ${logindef} | awk '{print $2}'` if [ ${pwdlife} -le ${pwdlifenew} ] then echo '> 密码生存周期配置正确,无需修改' >> ${bllogs} else eval sed -i '/^PASS_MAX_DAYS/s/${pwdlife}/${pwdlifenew}/g' ${logindef} echo "> 已修改密码生存周期为${pwdlifenew}" >> ${bllogs} fi else echo "> 找不到文件${logindef}" >> ${bllogs} fi } # 配置命令行界面超时时间 AUTOLOGOUT () { echo "# 设置命令行界面超时时间 #" >> ${bllogs} prflogout=`grep export ${prfile} | grep TMOUT` if [ -z "${prflogout}" ] then insline=`grep -n ^export ${prfile} | awk -F: '{print $1}' | tail -n 1` eval sed -i '${insline}a\export\ TMOUT=${logoutimenew}' ${prfile} source ${prfile} echo "> 已添加命令行界面超时时间为${logoutimenew}秒" >> ${bllogs} else logoutime=`grep ^export ${prfile} | grep TMOUT | awk -F'=' '{print $2}' | sed 's/\ //g'` if [ ${logoutime} -ge ${logoutimenew} ] then eval sed -i '/TMOUT/s/${logoutime}/${logoutimenew}/g' ${prfile} source ${prfile} echo "> 已经修改自动退出时间为${logoutimenew}秒" >> ${bllogs} else echo '> 系统自动退出时间符合要求,无需修改' >> ${bllogs} fi fi } # 修改MASK设置 CHECKMASK () { echo "# 检查MASK设置 #" >> ${bllogs} for file in ${umask1} ${umask2} ${umask3} do umaskvs=`egrep -v "^* #|^#" ${file} | grep umask | awk '{print $2}' | sed 's/[^0-9]//g' | awk 'END{print NR}'` if [ ${umaskvs} -eq 2 ] then umaskv1=`egrep -vn "^* #|^#" ${file} | grep umask | sed 's/[^0-9:]//g' | head -n 1 | awk -F':' '{print $2}'` umaskv2=`egrep -vn "^* #|^#" ${file} | grep umask | sed 's/[^0-9:]//g' | tail -n 1 | awk -F':' '{print $2}'` if [ "${umaskv1}" -ge "${unoroot}" ] then echo "> 文件${file}中所设置的umask为${umaskv1},无需调整" >> ${bllogs} else if [ ${autormask} -eq 1 ] then insline=`egrep -vn "^* #|^#" ${file} | grep umask | sed 's/[^0-9:]//g' | head -n 1 | awk -F':' '{print $1}'` eval sed -i '${insline}s/${umaskv1}/${unoroot}/g' ${file} echo -e "! 文件${file}中的umask已经由${umaskv1}改为${unoroot}" >> ${bllogs} else echo -e "! 文件${file}中的umask为${umaskv1},不符合要求\n! 请修改为安全的MASK值,建议${unoroot}" >> ${bllogs} fi fi if [ "$umaskv2" -ge "${uisroot}" ] then echo "> 文件${file}中所设置的umask为${umaskv2},无需调整" >> ${bllogs} else if [ ${autormask} -eq 1 ] then insline=`egrep -vn "^* #|^#" ${file} | grep umask | sed 's/[^0-9:]//g' | tail -n 1 | awk -F':' '{print $1}'` eval sed -i '${insline}s/${umaskv2}/${uisroot}/g' ${file} echo -e "! 文件${file}中的umask已经由${umaskv2}改为${uisroot}" >> ${bllogs} else echo -e "! 文件${file}中的umask为${umaskv2},不符合要求\n! 请修改为安全的MASK值,建议${uisroot}" >> ${bllogs} fi fi elif [ ${umaskvs} -eq 3 -o ${umaskvs} -eq 1 ] then umaskv3=`egrep -vn "^* #|^#" ${file} | grep umask | sed 's/[^0-9:]//g' | tail -n 1 | awk -F':' '{print $2}'` if [ "${umaskv3}" -ge "${stdmask}" ] then echo "> 文件${file}中自设的全局umask为${umaskv3},无需调整" >> ${bllogs} else if [ ${autormask} -eq 1 ] then insline=`egrep -vn "^* #|^#" ${file} | grep umask | sed 's/[^0-9:]//g' | tail -n 1 | awk -F':' '{print $1}'` eval sed -i '${insline}s/${umaskv3}/${stdmask}/g' ${file} echo -e "! 文件${file}中的umask已经由${umaskv1}改为${unoroot}" >> ${bllogs} else echo -e "! 文件${file}中自设的全局umask为${umaskv3},不符合要求\n! 请修改为安全的MASK值,建议${unoroot}" >> ${bllogs} fi fi else echo -e "! 文件${file}已被重度修改\n! 请手动检查并修改umask的设置" >> ${bllogs} fi done } # 修改SNMP默认团体字 SETSNMPPUB () { echo "# 修改SNMP默认团体字 #" >> ${bllogs} snmprpm=`rpm -qa net-snmp` snmpcfg="/etc/snmp/snmpd.conf" if [ -e "${snmpcfg}" ] then comname=`grep ^com2sec ${snmpcfg} | grep public` if [ -n "${comname}" ] then eval sed -i '/^com2sec/s/public/${comnamenew}/g' ${snmpcfg} echo "> 已经修改默认团体名为${comnamenew}" >> ${bllogs} else echo '> 默认团体字不是public,无需修改' >> ${bllogs} fi else [ -n "${snmprpm}" ] && echo '! 系统已安装SNMP,但未找到配置文件' >> ${bllogs} || echo '> 系统未安装SNMP,无需修改' >> ${bllogs} fi } # 禁止UID为0的用户 BANUID () { echo "# 禁止UID为0的用户 #" >> ${bllogs} userids=`grep -v root /etc/passwd | awk -F: '{print $1" "$3}' | grep -w 0 | awk '{print $1}'` if [ -n "${userids}" ] then for username in ${userids[@]} do usermod -L ${username} echo "> 已锁定UID为0的账号${username}" >> ${bllogs} done else echo "> 不存在UID为0的账号" >> ${bllogs} fi } # 禁用Ctrl+Alt+Del组合键 BANKEYCAD () { echo "# 禁用Ctrl+Alt+Del组合键 #" >> ${bllogs} cadtarget="/usr/lib/systemd/system/ctrl-alt-del.target" if [ -e "${cadtarget}" ] then rm -f ${cadtarget} init q echo "> 已删除文件并禁用ctrl+alt+del组合键" >> ${bllogs} else echo "> 系统已禁用禁用ctrl+alt+del组合键,无需修改" >> ${bllogs} fi } # 配置用户所需最小权限 SETUSERLMT () { echo "# 配置用户所需最小权限 #" >> ${bllogs} chmod ${modpwdgrp} /etc/group echo "> 修改文件/etc/group属性为${modpwdgrp}" >> ${bllogs} chmod ${modpwdgrp} /etc/passwd echo "> 修改文件/etc/passwd属性为${modpwdgrp}" >> ${bllogs} chmod ${modshadow} /etc/shadow echo "> 修改文件/etc/shadow属性为${modshadow}" >> ${bllogs} } # 配置密码重复使用次数限制 PWDREUTIME () { echo "# 配置密码重复使用次数限制 #" >> ${bllogs} if [ -e ${pamfile2} ] then pwdreuse=`grep ^password ${pamfile2} | grep sufficient | grep remember | awk -F'=' '{print $2}' | awk '{print $1}'` if [ -z ${pwdreuse} ] then insline=`grep -n ^password ${pamfile2} | grep sufficient | awk -F: '{print $1}' | tail -n 1` eval sed -i '${insline}s/$/\&\ remember=${pwdreusnew}/g' ${pamfile2} echo "> 已添加参数 remember=${pwdreusnew}" >> ${bllogs} elif [ ${pwdreuse} -le ${pwdreusnew} ] then echo '> 密码重复使用次数限制符合要求,无需修改' >> ${bllogs} else insline=`grep -n ^password ${pamfile2} | grep sufficient | awk -F: '{print $1}' | tail -n 1` eval sed -i '${insline}s/${pwdreuse}/${pwdreusnew}/g' ${pamfile2} echo "> 已将参数remember的值由${pwdreuse}修改为${pwdreusnew}" >> ${bllogs} fi else echo "> 找不到文件${pamfile2}" >> ${bllogs} fi } # 禁止ICMP重定向和源路由 BANICMPR () { echo "# 禁止ICMP重定向和源路由 #" >> ${bllogs} icmpredrct=`grep ^net.ipv4.conf.all.accept_redirects ${sysctlcfg} | awk -F= '{print $2}' | sed 's/[^0-9]//g'` if [ -z ${icmpredrct} ] then echo 'net.ipv4.conf.all.accept_redirects=0' >> ${sysctlcfg} echo '> 已添加ICMP重定向配置' >> ${bllogs} elif [ ${icmpredrct} -eq 0 ] then echo '> 系统已配置ICMP重定向,无需修改' >> ${bllogs} else eval sed -i '/^net.ipv4.conf.all.accept_redirects/s/${icmpredrct}/0/g' ${sysctlcfg} echo '> 已修改ICMP重定向配置' >> ${bllogs} fi icmpsrcrut=`grep ^net.ipv4.conf.all.accept_source_route ${sysctlcfg} | awk -F= '{print $2}' | sed 's/[^0-9]//g'` if [ -z ${icmpsrcrut} ] then echo 'net.ipv4.conf.all.accept_source_route=0' >> ${sysctlcfg} echo '> 已添加ICMP源路由配置' >> ${bllogs} elif [ ${icmpsrcrut} -eq 0 ] then echo '> 系统已配置ICMP源路由,无需修改' >> ${bllogs} else eval sed -i '/^net.ipv4.conf.all.accept_source_route/s/${icmpsrcrut}/0/g' ${sysctlcfg} echo '> 已修改ICMP源路由配置' >> ${bllogs} fi if [ -z ${icmpredrct} ] || [ -z ${icmpsrcrut} ] || [ ${icmpredrct} -ne 0 ] || [ ${icmpsrcrut} -ne 0 ] then sysctl -p fi } ##### 开始调整系统基线 ##### # 锁定额外系统用户 # 请修改需要锁定的账号 lockusers=(bin daemon adm uucp mail) LOCKUSER # 禁止root远程登录 # 立即重启sshd请将erstsshd修改为1 erstsshd=0 BANROOTRLOGIN # 配置telnet服务 # 默认Linux6系统将卸载telnet # 若不卸载请修改rmtelnet为0 rmtelnet=1 REMOVETELNET # 设置密码最小长度 # 请修改密码最小长度 pwdminlennew=6 SETPWDMINLEN # 设置密码复杂度(须先配置密码最小长度) SETPWDCOMPLEX # 设置口令生存周期 # 请修改口令生存周期 pwdlifenew=90 SETPWDLIFE # 配置命令行界面超时时间 logoutimenew=180 AUTOLOGOUT # 修改MASK设置 # 请修改MASK标准建议值 unoroot=027 uisroot=077 # 请修改已自设的全局MASK建议值 stdmask=027 # 如果需要自动修改MASK为建议值 # 将autormask的值改为1 autormask=0 CHECKMASK # 修改SNMP默认团体字(更新使用方配置的团体名) # 请修改默认团体字名称 comnamenew="mycomname" SETSNMPPUB # 禁止UID为0的用户 BANUID # 禁用Ctrl+Alt+Del组合键 BANKEYCAD # 配置用户所需最小权限 # 请修改文件属性值 modpwdgrp=644 modshadow=600 SETUSERLMT # 检查密码重复使用次数限制 # 请设置密码重复使用次数 pwdreusnew=5 PWDREUTIME # 禁止ICMP重定向和源路由 BANICMPR grep '^!' ${bllogs}
原创文章禁止转载:技术学堂 » Linux操作系统基线设置自动化脚本(Shell版)