跳转至

12. 安全加固

本章介绍 RHEL 9 的系统安全加固流程,涵盖 SELinux 策略管理、自动安全更新、账户与密码策略、auditd 审计配置、fail2ban 暴力破解防护,以及 OpenSCAP 合规扫描。安全加固应在基础环境部署完成后立即进行,是系统投入生产前的必要步骤。

SELinux 前提

第 1 章安装时已确认 SELinux 处于 Enforcing 模式,第 5 章 SSH 端口变更时已正确添加 SELinux 端口上下文。本章在此基础上,进一步介绍 SELinux 的日常管理与策略调整,而非从零配置。


12.1 前提条件

  • 已完成第一阶段全部配置(第 1–9 章)及第 10、11 章。
  • 通过 SecureCRT(SSH 端口 2222)以 ops 用户、密钥认证方式登录 192.168.1.100,执行 sudo -i 切换至 root 环境。
  • 官方仓库已启用(第 7 章),EPEL 仓库已启用(第 7 章)。

12.2 SELinux 管理

12.2.1 确认当前状态

# 查看当前模式
getenforce

# 查看详细信息(模式、策略类型、MLS 状态)
sestatus

检查点

getenforce 应返回 Enforcing。若为 Permissive,立即修复:

setenforce 1
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config

12.2.2 分析 SELinux 拒绝日志

当 SELinux 阻止某操作时,正确的处理方式是分析拒绝原因并精准修正,而非关闭 SELinux

# 安装分析工具
dnf install -y setroubleshoot-server policycoreutils-python-utils

# 查看最近的 AVC 拒绝记录
ausearch -m avc -ts recent

# 使用 sealert 分析(提供可操作的修复建议)
sealert -a /var/log/audit/audit.log

# 实时监控 AVC 事件
ausearch -m avc -ts recent -i | tail -20

12.2.3 修正文件 SELinux 上下文

# 查看文件的 SELinux 上下文
ls -lZ /etc/ssh/sshd_config
ls -lZ /var/www/html/

# 恢复文件到默认上下文(最常用修复方式)
restorecon -Rv /var/www/html/
restorecon -v /etc/ssh/sshd_config

# 永久修改文件上下文(restorecon 不会覆盖 semanage 设置的上下文)
semanage fcontext -a -t httpd_sys_content_t "/opt/webapp(/.*)?"
restorecon -Rv /opt/webapp/

# 查看已自定义的文件上下文策略
semanage fcontext -l | grep local

12.2.4 管理 SELinux 布尔值

布尔值(Boolean)是 SELinux 策略中的开关,允许在不修改策略的情况下调整行为:

# 列出所有布尔值
getsebool -a

# 查看特定布尔值
getsebool httpd_can_network_connect
getsebool allow_ftpd_anon_write

# 临时开启布尔值(重启失效)
setsebool httpd_can_network_connect on

# 永久开启布尔值(-P 参数写入策略)
setsebool -P httpd_can_network_connect on

# 查看布尔值变更记录
semanage boolean -l | grep httpd_can_network_connect

12.2.5 添加 SELinux 端口上下文

# 查看已有的端口类型定义
semanage port -l | grep -E "ssh|http"

# 添加自定义端口(如已在第 5 章完成,此处为参考)
semanage port -a -t ssh_port_t -p tcp 2222

# 修改已有端口类型
semanage port -m -t http_port_t -p tcp 8080

# 删除自定义端口策略
semanage port -d -t ssh_port_t -p tcp 2222

12.3 自动安全更新

手动定期更新容易遗漏,配置自动安全更新确保关键补丁及时应用。

12.3.1 安装并配置 dnf-automatic

dnf install -y dnf-automatic

vim /etc/dnf/automatic.conf

推荐生产环境配置:

[commands]
# 仅下载安全更新,不自动安装(安全且可控)
upgrade_type = security
download_updates = yes
apply_updates = no           # 生产环境谨慎设为 yes,建议人工审查后手动应用

[emitters]
emit_via = stdio             # 可改为 email,配置邮件通知

[base]
# 排除内核自动更新(内核更新需重启,应人工控制)
exclude = kernel*

启用定时器:

# 启用每日自动检查(下载但不安装)
systemctl enable --now dnf-automatic-download.timer

# 查看定时器状态
systemctl list-timers | grep dnf

12.3.2 手动应用安全更新

# 查看可用的安全更新
dnf updateinfo list security

# 查看安全更新摘要
dnf updateinfo summary --security

# 仅安装安全更新
dnf update --security -y

# 查看已安装的安全更新
dnf updateinfo list security --installed

生产更新策略建议

生产环境推荐:dnf-automatic 仅配置下载download_updates = yesapply_updates = no),在维护窗口内人工执行 dnf update --security -y 应用,重启前先创建 VMware 快照。


