写在前面:CentOS即将停止更新服务,对于已经安装CentOS的用户来说,系统安全加固就显得更加重要。
本文将基于最小化安装的CentOS 7.9,并参考《等级保护2.0》测评指导书(二级)的通用部分,从“身份鉴别”、“访问控制”、“安全审计”、“入侵防御”、“恶意代码防范”、“剩余信息保护”六个方面,介绍Linux安全加固。
一、准备工作
1.工具安装
考虑系统安全性,请选择最小化安装CentOS。系统安装和更新以及网络基本配置请参考"CentOS 7.9安装和更新" 。
1)命令补全
yum install bash-completion.noarch -y
安装后需要重启系统生效。
2)基础网络管理
yum install net-tools.x86_64 -y
*提示:可用yum search搜索不太清楚的安装包,然后再yum安装。
2.防火墙和selinux配置
1)防火墙配置
开放SSH端口
firewall-cmd --permanent --add-port=22/tcp --zone=work
为了更加安全,可以限定IP访问:
firewall-cmd --permanent --add-source=192.168.28.1
firewall-cmd --permanent --add-source=192.168.28.2
2)关闭selinux
selinux默认为Enforcing,用setenforce 0 临时设置为允许。
.
编辑/etc/selinux/config,将文件里SELINUX=enforcing改为SELINUX=disabled,退出保存,重启系统,禁用selinux。
完成上述准备后即可开始加固。
二、身份鉴别
等保要求:
a) 应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换;
b) 应具有登录失败处理功能,应配置并启用结束会话、限制非法登录次数和当登录连接超时自动退出等相关措施;
c) 当进行远程管理时,应采取必要措施防止鉴别信息在网络传输过程中被窃听。
加固方法:
1.用户密码检查
1)空密码检查
用下面命令查看是否存在空口令(空密码)帐号,如果命令结果为空则没有,否则要对空口令用户设置符合强度的密码。【说明:本文所有标灰底命令均需ROOT用户执行】
awk -F: '($2 == ""){print $1}' /etc/shadow
本文实验系统没有,所以结果为空。
2)弱口令排查
对于非空口令自建用户账号,需要与用户沟通,确保其密码符合要求。一般密码要求应当由大写字母、小写字母、数字、特殊符号三种或三种以上组合。
2.密码有效期策略
修改/etc/login.defs配置密码周期策略。
vi /etc/login.defs
PASS_MAX_DAYS 90 #密码有效期90天
PASS_MIN_DAYS 0 #密码设置后限制修改的天数,0天表示不限制
PASS_MIN_LEN 8 #密码最小长度8位,需要与密码复杂度配置保持一致
PASS_WARN_AGE 14 #密码过期提前14天提醒
注意:策略只对新创建帐号生效,已有【自建】帐号需要手动修改/etc/shadow文件对应值。root等系统账号不建议修改有效期。
3.密码复杂度策略
配置文件:/etc/pam.d/system-auth
模块名称:pam_pwquality.so
备份(pam文件非常重要,修改前应当备份):
cp /etc/pam.d/system-auth /root/system-auth.bak
vi /etc/pam.d/system-auth
编辑/etc/pam.d/system-auth文件,修改或添加如下参数:
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= minlen=8 lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1 difok=5 enforce_for_root
参数含义:
minlen = 8 #密码最小长度
lcredit = -1 #至少1个小写字母,注意是 -1
ucredit = -1 #至少1个大写字母
dcredit = -1 #至少1个数字
ocredit = -1 #至少1个特殊符号
difok = 5 #新密码与旧密码至少有5个不同字符
enforce_for_root #强制root用户也须符合本策略
配置后,系统将强制用户使用强口令,用户修改口令必须符合上述要求。
5.用户登录控制策略
通过pam_tally2.so的PAM模块,来限定用户的登录失败次数,如果次数达到设置的阈值,则锁定用户。
用以下命令查找模块是否存在,如果有则可以继续下面的加固配置,否则跳过本条。
find /lib*/* -iname "pam_tally2.so"
1)配置本地控制台登录控制策略,每输错1次临时锁定30秒,连续输错5次锁定600秒(10分钟),root用户也不放过~!
vi /etc/pam.d/login
在#%PAM-1.0的下面第3行下面写入以下一行,如图所示:
auth required pam_tally2.so deny=5 lock_time=30 unlock_time=600 even_deny_root root_unlock_time=600
特别说明:因为login文件里已经包含了system-auth,所以我们不用在system-auth这个全局文件里再配置,网上有不少教程都没有提到这一点,导致密码错误1次系统却记成2次,这是我们需要注意的地方。另外,如果复制上面的配置,请先用记事本粘贴再重新复制,防止编码错误导致配置失效或错误。
2)配置SSH远程登录控制策略,每输错1次临时锁定30秒,连续输错5次锁定600秒(10分钟)
vi /etc/pam.d/sshd
在适当位置添加如下行
auth required pam_tally2.so deny=5 lock_time=30 unlock_time=600 even_deny_root root_unlock_time=600
如图所示:
3)锁定后的操作
账号锁定后,用户可以等待自动解锁,也可以由系统管理员使用root用户手动解锁用户账号。解锁命令:
pam_tally2 -u <username> -r
或者
pam_tally2 -r -u <username>
查看用户登录失败信息:
pam_tally2 -u <username>
4)全局登录控制也可以控制,主要是通过/etc/pam.d/system-auth文件,但要记得在/etc/pam.d/sshd文件中包含system-auth相关项,否则SSH登录将不受该策略控制。
5)pam_tally2模块的参数含义
onerr=[succeed|fail]
file=/path/to/log #失败登录日志文件,默认为/var/log/tallylog
audit #如果登录的用户没有找到,则将用户名信息记录到系统日志中
silent #静默,不打印提示信息
no_log_info #不通过syslog记录日志信息
deny=n #登录失败n次后,锁定unlock_time(秒)时间,无unlock_time则永久锁定
lock_time=n #登录失败后临时锁定时间(秒),一般不设置
unlock_time=n #超出失败登录次数限制后,解锁的时间(秒)
no_lock_time #不在日志文件/var/log/faillog 中记录.fail_locktime字段
magic_root #root用户(uid=0)调用该模块时,计数器不会递增
even_deny_root #root用户失败登录次数超过deny=n次后拒绝访问
root_unlock_time=n #与even_deny_root相对应的选项,如果配置该选项,则root用户在登录失败次数超出限制后被锁定指定时间
三、访问控制
要求1:应及时删除多余的、过期的帐户,避免共享帐户的存在。删除或禁用临时、过期及可疑的帐号,防止被非法利用。
要求2:当对服务器进行远程管理时,应采取必要措施,防止鉴别信息在网络传输过程中被窃听。
要求3:应通过设定终端接入方式、网络地址范围等条件限制终端登录。
要求4:应根据安全策略设置登录终端的操作超时锁定。
1.禁用不必要的用户
usermod -L <用户名>
主要是管理员创建的普通帐号,如这里添加一个用户:user
useradd user #添加用户
usermod -L user #锁定用户,/etc/shadow密码密文列开头为“!”
userdel -U user #解锁user用户
userdel -r user #将用户user及家目录/home/user一并删除,家目录有数据的话慎用。
2.检查SSH安全配置
grep Protocol /etc/ssh/sshd_config #协议应为Protocol 2
cat /.rhosts #无此文件则安全,有此文件需删除。
cat /etc/hosts.equiv #无此文件则安全,有此文件需删除。
3.远程管理安全配置
主要是检查telnet服务是否开启,telnet是明文传输,远程管理过程中,密码等敏感信息很容易被窃听,非常不安全。检查最直接的方法就是用命令netstat -atln|grep 23看看23端口是否处于监听状态。
本文是基于最小化安装的CentOS,所以没有telnet服务,这里省略。
4.文件默认访问权限策略
修改新用户默认umask值
cp -p /etc/profile /etc/profile.bak
vi /etc/profile
修改新用户默认umask值,改后效果为:所有用户创建的文件、文件夹,默认“other”权限为0,意思即为禁止用户和用户所属组以外的其它用户访问。
source /etc/profile #使配置生效
5.ssh安全配置
先备份:
cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
UsePAM yes 启用Pam认证
sed -i "/#UsePAM yes/c UsePAM yes" /etc/ssh/sshd_config
# grep UsePAM /etc/ssh/sshd_config
编辑/etc/ssh/sshd_config
vi /etc/ssh/sshd_config
PermitRootLogin yes这行去掉注释,yes改为no禁止root远程登录,同时去掉相邻的4行注释,提高SSH安全性。修改后如下图:
6.禁止应用服务用户shell
这里以mysql为例,本文系统没有此用户,安装MySQL会自动生成,或自行添加此用户:
chsh -s /sbin/nologin mysql
其它应用服务如nginx也可以参考此方法。
解除禁止:
chsh -s /bin/bash mysql
7.应用访问控制
对接入服务器的IP、方式等进行限制,可以阻止非法入侵。
1) 在/etc/hosts.allow和/etc/hosts.deny文件中配置接入限制
最好的策略就是阻止所有的主机,在“/etc/hosts.deny”文件中加入“ ALL:ALL@ALL, PARANOID ”,然后再在“/etc/hosts.allow” 文件中加入所有允许访问的主机列表。如下操作:
编辑 hosts.deny文件,加入下面该行:
vi /etc/hosts.deny
编辑hosts.allow 文件,
vi /etc/hosts.allow
加入允许访问的主机列表,如下图所示:
具体含义请自行百度,篇幅原因这里不做赘述。
也可以通过以下命令在hosts.allow里快速追加允许的IP或IP地址段。
echo "sshd:10.166.214.65" >>/etc/hosts.allow
也可以用防火墙进行更加精细的访问控制,具体方法这里也省略。
8.关键文件权限
ls -dl /etc/security/
ls -l /etc/passwd
ls -l /etc/group
ls -l /etc/shadow
应确保上述关键文件的权限符合最小化原则。
9.超时锁定
1)设置登录超时时间,释放系统资源,也提高服务器的安全性。
执行以下命令在/etc/profile中添加配置,单位是秒。
echo "export TMOUT=600" >>/etc/profile #用户无操作600秒,即10分钟,系统自动注销
source /etc/profile #生效
echo $TMOUT #检验
改变这项设置后,必须注销再登录方可生效。
2)如果运行了图形桌面系统,则需要开启屏幕保护功能,本系统最小化安装,所以不涉及。具体设置方法:设置 -> 系统设置 -> 屏幕保护程序进行设置。
四、安全审计
要求1:审计范围应覆盖到服务器和重要客户端上的每个操作系统用户和数据库用户。
要求2:应保护审计记录,避免受到未预期的删除、修改或覆盖等。
1.日志服务检查
确保审核服务正确运行,审核策略开启后,当系统出现故障、安全事故则可以查看系统日志文件,排除故障、追踪入侵信息等。
检查rsyslog、auditd服务状态:
systemctl status rsyslog.service
systemctl status auditd.service
状态应该为:Active: active (running)……
2.日志配置增强
查看/etc/rsyslog.conf文件中所配置对应的日志文件权限是否为特定用户只读权限,防止重要日志信息被覆盖,配置策略,让系统日志文件转储一个月,保留6个月的信息。先查看目前配置,
more /etc/logrotate.conf | grep -v "^#\|^$"
将配置改为下图所示内容,默认按周转储,需改为按月,即注销weekly,改为monthly,默认保留1个月日志,改为保留6个月:
# vi /etc/logrotate.conf
修改后重启日志服务:
systemctl restart rsyslog.service
3.历史命令增强
修改默认历史命令保留条数,并为历史命令增加登录的IP地址、执行命令时间等
1)默认保存1000条,使用以下命令直接改为5000
sed -i 's/^HISTSIZE=1000/HISTSIZE=5000/g' /etc/profile
cat /etc/profile |grep HIST #验证修改结果
2)历史命令记录登录用户的IP地址、时间等信息
在/etc/profile的文件结尾添加如下配置:
USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}' |sed -e 's/[()]//g'`
if [ "$USER_IP" = "" ]; then
USER_IP=`hostname`
fi
export HISTTIMEFORMAT="%F %T $USER_IP `whoami` # "
shopt -s histappend
export PROMPT_COMMAND="history -a"
再执行以下命令让配置生效:
source /etc/profile
验证结果如下图所示:
五、入侵防御
要求1:操作系统遵循最小安装的原则,仅安装需要的组件和应用程序。
要求2:设置升级服务器,或定期执行更新命令,确保系统得到及时更新。
1.系统服务开启情况检查
CentOS7使用以下命令查看服务开启状况
systemctl list-unit-files |grep enabled
2.升级SSL和SSH
通过编译安装方式分别升级OpenSSL和OpenSSH,具体步骤可参考互联网上相关升级方案,后期有空也会发布SSH编译升级方面的文章,欢迎关注。
提示:一般在测试环境中尝试升级,确保成功升级后,再到生产环境中进行升级,升级前做好系统配置文件备份。如果服务器在云端或异地,建议先准备好备用远控通道,例如telnet、云主机控制台等,防止升级失败导致无法远程服务器。
3.攻击防御
防止拒绝服务攻击
TCP SYN保护机制等设置
1)打开 syncookie:
CentOS7之后默认为1,这里不用设置
表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
2)防syn 攻击优化
编辑/etc/sysctl.conf,添加如下行:
vi /etc/sysctl.conf
net.ipv4.tcp_max_syn_backlog = 2048
进入SYN包的最大请求队列,默认256,可用cat /proc/sys/net/ipv4/tcp_max_syn_backlog命令查验当前值。对重负载服务器,增加该值有好处,可根据服务器性能情况适当调高,这里调整到2048。
让配置生效:
sysctl -p
3)修改默认TTL值,迷惑攻击者
编辑/etc/sysctl.conf,在末尾增加net.ipv4.ip_default_ttl=128,伪装成Windows:
说明:ip_default_ttl取值范围:64-255
六、恶意代码防范
安装必要的杀毒软件,Linux系统虽然不易感染病毒,但是生产环境最好也要安装防病毒软件,并且通过防火墙仅开放必须的端口服务,也可以起到较好的防护作用。
也可以通过Linux内核功能inotify监视重要配置文件,在发生异常变化时及时通知管理者。
七、剩余信息保护
1.修改系统banner信息
清空相关banner信息,防止泄露系统内核等重要信息
echo "" >/etc/issue
echo "" >/etc/issue.net
echo "" >/etc/motd
添加个性化banner信息
echo 'Welcome to My Cloud Elastic Compute Service !' >>/etc/issue
echo 'Welcome to My Cloud Elastic Compute Service !' >>/etc/issue.net
echo 'Welcome to My Cloud Elastic Compute Service !' >>/etc/motd
连接服务器会显示个性化banner信息,而不是内核版本等信息:
2.检查FTP服务安全(如有)
ps -ef |grep ftp #无进程,再看看端口监听情况
netstat -atln |grep 21|grep LISTEN #如无输出则无需加固
如果存在FTP服务,需要禁用匿名登录,禁止ROOT登录FTP,修改FTP配置文件/etc/vsftpd.conf,在default小节手动增加或修改如下内容:
ftpd_banner="ATTENTION:You have logged onto a secured server. All accesses logged.\n\nlogin:"
其它应用加固这里不再介绍,请大家自行研究。
至此,Linux基本的安全加固方法已介绍完毕,感谢耐心阅读。
==============记录我和Linux、信息安全的点点滴滴!==============