CentOS安全基线检查与SELinux策略定制,本质上就是两件事:先用一套标准化的检查清单把系统默认的安全漏洞全部堵上,再根据你的业务场景把SELinux从"一刀切禁止"调整为"精准放行"。很多运维人员要么直接把SELinux设成permissive模式图省事,要么根本不做基线检查就上线,这两种做法在生产环境里都是高危操作。正确的做法是先跑完CIS Benchmark或者等保2.0的检查项,再针对每一条不合规项逐一修复,最后根据实际服务需求编写自定义SELinux策略模块,让安全和可用性达到平衡。

这篇文章会把从基线检查到SELinux策略定制的完整流程拆开来讲,包括具体的检查命令、配置修改方法、策略编写示例,以及实际生产中容易踩的坑。

一、为什么CentOS默认配置不安全

CentOS安装完成后,系统默认开启了大量不必要的服务和宽松的权限策略。举几个典型例子:sshd默认允许root远程登录、防火墙规则几乎全开、audit审计日志没有启用、密码策略过于简单。这些默认配置在开发测试环境没问题,但放到生产服务器上就是一个个待引爆的安全隐患。安全基线检查的目的,就是把这些默认配置逐项收紧到符合行业标准的状态。

目前主流的基线标准有三个:CIS CentOS Benchmark、等保2.0三级要求、以及各云厂商的安全加固规范。实际操作中建议以CIS Benchmark为核心参考,因为它的检查项最细、覆盖最全,而且有自动化工具可以直接扫描。

二、CentOS安全基线检查的核心步骤

基线检查分为手动检查和自动化扫描两种方式。自动化推荐使用OpenSCAP工具,它是Red Hat官方支持的合规扫描器,能直接对照CIS标准生成报告。安装和使用方法如下:

yum install -y openscap-scanner scap-security-guide
oscap xccdf eval --profile cis --report report.html /usr/share/xml/scap/ssg/content/ssg-centos7-ds.xml

这条命令会对CentOS 7系统执行CIS基准扫描,生成HTML格式的报告。报告里会列出每一项检查的结果:pass(通过)、fail(不通过)、notapplicable(不适用)。针对fail项,你需要逐一修复。

下面列出最关键的几项基线检查内容和具体修复方法:

1. 账户与密码策略加固

检查密码最小长度、过期时间、复杂度要求。编辑/etc/login.defs和/etc/pam.d/system-auth文件:

# /etc/login.defs
PASS_MIN_LEN 14
PASS_MAX_DAYS 90
PASS_MIN_DAYS 7
PASS_WARN_AGE 14

# /etc/pam.d/system-auth
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok
password required pam_deny.so

同时要锁定无用账户,检查/etc/passwd里UID为0的非root用户,以及没有登录shell的系统账户:

awk -F: '($3 == 0) {print}' /etc/passwd
awk -F: '($7 !~ /nologin|false$/) {print}' /etc/passwd
2. SSH服务安全加固

编辑/etc/ssh/sshd_config,重点修改以下几项:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
Protocol 2

修改后重启sshd服务生效:systemctl restart sshd。这里有个细节很多人忽略——改完配置后一定要先开一个新的SSH会话测试连接,确认没问题再关掉旧会话,否则一旦配置写错会直接锁死自己。

3. 防火墙与网络服务最小化

用firewalld或者iptables只开放业务必需的端口。先查看当前开放的端口:

firewall-cmd --list-all
# 或者
iptables -L -n --line-numbers

然后删除不需要的规则,只保留必要端口。同时关闭不需要的服务:

systemctl list-unit-files --state=enabled
systemctl disable postfix
systemctl disable avahi-daemon
systemctl disable cups

对于CentOS 8及以上版本,建议统一使用firewalld,规则管理更清晰。

4. 审计日志与入侵检测

确保auditd服务运行并配置了关键审计规则。编辑/etc/audit/rules.d/audit.rules:

-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k scope
-w /var/log/auth.log -p wa -k logins
-a always,exit -F arch=b64 -S open,openat,creat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access

启动并设置开机自启:

systemctl enable auditd
systemctl start auditd
三、SELinux策略定制的完整流程