12.4 账户安全加固

12.4.1 密码策略强化

在第 4 章基础上,进一步强化密码策略:

vim /etc/security/pwquality.conf

完整生产环境配置:

minlen         = 14    # 最短长度(STIG 要求 ≥ 15)
minclass       = 4     # 必须包含全部 4 类字符
difok          = 8     # 新旧密码至少有 8 个不同字符
maxrepeat      = 2     # 同一字符不超过连续 2 次
maxclassrepeat = 4     # 同类字符不超过连续 4 个
usercheck      = 1     # 不允许包含用户名
gecoscheck     = 1     # 不允许包含 GECOS 信息
dictcheck      = 1     # 字典检查

12.4.2 账户过期与锁定策略

# 为现有用户设置密码有效期
# -M 90:最长有效期 90 天;-m 1:最短使用期 1 天;-W 14:提前 14 天警告
chage -M 90 -m 1 -W 14 ops

# 查看账户策略
chage -l ops

# 锁定指定账户(如员工离职)
usermod -L <username>

# 设置全局默认:账户密码无活动 30 天后过期
useradd -D -f 30

12.4.3 禁用不必要的系统账户

# 列出所有可登录的系统账户(Shell 非 nologin 的)
grep -v '/sbin/nologin\|/bin/false' /etc/passwd

# 锁定不需要登录的系统账户
for user in games ftp lp mail; do
    usermod -s /sbin/nologin -L $user
done

12.4.4 配置登录失败锁定(PAM)

vim /etc/security/faillock.conf
# 失败 5 次后锁定账户
deny = 5
# 锁定持续时间(秒),600 = 10 分钟
unlock_time = 600
# 失败计数窗口时间(秒)
fail_interval = 900
# root 账户也受此策略约束
even_deny_root = true
# 查看某账户的失败记录
faillock --user ops

# 手动解锁账户
faillock --user ops --reset

12.5 auditd 审计配置

auditd 是 Linux 内核级别的审计框架,记录关键系统调用与事件,是等保合规的基本要求。

12.5.1 安装并启用 auditd

# RHEL 9 通常已预装
rpm -q audit || dnf install -y audit

systemctl enable --now auditd
systemctl status auditd

12.5.2 配置审计规则

# 查看当前审计规则
auditctl -l

# 查看审计配置
cat /etc/audit/auditd.conf

创建持久化审计规则文件(重启后生效):

tee /etc/audit/rules.d/linuxdc-audit.rules << 'EOF'
# 删除所有已有规则(清空开始)
-D

# 设置缓冲区大小
-b 8192

# 失败时的行为:0=静默,1=打印,2=内核 panic
-f 1

# 监控特权命令执行
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_commands
-a always,exit -F arch=b64 -S execve -F auid>=1000 -k user_commands

# 监控账户与权限文件变更
-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 sudoers
-w /etc/sudoers.d -p wa -k sudoers

# 监控 SSH 配置变更
-w /etc/ssh/sshd_config -p wa -k sshd_config

# 监控登录事件
-w /var/log/lastlog  -p wa -k login
-w /var/run/faillock -p wa -k login

# 监控网络配置变更
-w /etc/NetworkManager/system-connections -p wa -k network_config

# 监控 SELinux 配置变更
-w /etc/selinux -p wa -k selinux_config

# 使规则不可修改(生产环境启用,需重启才能更改)
# -e 2
EOF

加载规则:

augenrules --load

# 验证规则已加载
auditctl -l

12.5.3 查询审计日志

# 查看特定关键字(-k)的事件
ausearch -k identity -ts today
ausearch -k root_commands -ts recent

# 查看特定用户的操作
ausearch -ua ops -ts today

# 查看特定文件的访问记录
ausearch -f /etc/passwd

# 生成审计报告
aureport --summary
aureport --auth               # 认证事件报告
aureport --failed             # 失败事件报告

12.6 fail2ban 防暴力破解

fail2ban 监控日志文件,自动封禁达到失败阈值的 IP 地址。

12.6.1 安装 fail2ban

dnf install -y fail2ban

systemctl enable --now fail2ban

12.6.2 配置 SSH 防护

配置原则

不要直接修改 /etc/fail2ban/jail.conf(软件升级会覆盖),在 jail.d/ 下创建本地配置。

tee /etc/fail2ban/jail.d/sshd-linuxdc.local << 'EOF'
[sshd]
enabled   = true
port      = 2222
filter    = sshd
backend   = systemd
logpath   = /var/log/secure
maxretry  = 5
bantime   = 3600
findtime  = 600
banaction = firewallcmd-ipset
# 运维网段白名单,防止误封自身
ignoreip  = 127.0.0.1/8 192.168.1.0/24
EOF

