1. 先从一次安全评分不达标聊起
年初帮某公司做例行服务器排查,几十台 CentOS 7 跑着 Nginx、Java 应用和内部数据库,厂商控制台里的安全基线报告打开一看,一片红色不合格项。说实话,真被实打实攻击打穿的几乎没有,但云平台基线检查就是把这些“平时没人管”的问题全摆到了台面上:SSH 还开着密码登录、root 还能直接远程连、/etc/shadow 权限太宽、系统里躺着好几个长期不用的历史账户。每一条单独看好像都不致命,但组合起来就是一台“裸奔”的服务器。
后来我按十五项标准配置逐台整改,花了一周多时间把所有机器拉到合格线。这篇文章就是把当时整套做法整理出来,适合正在做云安全基线检查整改、维护 CentOS 7 存量服务器的运维和网安同学参考。文中的命令我都按实际可复现的方式写,同时也把容易踩的坑和为什么这样做的逻辑讲清楚,不是让你机械执行,而是改完知道自己在防什么。
我建议先通读清单,再按章节逐项落地,最后用第八节的顺序和回滚方案收尾。如果你手里已经有整改单,也可以跳过清单直接看对应项。
2. 十五项加固清单全景:先看应做项,再谈细节
安全基线检查听起来很玄,实际拆开就是十五个固定动作。我在实际梳理时把它们分成五层:账号层、SSH 通道层、网络层、文件层、审计层。为了便于对照整改单,先给一张总表,后续章节再逐层展开。
这里需要说明一点:不同厂商的基线检查工具给出的名称会有差异,有的叫“口令策略”,有的叫“密码复杂度和有效期”,但核心指标一样。你只需要理解每项实际上是检查什么,就不用担心换一个平台就不认识了。
| 编号 | 加固项 | 为什么检查 | 涉及层级 |
|---|---|---|---|
| 1 | 密码复杂度与有效期 | 弱密码是爆破和内网横向移动的第一入口 | 账号 |
| 2 | 登录失败锁定 | 限制离线与在线暴力破解的频率 | 账号 |
| 3 | 空密码账户排查 | 空口令等于免密登录,风险极高 | 账号 |
| 4 | 清理过期离职与无效账户 | 幽灵账户可能残留 sudo、cron 等隐藏入口 | 账号 |
| 5 | su 权限白名单 | 限制普通用户提权通道,收紧 wheel 组 | 账号 |
| 6 | SSH 修改默认端口 | 降低全网自动化扫描和爆破命中率 | SSH |
| 7 | 禁用 root 远程登录 | 避免 root 密码泄露后被直接拿到最高权限 | SSH |
| 8 | 密钥登录并禁用密码 | 密钥比密码更难被暴力破解,且可单独吊销 | SSH |
| 9 | SSH 用户白名单与空闲超时 | 最小化可登录账号,缩短无效连接窗口 | SSH |
| 10 | 防火墙最小化开放端口 | 减少暴露面,让不可见服务不被访问 | 网络 |
| 11 | 内核网络参数加固 | 缓解扫描、ICMP 探测和部分 SYN 型攻击 | 网络 |
| 12 | 关键文件权限收紧 | 避免普通用户读取密码哈希或篡改系统配置 | 文件 |
| 13 | 全局 umask 与终端超时 | 控制新建文件默认权限,防止闲置终端被利用 | 文件 |
| 14 | 关闭不必要的系统服务 | 减少系统资源占用和潜在未知漏洞入口 | 服务 |
| 15 | 审计、日志、时间同步 | 让异常登录和文件变更可追溯,保证日志可信 | 审计 |
不要被“十五项”这个数字吓到,里面真正复杂的其实只有 SSH、防火墙、审计这三块。账号和文件权限主要是熟悉几个命令的事。还有项间依赖关系很重要:比如第 8 项的密钥登录必须排在第 7 项 root 禁止登录之前做,不然自己会被锁在门外。第八节会专门讲顺序。
我个人的处理顺序是:先备份,再做 SSH 和账号,再做网络,再做文件,最后做审计。之所以把 SSH 放前面,是因为如果远程加固过程中不小心断了连接,后面所有步骤都得通过救援通道完成,会很痛苦。
3. 账号与登录防线:口令、锁定、无效账户这三类最容易被忽略
3.1 密码复杂度与有效期设置,不是越大越好
密码策略是所有基线检查里必出的一项。CentOS 7 默认的密码策略其实很弱,只限制最少 5 位,很多机器跑了几年的业务密码还是 123456 或者主机名。整改动作分两层:第一层是密码复杂度,第二层是密码有效期。
复杂度靠 PAM 的 pwquality 模块实现:
yum install -y libpwquality vim /etc/security/pwquality.conf核心参数我一般按内网普通服务器过渡标准来设:
minlen = 12 dcredit = -1 ucredit = -1 lcredit = -1 ocredit = -1 minclass = 3 retry = 3minlen 是密码最小长度,dcredit、ucredit、lcredit、ocredit 分别是数字、大写、小写、特殊字符的最少数目,负号表示“至少要有”。这样组合的意思是:密码不得少于 12 位,并且至少包含数字、大写、小写、特殊字符中的三类。
有效期改在 /etc/login.defs 里:
PASS_MAX_DAYS 90 PASS_MIN_DAYS 7 PASS_MIN_LEN 12 PASS_WARN_AGE 7PASS_MIN_DAYS 设 7 是防止用户改密后立刻又改回原密码,同时也是给系统一个合理缓冲。要注意这个配置只影响之后创建或修改的账户,存量用户密码到期时间不会自动更新,需要结合 chage 命令处理:
chage -M 90 -m 7 -W 7 用户名3.2 登录失败锁定,重点是不把 PAM 配置改坏
暴力破解是云服务器最日常的噪声,基线检查里常见的要求是“连续失败 5 次锁定 15 分钟以上”。CentOS 7 常见实现是 pam_faillock,配置位置在 /etc/pam.d/system-auth 和 /etc/pam.d/password-auth。手改 PAM 文件容易出错,建议用系统自带的 authconfig 工具:
authconfig --enablefaillock --faillockdeny=5 --faillockunlocktime=900 --update这样会把认证相关配置统一写进去。改完可以查看 /etc/pam.d/system-auth,确认 pam_faillock.so 出现在 auth 段和 account 段:
grep faillock /etc/pam.d/system-auth这里有一个非常典型的坑:不要在 pam_faillock 配置里单纯叠加 pam_tally2,两个模块同时启用会导致失败次数被双倍计数,实际尝试 3 次就可能被锁。很多报表上的“锁定策略已启用”不代表正确启用,它可能恰恰是被锁定次数记录异常的那一台。
另外,不要忘了 SSH 服务本身也有 MaxAuthTries 限制,见后文 SSH 章节。两条机制可以互补,但一个在 PAM 层,一个在 SSH 层,不能互相替代。
3.3 空密码、UID 0 账户和历史幽灵账户的排查方法
这一项真正的问题是很多机器根本不知道系统里有哪些弱账户。我一般按三个方向排查:
# 找出所有密码为空的账户,正常应为空结果 awk -F: '($2 == "") {print $1}' /etc/shadow # 找出所有 UID 0 的账户,正常应该只有 root awk -F: '($3 == 0) {print $1}' /etc/passwd # 列出可以登录 shell 的账户 awk -F: '($7 != "/sbin/nologin" && $7 != "/bin/false") {print $1, $7}' /etc/passwd对第一、二条,只要出现结果就是大问题,立即锁定或删除。第三条会看到一堆系统账户,需要人工判断。整改时用到的命令:
# 锁定账户而不删除,适合不确定是否还被业务依赖的场景 usermod -L 用户名 # 确认废弃后删除,-r 会同时删除主目录和邮件池 userdel -r 用户名有人喜欢直接 userdel -r 把所有看起来没用的账户全删掉,这是高风险操作。我遇到过一台机器的 zabbix 监控账户没在 passwd 里被识别为登录账户,但它承担了定时采集任务,删掉后监控立刻断档。稳妥做法是先锁定,观察两个完整业务周期,确认日志里没有再出现该账户相关报错,再删除。
空密码和 UID 0 账户是必须当场处理的,不能观察。因为空密码账户开机都会出现在登录列表里,UID 0 账户等于第二个 root,业务系统几乎不可能合法使用这两类账户。
3.4 su 权限白名单,限制提权通道
很多服务器的现状是 root 密码稍微守不住,整个系统就沦陷,原因是所有能登录的普通用户都有 su 到 root 的能力。基线检查对这一项的期望通常是:只有明确授权的管理员账户可以执行 su。
默认 CentOS 7 已经支持 wheel 组,但需要把 /etc/pam.d/su 里的配置打开:
vim /etc/pam.d/su把这一行取消注释:
auth required pam_wheel.so use_uid然后再把运维人工账号加进 wheel 组:
usermod -aG wheel 用户名这样普通用户执行 su 时会收到“密码正确但账户未授权”的拒绝信息。如果你有更精细的按组授权需求,可以在 /etc/sudoers 里配置:
%ops ALL=(ALL) ALL不要小看这一项,它和 root 远程登录禁用是成对出现的。单禁 root 远程登录但允许任意用户 su,等于攻击者只要拿下一个普通账号,就很容易横向提权。
4. SSH 运维通道加固:端口、密钥、用户白名单,缺一不可
4.1 修改默认端口前,先想清楚影响范围
把 SSH 从 22 改成高端口不是万能的,但确实能显著减少全网扫描量。攻击者对 22 端口的爆破是持续不断的,换成 22022、2022 这类非默认端口,自动扫描脚本大概率不会命中。我习惯选 22022-22999 之间的端口,避开被服务占用的常见段,同时还要记住“防火墙要放行的是新端口,而不是老 22”。
修改在 /etc/ssh/sshd_config:
Port 22022 ListenAddress 0.0.0.0有的机器上可能同时绑定了 IPv6,如果业务只用 IPv4,把 ListenAddress 单独写更严谨。改端口前一定先跑一句:
sshd -t这条检查语法不过关,不要重启 sshd,否则当前会话也可能受影响。确认正常后:
systemctl reload sshd4.2 禁止 root 远程登录,但要保留本地运维手段
PermitRootLogin no 是云基线必查项。原因是 root 这个账户名是公开的,攻击者不需要猜测用户名,直接对固定名字做密码爆破即可。禁止 root 远程登录后,运维先用普通账户登录,再 su 或 sudo 提权,攻击成本会明显提高。
PermitRootLogin no这里必须提醒一下:仅关闭 root 远程登录,不意味着 root 不能通过控制台登录。如果云厂商的 VNC/管理终端走的是虚拟控制台,那这条配置不影响物理机/虚拟机的本地登录。所以团队里要约定好:本地控制台留给紧急救援,日常远程一律走普通用户 + sudo。
4.3 密钥登录并禁用密码,注意权限不是摆设
密钥登录有两种思路,一种是用户自己生成密钥对并把公钥放到服务器上,另一种是由运维统一生成并分发私钥。我更推荐前者,因为私钥应该只存在于个人设备,不经过网络传输。生成密钥的命令:
ssh-keygen -t ed25519 -C "备注信息" -f ~/.ssh/id_ed25519ED25519 密钥短、性能好,比 RSA 更现代。如果为了兼容老旧设备而必须用 RSA,建议位数不低于 3072。拿到公钥后上传到服务器:
mkdir -p ~/.ssh chmod 700 ~/.ssh echo "公钥内容" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys restorecon -R ~/.ssh之后在 sshd_config 关闭密码认证:
PubkeyAuthentication yes PasswordAuthentication no ChallengeResponseAuthentication no UsePAM yes这里的顺序必须注意:没有密钥能正常登录前,不要执行 systemctl reload sshd。建议在两个不同终端分别用密钥登录成功,再关闭密码认证。同时保证至少一把备用密钥存在本地或密码管理器里,否则一旦私钥丢失就是灾难性的事故。
4.4 SSH 用户白名单与空闲超时,把连接数也管起来
AllowUsers 是最直观的“最小暴露”配置。你可以在 sshd_config 里限定允许登录的用户:
AllowUsers ops deploy没有在这个列表里的用户,即使密码正确也无法登录。如果你的机器用户特别多,建议用 AllowGroups 按组管理,避免每加一个临时用户都改一次 sshd_config。
空闲超时也是基线会检查的项。默认 SSH 连接可以挂一天不动作,这个连接如果被复用,会在运维不在场时留下风险窗口。设置如下:
ClientAliveInterval 300 ClientAliveCountMax 0意思是每 300 秒发一次心跳,连续 0 次未响应就断开。ClientAliveCountMax 设为 0 最严格,客户端只要失去响应就断开。但要注意,如果你经常用 tmux 或 screen 做长任务,这个配置可能在你离线后杀掉会话里的任务,需要和团队提前沟通。
5. 网络层与内核参数:防火墙和 sysctl 才是防扫描的关键
5.1 firewalld 最小化开放,别只惦记加端口
CentOS 7 默认用的是 firewalld,很多机器常年处于 disabled 状态,安全基线当然会给 Liable 不合格。启用并设置默认区域:
systemctl enable --now firewalld firewall-cmd --set-default-zone=public然后通过一条条命令把端口“白名单化”:
firewall-cmd --permanent --zone=public --remove-service=ssh firewall-cmd --permanent --zone=public --add-port=22022/tcp firewall-cmd --permanent --zone=public --add-port=80/tcp firewall-cmd --permanent --zone=public --add-port=443/tcp firewall-cmd --reload为什么防火墙配置要带 --permanent?因为不带的话只对当前运行时生效,reload 就没了。我见过不少运维在开发环境里手动加了端口但忘记持久化,重启后服务失联,查了半天才发现是防火墙规则丢了。
数据库端口如 3306、6379 不应暴露到公网,必须用 rich rule 限定来源网段:
firewall-cmd --permanent --zone=public --add-rich-rule='rule family=ipv4 source address=10.0.0.0/8 port protocol=tcp port=3306 accept' firewall-cmd --reload做完后用 firewall-cmd --list-all 核对,确认没有多余的允许项。最小化开放的原则是:只开放业务和管理必须的端口,其余一律默认拒绝。
5.2 sysctl 内核参数,为什么这些数字能防攻击
网络层不只是防火墙,sysctl 才是很多自动化扫描无效的底层原因。我按基线要求整理了一份常见配置,写入 /etc/sysctl.d/99-security.conf:
# 禁止 ICMP 回显,降低主机探测成功率 net.ipv4.icmp_echo_ignore_all = 1 # 禁止转发,防止服务器被当跳板 net.ipv4.ip_forward = 0 # 开启 SYN Cookie,缓解 SYN Flood net.ipv4.tcp_syncookies = 1 # 忽略伪造的 ICMP 差错报文 net.ipv4.icmp_ignore_bogus_error_responses = 1 # 关闭 ICMP 重定向 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 # 关闭源路由 net.ipv4.conf.all.accept_source_route = 0 # 限制反向路径过滤 net.ipv4.conf.all.rp_filter = 1生效:
sysctl -p /etc/sysctl.d/99-security.conf这里我重点解释两个容易理解偏差的参数。icmp_echo_ignore_all 设为 1 表示服务器不响应 ping,但它不限制对外主动 ping,也不影响 TCP 业务连接。运维团队普遍用 ping 做在线检测,这条配置可能会让监控系统误判主机离线,所以在生产环境落地前,最好先把监控侧改成走端口探测或与运维确认告警阈值。
tcp_syncookies 是应对 SYN Flood 的经典手段。当半连接队列被攻击打满时,内核通过 SYN Cookie 机制不占用队列就能验证连接合法性。它不是彻底解决方案,但作为服务器自身的第一道缓冲很有效。开启后通常在性能上感知不到影响,除非你这台机器本身就承担着超高并发的连接处理任务,那需要另行评估。
6. 文件权限与启动链路:守住最后一道物理与引导安全
6.1 关键配置文件的权限,差一档就是密码哈希泄露
基线检查里“关键文件权限”一项,通常看 /etc/passwd、/etc/shadow、/etc/group、/etc/gshadow 和 grub 配置。常见整改结果:
chown root:root /etc/passwd /etc/shadow /etc/group /etc/gshadow chmod 644 /etc/passwd chmod 600 /etc/shadow chmod 644 /etc/group chmod 600 /etc/gshadow这个组合的意图很明确:/etc/passwd 是任何人都要读的公共用户信息,保持 644;shadow 里保存的是密码哈希,只允许 root 读;gshadow 同理。很多 CentOS 默认文件权限本身没问题,问题在于历史操作中有人 chmod 777 过,或者某个程序安装包把 shadow 权限改宽了。改完权限后,用 ls -l /etc/shadow 确认输出必须是“root root 且其他用户不可读写”。
值得单独提一下:/etc/openldap 下或某些自定义应用的密码文件,如果存在,也应按同级别保护。基线工具未必查得到,但思路要一致。
6.2 grub 引导密码与单用户模式,别给物理接触的人留后门
这个问题在虚拟机环境容易被忽略,但物理机或可控硬件维保的同仁一定要做。攻击者只要能够接触服务器终端,重启机器进入单用户模式,就能在不输入 root 密码的情况下重置密码。补救措施是给 GRUB 设置密码。
CentOS 7 提供了相对简单的命令:
grub2-setpassword按提示输入两遍密码,它会生成 /boot/grub2/user.cfg 和更新相关配置。需要注意:这个命令并不会让你在每次启动时都要输密码,而是修改 GRUB 菜单需要认证。如果想让“进入 GRUB 编辑界面”也需要密码,还需要在 /etc/grub.d/00_header 等文件里做进一步配置,生产环境建议按团队的恢复预案来定,不要因为加了密码导致无人能进入救援模式。
给一个实用提醒:做完 grub2-setpassword 后,重启前先确认你手里有控制台访问能力。一旦 GRUB 密码配置出错,远程是无法直接修复的,只能靠虚拟控制台或带外管理。
6.3 全局 umask 与 TMOUT,细节里的默认安全基线
umask 控制新建文件的默认权限。CentOS 7 默认是 022,也就是新建文件 644、新建目录 755,这对外公开的服务文件是合适的,但对内部服务器建议收紧到 027,让同组用户无法读取新建文件:
在 /etc/profile 和 /etc/bashrc 中:
umask 027 export TMOUT=600TMOUT=600 表示用户登录 shell 后 10 分钟没有操作会自动注销。这个配置对多人共用的堡垒机效果很好,但对常驻后台任务的开发机会有影响:有些人挂着 nohup 任务的窗口被踢掉不会中断任务,但 tmux 会话可能会受影响,落地前务必要和开发团队提前打好招呼。
我在实际过程中还见过一种常见误解:认为设置了 /etc/profile 里的 umask,所有用户新建文件的权限就一定受控。其实这只对登录 shell 生效。cron、rsync、某些服务进程的 umask 不一定继承这个值。真正重要的服务,最好在服务配置里单独指定。
6.4 关闭不必要的系统服务,重点先看 enabled
服务加固里我不建议把所有“看起来没用”的服务全部禁用,因为有些人会误把 ntp、dbus、tuned 这类基础服务一起关掉。正确方法是先看开机自启服务列表:
systemctl list-unit-files --type=service --state=enabled从中识别出明显用不到的服务,比如不出外网邮件就不需要 postfix,纯内网服务器可以禁用 avahi-daemon、cups、bluetooth 等。操作命令:
systemctl disable --now postfix systemctl mask avahi-daemondisable 是停止并取消开机自启,mask 是彻底屏蔽,连手动启动都禁止。mask 比 disable 更严格,但也更容易误伤。初次整改用 disable 就够了,确认业务无影响后再决定是否 mask。
还可以顺手加一条 USB 存储限制。服务器物理端口插 U 盘是数据泄露通道,同时也可能携带恶意程序。写入 /etc/modprobe.d/usb-storage.conf:
install usb-storage /bin/true这条配置会让加载 usb-storage 模块的请求被替换为 true,相当于模块永远加载不上。对需要连接 USB 存储的物理机不适用;虚拟机上基本没有影响,可以放心加。
7. 审计、日志和时间同步:让危险可追踪、让取证有据
7.1 auditd 规则,别把所有命令执行都审计
打开审计服务:
systemctl enable --now auditdauditd 本身在 CentOS 7 默认是启用的,但默认规则很弱。基线检查一般会要求至少审计身份变化和文件访问。常见持久化规则写进 /etc/audit/rules.d/audit.rules:
-w /etc/passwd -p wa -k passwd_changes -w /etc/shadow -p wa -k shadow_changes -w /etc/sudoers -p wa -k sudoers_changes -w /var/log/secure -p wa -k security_log然后重启 auditd 或者用 auditctl -R 加载:
service auditd restart这里有个性能坑:有些加固指南会让你加“监控所有 execve”,这在低频服务器上问题不大,但在高并发应用服务器上会产生海量日志,直接拖慢系统。我建议只对关键命令和关键目录做审计,不要贪多。真实性可靠的日志比什么都记最后没人看更有价值。
查日志的命令:
ausearch -k passwd_changes -ts recent如果哪天想知道谁该为某次权限变更负责,这条命令就能拉出时间线和操作账号。
7.2 rsyslog 与 logrotate,审计日志先有地方放
rsyslog 在 CentOS 7 默认就起着收集系统日志的作用,但很多服务器会把它停掉。启用并确认开机自启:
systemctl enable --now rsyslog如果日志轮转策略缺失,/var/log/secure 会无限制长大。CentOS 7 的 /etc/logrotate.d/syslog 默认已经有了,但建议确认里面包含 secure、messages、maillog:
cat /etc/logrotate.d/syslog轮转周期可以根据日志量调整,常见是 weekly 加 rotate 4。日志保留多久取决于你的磁盘空间和业务要求,但最短也不要低于 4 周,否则可能连问题发生的现场都找不到。
7.3 时间同步必须做,不然日志串联不上
日志节奏如果依靠服务器本地时间,一旦时钟漂移,发生安全事件时无法把多台机器日志按时间顺序串起来。CentOS 7 推荐用 chrony:
yum install -y chrony systemctl enable --now chronyd chronyc sources -v验证输出里能看到^*表示已同步。如果显示^?,说明还没有建立同步,需要检查网络或配置上游时间源。厂商云服务器通常内网就有 NTP 源,如你用的是本地物理机,则把 /etc/chrony.conf 里的 server 指向可用源即可。
8. 落地顺序与回滚预案:加固绝不能把自己关在门外
8.1 先备份,再分阶段操作
我最开始做加固时也只想“快速执行完”,但实际操作中远程服务器一旦 SSH 配置写错、防火墙规则没放行新端口,就面临失联风险。后来我养成一个固定习惯:操作前统一建备份目录,把每个要改的文件先原样复制一份。
mkdir -p /root/hardening_backup/$(date +%F) cp -p /etc/ssh/sshd_config /root/hardening_backup/$(date +%F)/ cp -p /etc/pam.d/system-auth /root/hardening_backup/$(date +%F)/ cp -p /etc/sysctl.conf /root/hardening_backup/$(date +%F)/备份文件名里带日期,避免后续多次整改时互相覆盖。
实际执行顺序建议固定为下面四步,每一阶段之间都做一次连通性验证:
- 先处理账号策略和密钥登录,测试新端口登录成功,再关闭密码认证;
- 再改防火墙最小化策略,先放行新端口,再 reload;
- 再做网络内核参数、文件权限和服务关闭这类“不会断连接”的项目;
- 最后开审计和时间同步。
这样做的核心逻辑是把“可能导致失联”的操作集中在前面可控阶段。万一断了,后面再处理别的也不会扩大风险。
8.2 远程加固失败后的应急恢复思路
再谨慎也可能出问题,典型场景是:SSH 端口改了、防火墙只放行新端口但忘记加 permanent、reload 后服务重启,当前会话被防火墙规则切断了。这时远程 SSH 已经回不去,只能用云厂商控制台里的 VNC/管理终端登录,登录后立刻回滚:
# 恢复 sshd 配置 cp /root/hardening_backup/$(date +%F)/sshd_config /etc/ssh/sshd_config chmod 600 /etc/ssh/sshd_config systemctl restart sshd # 恢复防火墙规则 systemctl stop firewalld如果你连控制台都没有,那就只能靠带外管理或现场介入。这也是为什么我一直强调:任何改动前,必须确保手上有一条不依赖 SSH 的救援通道。很多公司给云服务器配置了终端管理,这是最后一条保命通道,一定要在加固前测试能用。
8.3 验证结果不能只靠肉眼看
逐项改完后,建议跑一遍综合检查:
# SSH 语法与运行状态 sshd -t && systemctl status sshd # 防火墙规则核对 firewall-cmd --list-all # 端口监听确认 ss -lntup | grep -E '22022|80|443' # 关键文件权限 ls -l /etc/shadow /etc/gshadow /etc/passwd # 当前 SSH 审计目录里的无效用户数 awk -F: '($2 == "") {print $1}' /etc/shadow # 审计状态 systemctl is-enabled auditd rsyslog chronyd firewalld如果其中有任何一项与你预期不符,不要急着交付,先回到该项目的章节重新排查。安全基线报表会自动重新扫描,但建议你在扫描前自己先过一遍,省得等报告出来又返工。
9. 我做了几年基线整改后的几点体会
说几条纯粹的体感,不一定写在任何手册里,但很影响长期效果。
第一,安全加固不是一次性工程。报表合格只是某个时间点的合格,三个月后新装的软件、新加的人工账号、新打开的防火墙端口都有可能让状态回落。比较好的做法是把这些配置纳入初始化模板或自动化脚本,新服务器一创建就自带基线,并及时安排周期巡检。
第二,不要盲目追求每一项都满足最严格值。比如 icmp_echo_ignore_all 如果影响了监控,就和监控团队确认后改成针对告警系统的白名单放行,这比一刀切禁 ping 更合理。TMOUT 如果导致开发人员频繁被踢,可以适当放宽到 1200 或 3600,但一定要有超时机制,不能完全没有。
第三,能自动化就不要手工。我最后洗一次整改时,把所有命令整理成了可重复执行的脚本,按顺序执行,并在每段后输出检查结果。除非你管理的机器只有几台,否则手工维护十五项在几百台服务器场景下是坚持不住的,也最容易漏项。
第四,改动记录是安全体系里容易被低估的一块。哪怕只有一条简单的时间戳注释,在问题回溯时的价值也远超你当时敲命令的时间。我是用统一的注释格式,写明“改了什么、为什么、使用人”,再配合审计日志,基本能还原每一次关键操作。
如果你正面对一台或一百台 CentOS 7 的报表,按照这十五项从头到尾走一遍,短期内拿到合格结果并不难。难的是下一轮巡检还能保持住,以及出了事件后真的能从日志里讲清楚发生了什么。把基础打牢,后面无论换什么检查工具都不会虚。