最近写了一些操作系统加固的脚本,操作系统包括: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 该脚本对应的检查项
- 检查口令策略设置是否符合复杂度要求
#!/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
- 检查是否按角色进行帐号管理 / 检查是否按用户分配账号责任到人
#!/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
- 检查用户缺省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
- 检查是否删除或锁定无关账号
#!/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
- 检查是否设置登录超时
#!/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
- 检查是否限制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
- 检查是否非活动时断线
#!/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
- 检查登录提示-是否设置登录成功后警告
#!/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
- 检查日志文件权限设置
#!/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"
- 检查是否禁止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
还有其他的脚本,考虑到篇幅限制,可以参考下篇