参数说明:

参数 说明
port 2222 与 SSH 实际端口一致
maxretry 5 触发封禁的失败次数
bantime 3600 封禁持续时间(秒),3600 = 1 小时
findtime 600 统计失败次数的时间窗口(秒)
banaction firewallcmd-ipset 使用 firewalld ipset,性能优于直接操作 iptables
ignoreip 192.168.1.0/24 白名单网段,永不封禁
systemctl restart fail2ban

# 验证 SSH jail 状态
fail2ban-client status
fail2ban-client status sshd

检查点

fail2ban-client status sshd 输出中 Currently bannedTotal banned 显示数字(初始为 0 正常)。

12.6.3 手动管理封禁

# 查看被封禁的 IP
fail2ban-client status sshd

# 手动解封 IP(如误封自己)
fail2ban-client set sshd unbanip 192.168.1.50

# 手动封禁 IP
fail2ban-client set sshd banip 10.0.0.99

12.7 OpenSCAP 合规扫描

OpenSCAP 基于 SCAP 标准对系统进行合规性扫描,支持 CIS、STIG 等基线。

12.7.1 安装工具

dnf install -y openscap-scanner scap-security-guide

12.7.2 查看可用扫描配置

oscap info /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml | grep -A2 "Profile"

12.7.3 执行合规扫描

# 使用 STIG 配置扫描并生成 HTML 报告
oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_stig \
  --results /tmp/stig-results.xml \
  --report /tmp/stig-report.html \
  /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

通过 SecureFX 将 /tmp/stig-report.html 下载至本地,用浏览器查看详细结果。


12.8 常见问题与排查

问题现象 排查步骤
SELinux 拒绝访问 ausearch -m avc -ts recentsealert -a /var/log/audit/audit.log 获取修复建议
dnf-automatic 未执行 systemctl status dnf-automatic-download.timer;检查 /var/log/dnf.log
fail2ban 误封己方 IP fail2ban-client set sshd unbanip <IP>;确认 ignoreip 已包含运维网段
auditd 日志磁盘占满 调整 /etc/audit/auditd.confmax_log_file_action = rotatenum_logs = 5
# 查看 fail2ban 日志
journalctl -u fail2ban -f

# 测试 auditd 规则是否生效
touch /etc/passwd
ausearch -k identity -ts recent

12.9 实践任务

  1. 确认 SELinux 处于 Enforcing 模式:getenforce
  2. 安装 setroubleshoot-server,执行 sestatus 查看详细状态。
  3. 配置 dnf-automatic,设置仅下载安全更新,启用定时器,验证:

    systemctl list-timers | grep dnf
    
  4. 按照 12.4.2 节为 ops 账户设置 90 天密码策略并验证:

    chage -M 90 -W 14 ops
    chage -l ops
    
  5. 创建 /etc/audit/rules.d/linuxdc-audit.rules,加载规则,验证:

    augenrules --load
    auditctl -l
    
  6. 安装并配置 fail2ban,验证 SSH jail 已启用:

    fail2ban-client status sshd
    

12.10 自测问题

Q1:SELinux 拒绝了某个服务的操作,应该如何正确处理而不是关闭 SELinux?

正确流程:① ausearch -m avc -ts recent 找到具体的 AVC 拒绝记录;② sealert -a /var/log/audit/audit.log 获取分析报告和修复建议;③ 根据建议选择 restorecon(修复文件上下文)、semanage fcontext(自定义文件上下文)、setsebool -P(开启布尔值)或 semanage port(添加端口)等方式精准修复。

Q2:auditctl -l/etc/audit/rules.d/ 的关系是什么?

auditctl -l 显示当前内核内存中已加载的审计规则(实时生效);/etc/audit/rules.d/ 中的文件是持久化配置,通过 augenrules --load 编译并加载到内核。系统重启后,auditd 自动从 rules.d 加载规则。

Q3:fail2ban 误封了运维人员的 IP,如何恢复并防止再次发生?

立即执行 fail2ban-client set sshd unbanip <IP> 解封。预防:在 fail2ban 配置的 [sshd] 节中添加 ignoreip = 127.0.0.1/8 192.168.1.0/24,将运维网段加入白名单。本教程已在 12.6.2 节的配置文件中预置此项。


12.11 章节总结

本章完成了 RHEL 9 的系统安全加固:SELinux 日常管理(布尔值、端口、文件上下文)、自动安全更新(dnf-automatic)、账户密码与锁定策略、auditd 内核级审计、fail2ban 暴力破解防护(含运维白名单),以及 OpenSCAP 合规扫描。这些措施共同构建了系统的安全基线,是满足等保合规要求的核心内容。