基线检查做完后,下一步就是处理SELinux。很多人的第一反应是直接setenforce 0或者把/etc/selinux/config里的SELINUX改成disabled,这是最不推荐的做法。SELinux是Linux内核级别的强制访问控制机制,关掉它等于把系统的最后一道防线拆了。正确的做法是保持enforcing模式,然后针对业务需求编写自定义策略。

1. 先搞清楚SELinux的三种模式

enforcing:强制模式,违反策略的操作直接被拦截并记录日志。permissive:宽容模式,违反策略只记录不拦截。disabled:完全关闭。生产环境必须用enforcing,调试阶段可以临时切permissive,但不能长期使用。

查看当前状态:

getenforce
sestatus
2. 分析SELinux拒绝日志找问题

当SELinux拦截了某个操作时,audit日志里会记录详细信息。用ausearch或者sealert查看:

ausearch -m avc -ts recent
sealert -a /var/log/audit/audit.log

sealert会给出人类可读的分析报告,包括被拦截的进程、涉及的文件路径、建议的解决方案。这是定制策略的起点——你得先知道SELinux在拦什么。

3. 使用audit2allow生成策略模块

audit2allow是SELinux工具包里的神器,它能根据audit日志自动生成允许规则。基本用法:

# 生成所有最近的拒绝事件对应的策略
ausearch -m avc -ts recent | audit2allow -M my_custom_policy

# 查看生成的策略内容
cat my_custom_policy.te

# 安装策略模块
semodule -i my_custom_policy.pp

生成的.te文件是策略的源代码,你可以先查看内容再决定是否安装。这里有个关键原则:不要无脑把所有拒绝都放行,要逐条审查。比如某个拒绝是因为httpd试图写/tmp目录,这可能是配置错误而不是策略太严,应该先修复配置再考虑放策略。

4. 手动编写自定义SELinux策略模块

当audit2allow生成的策略不够精细时,需要手动编写。假设你要让Nginx服务读取/data/web目录下的文件,需要创建一个类型为httpd_sys_content_t的文件上下文:

# 创建策略文件
cat > nginx_custom.te << 'EOF'
module nginx_custom 1.0;

require {
    type httpd_t;
    type httpd_sys_content_t;
    class file { read open getattr };
}

#============= httpd_t ==============
allow httpd_t httpd_sys_content_t:file { read open getattr };
EOF

# 编译并安装
checkmodule -M -m -o nginx_custom.mod nginx_custom.te
semodule_package -o nginx_custom.pp -m nginx_custom.mod
semodule -i nginx_custom.pp

如果涉及端口或布尔值调整,还需要配合semanage命令:

# 允许httpd使用非标准端口
semanage port -a -t http_port_t -p tcp 8080

# 开启某个布尔开关
setsebool -P httpd_can_network_connect on
5. 文件上下文标签管理

SELinux通过文件上下文(context)来控制进程对文件的访问。常用命令:

# 查看文件上下文
ls -Z /data/web

# 修改文件上下文
semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?"
restorecon -Rv /data/web

# 查看进程的域(domain)
ps -eZ | grep nginx

文件上下文设置错误是SELinux问题里最常见的原因之一。比如你把网站文件放到了/home目录下,默认上下文是user_home_t,httpd进程根本读不了。正确做法是把文件放到/var/www/html或者自定义目录并手动设置上下文。

四、生产环境中的实战建议

第一,基线检查不是一次性工作。建议用cron定期跑OpenSCAP扫描,或者集成到CI/CD流程里,每次系统变更后自动检查。第二,SELinux策略定制要建立版本管理,把所有自定义的.te和.pp文件纳入代码仓库,方便回滚和审计。第三,不要在生产环境直接用audit2allow -M生成的策略,先在测试环境验证,确认不会引入新的安全风险再上线。第四,对于容器化部署的场景,要特别注意容器内的SELinux标签,Docker和Podman都支持--security-opt参数来指定标签。

最后说一个很多人忽视的点:SELinux策略和防火墙是两层不同的防护。防火墙控制的是网络层面的访问,SELinux控制的是进程层面的权限。两者不能互相替代,必须同时配置才能形成完整的纵深防御体系。

总结一下,CentOS安全基线检查是"先体检再治病",SELinux策略定制是"精准手术而非一刀切"。把这两件事做扎实了,你的服务器安全水位会提升一个档次,而且不会因为过度限制导致业务跑不起来。