TL;DR
本教程系统讲解 CentOS 7 云服务器的安全运维与应急响应方法。安全运维层面涵盖账户权限管理、SSH 加固、防火墙配置、系统补丁更新、日志监控与入侵检测等核心措施;应急响应层面则给出从事件发现、隔离止损、取证溯源到清除后门、恢复业务的完整处置流程,并针对挖矿、勒索、Web 入侵等常见安全事件提供实战处置方案。文章还提供了安全巡检脚本与 Ansible 批量加固示例,帮助读者将安全方案落地为日常制度。
目录
- 1. 引言
- 2. 安全运维基础:账户与权限管理
- 3. SSH 安全加固
- 4. 防火墙与网络安全配置
- 5. 系统更新与漏洞管理
- 6. 日志监控与入侵检测
- 7. 安全应急响应流程
- 8. 常见安全事件处置实战
- 9. 安全运维自动化
- 10. 总结与最佳实践清单
1. 引言
随着云计算技术的普及,越来越多的企业和个人将业务部署在云服务器上。CentOS 7 作为一款稳定、开源且社区活跃的 Linux 发行版,是众多云服务器的主流操作系统选择。然而,云服务器暴露在公网环境中,面临着暴力破解、漏洞利用、恶意扫描、数据泄露等各类安全威胁。安全运维与应急响应能力,已成为每一位云服务器管理员必须掌握的技能。
本教程将从安全运维与应急响应两个维度出发,系统讲解 CentOS 7 云服务器的安全加固方法、日常监控手段,以及安全事件发生后的应急处置流程。内容涵盖账户安全、SSH 加固、防火墙配置、入侵检测、日志分析、病毒查杀、应急响应流程等核心主题,力求为读者提供一套可落地、可执行的完整安全方案。
2. 安全运维基础:账户与权限管理
账户与权限管理是服务器安全的第一道防线。攻击者入侵服务器后,往往会创建后门账户、修改权限配置,以维持持久化访问。因此,做好账户与权限的日常管理至关重要。
2.1 用户账户安全基线
首先,检查系统中是否存在异常账户:
# 查看所有本地用户
cat /etc/passwd
# 查看具有登录 Shell 的用户
awk -F: '$7 ~ /(bash|sh)$/ {print $1}' /etc/passwd
# 查看 UID 为 0 的超级用户(正常应只有 root)
awk -F: '$3 == 0 {print $1}' /etc/passwd
安全基线要求:
- 除 root 外,不应存在其他 UID 为 0 的账户;
- 禁用不必要的系统账户登录 Shell;
- 定期清理长期不用的僵尸账户;
- 为每个管理员分配独立账户,避免共享 root 密码。
2.2 密码策略与账户锁定
通过修改 /etc/login.defs 和 /etc/security/pwquality.conf 强化密码策略:
# /etc/login.defs 关键配置
PASS_MAX_DAYS 90
PASS_MIN_DAYS 7
PASS_MIN_LEN 12
PASS_WARN_AGE 7
启用密码复杂度校验:
yum install -y libpwquality
编辑 /etc/security/pwquality.conf:
minlen = 12
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
配置账户登录失败锁定策略,编辑 /etc/pam.d/password-auth 和 /etc/pam.d/system-auth,添加:
auth required pam_tally2.so deny=5 unlock_time=600 even_deny_root root_unlock_time=600
account required pam_tally2.so
上述配置表示连续失败 5 次锁定账户 10 分钟。
2.3 sudo 权限最小化
为管理员配置最小化 sudo 权限,避免直接使用 root 操作:
# 创建管理员组
groupadd admin
# 将用户加入管理员组
usermod -aG admin username
# 编辑 sudoers 文件
visudo
在 sudoers 中添加:
%admin ALL=(ALL) ALL
同时建议禁用 root 直接 SSH 登录(见下一节),强制管理员通过普通用户 + sudo 方式操作,既便于审计,又能降低风险。
3. SSH 安全加固
SSH 是云服务器最常用的远程管理通道,也是被暴力破解攻击最频繁的服务。SSH 加固是安全运维的重中之重。
3.1 修改默认端口与禁用 root 登录
编辑 /etc/ssh/sshd_config:
# 修改默认端口,避开 22 端口的批量扫描
Port 2222
# 禁止 root 直接登录
PermitRootLogin no
# 限制允许登录的用户
AllowUsers adminuser
# 使用密钥认证,禁用密码认证
PubkeyAuthentication yes
PasswordAuthentication no
# 空闲超时断开
ClientAliveInterval 300
ClientAliveCountMax 2
修改后重启服务:
systemctl restart sshd
注意:修改端口前务必先在云平台安全组放行新端口,并确认防火墙规则,避免把自己锁在门外。
3.2 配置密钥登录
在本地生成密钥对:
ssh-keygen -t ed25519 -C "your_email@example.com"
将公钥上传至服务器:
ssh-copy-id -p 2222 adminuser@server_ip
或手动将公钥追加到 ~/.ssh/authorized_keys,并设置正确权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
3.3 安装 Fail2ban 防暴力破解
Fail2ban 能自动检测并封禁频繁尝试登录的 IP:
yum install -y epel-release
yum install -y fail2ban
创建 /etc/fail2ban/jail.local:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
[sshd]
enabled = true
port = 2222
logpath = /var/log/secure
maxretry = 5
启动并设置开机自启:
systemctl start fail2ban
systemctl enable fail2ban
4. 防火墙与网络安全配置
4.1 firewalld 基础配置
CentOS 7 默认使用 firewalld 作为防火墙管理工具:
# 启动并设置开机自启
systemctl start firewalld
systemctl enable firewalld
# 查看当前区域与规则
firewall-cmd --list-all
# 仅放行必要端口
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload
4.2 限制来源 IP
对于管理端口,建议仅允许办公网 IP 访问:
# 仅允许特定 IP 访问 SSH 端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10" port port="2222" protocol="tcp" accept'
firewall-cmd --reload
4.3 使用云平台安全组
云平台安全组是服务器的第一层网络防线,应遵循最小开放原则:
- 仅开放业务必需端口;
- 管理端口(SSH、数据库等)限制来源 IP;
- 定期审查安全组规则,清理无效规则;
- 避免使用 0.0.0.0/0 全开放策略。
下面分别介绍阿里云与腾讯云安全组控制台的配置步骤,读者可对照截图占位说明在控制台完成操作。
阿里云安全组配置步骤
- 登录阿里云控制台,进入「云服务器 ECS」→「网络与安全」→「安全组」;
- 选择目标实例所在的地域,找到并点击实例绑定的安全组 ID;
- 点击「入方向」→「手动添加」或「快速添加」规则;
- 按需填写协议类型、端口范围、授权对象(来源 IP)与策略;
- 点击「保存」后,规则即时生效,无需重启实例。
截图占位:此处可插入「阿里云安全组入方向规则配置界面」截图,重点标注「协议类型」「端口范围」「授权对象」「策略」四个字段的位置。
腾讯云安全组配置步骤
- 登录腾讯云控制台,进入「云服务器 CVM」→「安全组」;
- 在安全组列表中找到目标安全组,点击「入站规则」→「添加规则」;
- 选择类型(如自定义)、来源(IP 或 CIDR)、协议端口与策略;
- 点击「完成」保存规则,并确认该安全组已关联到目标实例;
- 如需修改,可随时在「入站规则」/「出站规则」中编辑或删除。
截图占位:此处可插入「腾讯云安全组入站规则配置界面」截图,重点标注「来源」「协议端口」「策略」三个字段的位置。
安全组规则示例
以下是一组典型的安全组入方向规则示例,遵循「最小开放」原则:
| 协议 | 端口 | 来源 IP | 策略 | 说明 |
|---|---|---|---|---|
| TCP | 22 | 203.0.113.10/32 | 允许 | 仅允许办公网 IP 访问 SSH |
| TCP | 2222 | 203.0.113.10/32 | 允许 | 修改后的 SSH 管理端口,仅限办公网 |
| TCP | 80 | 0.0.0.0/0 | 允许 | 对外开放 HTTP 服务 |
| TCP | 443 | 0.0.0.0/0 | 允许 | 对外开放 HTTPS 服务 |
| TCP | 3306 | 10.0.0.0/8 | 允许 | 数据库端口仅允许内网访问 |
| TCP | 6379 | 10.0.0.0/8 | 允许 | Redis 端口仅允许内网访问 |
| 全部 | 全部 | 0.0.0.0/0 | 拒绝 | 兜底拒绝所有未放行流量(置于规则列表末尾) |
说明:安全组规则按优先级从上到下匹配,命中即生效。建议将「拒绝全部」作为最后一条兜底规则,并将管理端口(SSH、数据库等)的来源 IP 严格限制为办公网或内网网段,避免暴露在公网。
4.4 部署简单的入侵防御
可选用开源工具如 crowdsec 或 snort 增强网络层检测能力。以 CrowdSec 为例:
curl -s https://install.crowdsec.net | sh
systemctl start crowdsec
cscli collections install crowdsecurity/sshd
cscli decisions list
CrowdSec 基于社区共享的威胁情报,能自动识别并封禁恶意 IP,适合作为 Fail2ban 的增强替代方案。
5. 系统更新与漏洞管理
5.1 定期更新系统补丁
保持系统补丁最新是抵御已知漏洞攻击的最有效手段:
# 检查可用更新
yum check-update
# 更新所有软件包
yum update -y
# 仅更新安全补丁
yum update --security -y
5.2 配置自动安全更新
安装自动更新工具:
yum install -y yum-cron
编辑 /etc/yum/yum-cron.conf:
update_cmd = security
apply_updates = yes
启动服务:
systemctl start yum-cron
systemctl enable yum-cron
5.3 漏洞扫描
定期使用漏洞扫描工具评估服务器安全状况:
# 安装 Lynis 安全审计工具
yum install -y epel-release
yum install -y lynis
# 执行安全审计
lynis audit system
Lynis 会输出详细的安全建议报告,可作为加固依据。此外,也可使用 nmap 对自身服务进行端口扫描,验证暴露面:
yum install -y nmap
nmap -sV -p- server_ip
6. 日志监控与入侵检测
6.1 关键日志文件
CentOS 7 的关键日志位置:
| 日志文件 | 说明 |
|---|---|
/var/log/messages | 系统通用日志 |
/var/log/secure | 安全认证日志(SSH、sudo 等) |
/var/log/cron | 计划任务日志 |
/var/log/boot.log | 系统启动日志 |
/var/log/httpd/ | Apache 访问与错误日志 |
/var/log/nginx/ | Nginx 访问与错误日志 |
6.2 日志审计关键点
日常巡检时应重点关注:
# 查看 SSH 登录成功记录
grep "Accepted" /var/log/secure
# 查看 SSH 登录失败记录
grep "Failed password" /var/log/secure | tail -50
# 查看 sudo 使用记录
grep "sudo" /var/log/secure
# 查看新增用户
grep "useradd" /var/log/secure
6.3 配置 rsyslog 远程日志
为防止攻击者清除本地日志,建议将日志实时同步到远程日志服务器。编辑 /etc/rsyslog.conf:
*.* @logserver.example.com:514
重启服务:
systemctl restart rsyslog
6.4 部署入侵检测工具
推荐使用 AIDE(高级入侵检测环境)监控关键文件完整性:
yum install -y aide
初始化数据库:
aide --init
mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
定期比对:
aide --check
可将比对任务加入 crontab 每日执行,并将结果发送至管理员邮箱。
7. 安全应急响应流程
安全应急响应是指在安全事件(如入侵、勒索、数据泄露)发生后,为控制损失、恢复业务、溯源取证而采取的一系列有序行动。一个规范的应急响应流程通常包含以下阶段:
说明:上图将应急响应拆解为「发现 → 研判 → 隔离 → 取证 → 清除 → 恢复 → 复盘」七个阶段。每个阶段都包含关键操作步骤(如封禁 IP、备份日志、删除后门)与输出物(如研判记录、取证报告、加固清单),便于团队按图执行、留痕归档。其中「隔离与止损」是控制损失扩大的关键节点,务必在取证前完成;「清除后门与加固」则需在确认入侵路径后彻底执行,防止二次入侵。
7.1 发现与初步研判
常见的安全事件信号包括:
- 服务器 CPU 异常飙高,存在挖矿进程;
- 出现未知账户或异常登录记录;
- 网站被篡改、植入恶意链接;
- 数据库被勒索,出现
.locked等后缀文件; - 对外发起大量异常流量,被云平台告警。
发现异常后,第一时间记录现象、时间、涉及系统,并通知相关人员,避免单人盲目操作破坏现场。
7.2 隔离与止损
隔离是应急响应的第一步,目的是切断攻击者的控制通道,防止损失扩大:
# 立即断开服务器外网(在云平台控制台操作,或直接禁用网卡)
# 或通过安全组紧急封禁来源 IP
# 冻结可疑账户
usermod -L suspicious_user
# 查看并终止可疑进程
ps aux | grep -i suspicious
kill -9 PID
# 查看并清理异常计划任务
crontab -l
cat /etc/crontab
ls /etc/cron.d/
注意:在取证完成前,尽量保持服务器运行状态,不要直接关机或重启,以免丢失内存中的关键证据。
7.3 取证与溯源
取证阶段的目标是还原攻击路径、确认入侵方式。关键取证操作:
# 记录当前系统时间与运行时长
date
uptime
# 查看当前登录用户
who
w
last
# 查看历史命令
history
cat ~/.bash_history
# 查看 SSH 登录日志
grep "Accepted" /var/log/secure | tail -100
# 查看网络连接
netstat -antlp
ss -antlp
# 查看进程
ps -ef
# 查看启动项
ls -la /etc/rc.d/
cat /etc/rc.local
systemctl list-unit-files | grep enabled
对可疑文件进行备份并计算哈希值,作为后续分析依据:
cp /tmp/suspicious_file /evidence/
md5sum /tmp/suspicious_file
sha256sum /tmp/suspicious_file
7.4 清除后门与加固
确认入侵方式后,彻底清除后门并修复漏洞:
# 删除可疑账户
userdel -r suspicious_user
# 清理 SSH 后门公钥
cat ~/.ssh/authorized_keys
# 删除可疑条目
# 清理异常计划任务
crontab -r
# 清理异常启动项
rm -f /etc/rc.d/rc*.d/S99backdoor
# 检查并清理 LD_PRELOAD 后门
cat /etc/ld.so.preload
清除后门后,立即执行第 2 至 5 节的全部加固措施,修改所有密码和密钥,更新系统补丁。
7.5 恢复业务与复盘
确认系统干净后,逐步恢复业务服务,并持续观察一段时间。最后进行复盘总结,输出应急响应报告,内容包括:
- 事件时间线与影响范围;
- 攻击路径与入侵方式;
- 已采取的措施与修复结果;
- 暴露的管理短板与改进计划。
8. 常见安全事件处置实战
8.1 挖矿病毒处置
挖矿病毒是云服务器最常见的入侵类型,典型特征是 CPU 占用率飙升。处置步骤:
# 1. 定位高 CPU 进程
top -c
# 2. 查看进程详情
ls -l /proc/PID/exe
cat /proc/PID/cmdline
# 3. 终止进程并删除文件
kill -9 PID
rm -f /tmp/.xmr-stak
# 4. 清理计划任务与启动项
crontab -l
crontab -r
# 5. 检查 SSH 后门
cat ~/.ssh/authorized_keys
8.2 勒索病毒处置
发现勒索病毒(文件被加密、出现勒索提示)时:
- 立即隔离:断开服务器网络,防止横向扩散;
- 保留现场:不要删除勒索提示文件,不要重启;
- 备份取证:复制被加密文件样本和勒索提示;
- 查找入口:排查弱口令、未修复漏洞、暴露的数据库端口;
- 评估恢复:检查是否有备份可恢复,评估解密工具可行性;
- 重建系统:如无备份,建议重装系统并全面加固后恢复业务。
8.3 Web 入侵处置
网站被篡改或植入恶意代码时:
# 1. 查看 Web 访问日志,定位攻击来源
tail -100 /var/log/nginx/access.log
# 2. 扫描 Web 目录中的恶意文件
grep -r "eval(" /var/www/html/
grep -r "base64_decode" /var/www/html/
# 3. 检查文件完整性
find /var/www/html -type f -mtime -3
# 4. 检查 Web 服务运行账户权限
ps aux | grep nginx
8.4 常见问题快速排查表
| 症状 | 可能原因 | 排查命令 | 处置建议 |
|---|---|---|---|
| SSH 登录慢 | DNS 反向解析超时、GSSAPI 认证延迟 | grep -i "sshd" /var/log/secure、ss -antlp | grep :22 | 在 sshd_config 中设置 UseDNS no 和 GSSAPIAuthentication no,重启 sshd |
| 端口被频繁扫描 | 暴露在公网、未限制来源 IP | grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head | 修改 SSH 默认端口、配置 Fail2ban、通过安全组限制来源 IP |
| CPU 飙高 | 挖矿病毒、异常进程、资源耗尽 | top -c、ps aux --sort=-%cpu | head、ls -l /proc/PID/exe | 定位并终止可疑进程,清理计划任务与启动项,删除恶意文件 |
| 文件被篡改 | Web 入侵、后门植入、权限配置不当 | find /var/www/html -type f -mtime -3、aide --check、grep -r "eval(" /var/www/html/ | 恢复备份、修复漏洞、收紧 Web 目录权限,必要时重建系统 |
| 异常外连 | 木马回连、数据外传、被植入后门 | ss -antlp、netstat -antlp、lsof -i | 记录目标 IP 与进程,终止可疑连接,清除后门并封禁外连 IP |
| 账户异常登录 | 弱口令被爆破、账户泄露 | last、grep "Accepted" /var/log/secure、awk -F: '$3 == 0 {print $1}' /etc/passwd | 冻结可疑账户、修改密码、启用密钥认证并配置登录失败锁定 |
8.5 安全运维与应急响应 CTF 常用命令大全
CTF 竞赛中的运维与应急响应题目,通常要求选手在模拟被入侵的服务器中快速定位后门、还原攻击路径、提取恶意样本。以下命令按场景分类整理,可作为实战速查手册。
8.5.1 信息收集与系统状态
# 系统基本信息
uname -a
cat /etc/redhat-release
hostname
id
# 当前登录用户与登录历史
who
w
last
lastlog
# 系统运行时间与负载
uptime
cat /proc/loadavg
# 环境变量(排查可疑 PATH 劫持)
env
echo $PATH
8.5.2 进程排查
# 查看所有进程
ps -ef
ps aux
# 按 CPU / 内存排序,定位异常进程
ps aux --sort=-%cpu | head -20
ps aux --sort=-%mem | head -20
# 查看进程可执行文件路径与启动命令
ls -l /proc/PID/exe
cat /proc/PID/cmdline | tr '\0' ' '
cat /proc/PID/environ | tr '\0' '\n'
# 查看进程打开的文件与网络连接
lsof -p PID
ls -l /proc/PID/fd
# 查看进程工作目录
ls -l /proc/PID/cwd
8.5.3 网络连接排查
# 查看所有 TCP/UDP 连接及对应进程
netstat -antlp
ss -antlp
# 查看监听端口
netstat -tlnp
ss -tlnp
# 查看 ESTABLISHED 状态的连接(排查外连)
ss -antp | grep ESTAB
# 查看与某 IP 的通信
ss -antp | grep 1.2.3.4
# 抓包分析
tcpdump -i eth0 -nn -s 0 -w /tmp/capture.pcap
tcpdump -i eth0 -nn port 4444
8.5.4 账户与权限排查
# 查看所有用户与 UID 为 0 的账户
cat /etc/passwd
awk -F: '$3 == 0 {print $1}' /etc/passwd
# 查看可登录 Shell 的用户
awk -F: '$7 ~ /(bash|sh)$/ {print $1}' /etc/passwd
# 查看 sudo 权限
cat /etc/sudoers
ls -la /etc/sudoers.d/
# 查看最近登录记录
last
lastb
cat /var/log/secure | grep "Accepted"
8.5.5 文件与后门排查
# 查找最近修改的文件(定位被篡改/植入文件)
find / -type f -mtime -3 2>/dev/null
find /tmp /var/tmp /dev/shm -type f 2>/dev/null
# 查找 SUID 提权文件
find / -perm -4000 -type f 2>/dev/null
# 查找隐藏文件与可疑脚本
find / -name ".*" -type f 2>/dev/null | head -50
find / -name "*.sh" -newer /etc/passwd 2>/dev/null
# 检查 SSH 后门公钥
cat ~/.ssh/authorized_keys
cat /root/.ssh/authorized_keys
# 检查 LD_PRELOAD 后门
cat /etc/ld.so.preload
echo $LD_PRELOAD
# 检查启动项
ls -la /etc/rc.d/
cat /etc/rc.local
systemctl list-unit-files | grep enabled
8.5.6 计划任务排查
# 查看当前用户与 root 的计划任务
crontab -l
crontab -u root -l
# 查看系统级计划任务
cat /etc/crontab
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
# 查看 anacron 与 at 任务
cat /etc/anacrontab
atq
8.5.7 日志分析
# SSH 登录成功/失败记录
grep "Accepted" /var/log/secure
grep "Failed password" /var/log/secure
# 按 IP 统计登录失败次数
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr
# 查看 sudo 与用户创建记录
grep "sudo" /var/log/secure
grep "useradd" /var/log/secure
# 查看 Web 访问日志中的恶意请求
grep -E "(eval|base64|cmd|exec)" /var/log/nginx/access.log
tail -100 /var/log/nginx/access.log
8.5.8 恶意样本提取与哈希
# 备份可疑文件并计算哈希
cp /tmp/suspicious /evidence/
md5sum /tmp/suspicious
sha1sum /tmp/suspicious
sha256sum /tmp/suspicious
# 提取内存中的进程镜像(需 root)
cat /proc/PID/mem > /evidence/mem_dump.bin
# 查看文件类型与字符串
file /tmp/suspicious
strings /tmp/suspicious | head -50
8.5.9 常用提权与漏洞利用辅助
# 查看内核版本与发行版(匹配已知漏洞)
uname -a
cat /etc/redhat-release
# 查看可写文件与目录
find / -writable -type f 2>/dev/null | grep -v proc | head -50
# 查看环境变量中的可疑路径
echo $PATH
cat /etc/profile
cat ~/.bashrc
提示:CTF 应急响应题的核心思路是「先隔离、再取证、后清除」。拿到题目后先备份关键日志与可疑文件,再按「进程 → 网络 → 账户 → 文件 → 计划任务 → 日志」的顺序逐层排查,避免遗漏后门。
9. 安全运维自动化
9.1 编写安全巡检脚本
将日常巡检工作脚本化,可显著提升效率。以下是一个简单的巡检脚本示例:
#!/bin/bash
# security_check.sh - 每日安全巡检脚本
echo "===== 系统安全巡检报告 $(date) ====="
echo ""
echo "--- 1. 最近登录记录 ---"
last -10
echo ""
echo "--- 2. SSH 登录失败统计 ---"
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -10
echo ""
echo "--- 3. 新增用户检查 ---"
awk -F: '$3 >= 1000 {print $1, $3}' /etc/passwd
echo ""
echo "--- 4. 高 CPU 进程 ---"
ps aux --sort=-%cpu | head -6
echo ""
echo "--- 5. 异常计划任务 ---"
crontab -l 2>/dev/null
加入 crontab 每日执行:
chmod +x /usr/local/bin/security_check.sh
echo "0 8 * * * /usr/local/bin/security_check.sh | mail -s 'Daily Security Report' admin@example.com" | crontab -
除了上述基础巡检脚本,下面提供一个更全面的安全基线检查脚本。它逐项检查账户权限、SSH 配置、防火墙规则、关键文件权限、异常进程与网络连接,并为每项输出 PASS/FAIL 状态和对应的修复建议,适合作为定期安全审计的自动化工具:
#!/bin/bash
# security_baseline_check.sh - 安全基线检查脚本
# 用法:sudo bash security_baseline_check.sh
PASS=0
FAIL=0
WARN=0
check() {
local name="$1"
local status="$2"
local advice="$3"
if [ "$status" = "PASS" ]; then
PASS=$((PASS+1))
echo "[PASS] $name"
elif [ "$status" = "WARN" ]; then
WARN=$((WARN+1))
echo "[WARN] $name - $advice"
else
FAIL=$((FAIL+1))
echo "[FAIL] $name - $advice"
fi
}
echo "===== CentOS 7 安全基线检查报告 $(date) ====="
echo ""
# ---------- 1. 账户与权限检查 ----------
echo "--- 1. 账户与权限 ---"
# 1.1 检查 UID 为 0 的账户(正常应只有 root)
uid0=$(awk -F: '$3 == 0 {print $1}' /etc/passwd | grep -v '^root$')
if [ -z "$uid0" ]; then
check "UID 0 账户检查" "PASS" ""
else
check "UID 0 账户检查" "FAIL" "存在非 root 的 UID 0 账户: $uid0,请立即排查并删除: userdel -r $uid0"
fi
# 1.2 检查空密码账户
empty_pw=$(awk -F: '($2 == "" || $2 == "!") && $3 >= 1000 {print $1}' /etc/shadow 2>/dev/null)
if [ -z "$empty_pw" ]; then
check "空密码账户检查" "PASS" ""
else
check "空密码账户检查" "FAIL" "存在空密码账户: $empty_pw,请设置强密码: passwd $empty_pw"
fi
# 1.3 检查可登录账户数量(排除系统账户)
login_users=$(awk -F: '$7 ~ /(bash|sh)$/ && $3 >= 1000 {print $1}' /etc/passwd | wc -l)
if [ "$login_users" -le 5 ]; then
check "可登录账户数量" "PASS" ""
else
check "可登录账户数量" "WARN" "可登录账户较多($login_users 个),请确认是否均为必要账户"
fi
# 1.4 检查 sudoers 是否包含 NOPASSWD
if grep -r "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null | grep -v '^#'; then
check "sudo NOPASSWD 检查" "FAIL" "存在免密 sudo 配置,建议移除 NOPASSWD 以降低风险"
else
check "sudo NOPASSWD 检查" "PASS" ""
fi
echo ""
# ---------- 2. SSH 配置检查 ----------
echo "--- 2. SSH 配置 ---"
# 2.1 检查 PermitRootLogin
if grep -q "^PermitRootLogin no" /etc/ssh/sshd_config 2>/dev/null; then
check "SSH 禁用 root 登录" "PASS" ""
else
check "SSH 禁用 root 登录" "FAIL" "未禁用 root 登录,请在 /etc/ssh/sshd_config 设置 PermitRootLogin no 并重启 sshd"
fi
# 2.2 检查密码认证是否禁用
if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config 2>/dev/null; then
check "SSH 禁用密码认证" "PASS" ""
else
check "SSH 禁用密码认证" "FAIL" "未禁用密码认证,建议启用密钥认证并设置 PasswordAuthentication no"
fi
# 2.3 检查 SSH 端口是否为默认 22
ssh_port=$(grep -E "^Port " /etc/ssh/sshd_config 2>/dev/null | awk '{print $2}')
if [ -n "$ssh_port" ] && [ "$ssh_port" != "22" ]; then
check "SSH 端口非默认" "PASS" ""
else
check "SSH 端口非默认" "WARN" "SSH 仍使用默认端口 22,建议修改为高位端口以降低被扫描风险"
fi
# 2.4 检查 authorized_keys 权限
if [ -f /root/.ssh/authorized_keys ]; then
perm=$(stat -c "%a" /root/.ssh/authorized_keys)
if [ "$perm" = "600" ]; then
check "authorized_keys 权限" "PASS" ""
else
check "authorized_keys 权限" "FAIL" "权限为 $perm,应设为 600: chmod 600 /root/.ssh/authorized_keys"
fi
else
check "authorized_keys 权限" "WARN" "未找到 /root/.ssh/authorized_keys,如使用密钥登录请检查配置"
fi
echo ""
# ---------- 3. 防火墙检查 ----------
echo "--- 3. 防火墙 ---"
# 3.1 检查 firewalld 是否运行
if systemctl is-active firewalld >/dev/null 2>&1; then
check "firewalld 运行状态" "PASS" ""
else
check "firewalld 运行状态" "FAIL" "firewalld 未运行,请启动: systemctl start firewalld && systemctl enable firewalld"
fi
# 3.2 检查是否放行了 SSH 端口
ssh_port_check=${ssh_port:-22}
if firewall-cmd --list-ports 2>/dev/null | grep -q "$ssh_port_check/tcp"; then
check "防火墙放行 SSH 端口" "PASS" ""
else
check "防火墙放行 SSH 端口" "WARN" "防火墙未显式放行 SSH 端口 $ssh_port_check,请确认规则: firewall-cmd --list-all"
fi
# 3.3 检查默认区域策略
default_zone=$(firewall-cmd --get-default-zone 2>/dev/null)
if [ "$default_zone" = "drop" ] || [ "$default_zone" = "public" ]; then
check "防火墙默认区域" "PASS" ""
else
check "防火墙默认区域" "WARN" "默认区域为 $default_zone,建议使用 public 或 drop 以默认拒绝未放行流量"
fi
echo ""
# ---------- 4. 关键文件权限检查 ----------
echo "--- 4. 关键文件权限 ---"
# 4.1 /etc/passwd 权限
perm=$(stat -c "%a" /etc/passwd)
if [ "$perm" = "644" ]; then
check "/etc/passwd 权限" "PASS" ""
else
check "/etc/passwd 权限" "FAIL" "权限为 $perm,应设为 644: chmod 644 /etc/passwd"
fi
# 4.2 /etc/shadow 权限
perm=$(stat -c "%a" /etc/shadow)
if [ "$perm" = "000" ] || [ "$perm" = "400" ] || [ "$perm" = "600" ]; then
check "/etc/shadow 权限" "PASS" ""
else
check "/etc/shadow 权限" "FAIL" "权限为 $perm,应设为 000 或 600: chmod 600 /etc/shadow"
fi
# 4.3 /etc/ssh/sshd_config 权限
perm=$(stat -c "%a" /etc/ssh/sshd_config)
if [ "$perm" = "600" ]; then
check "sshd_config 权限" "PASS" ""
else
check "sshd_config 权限" "FAIL" "权限为 $perm,应设为 600: chmod 600 /etc/ssh/sshd_config"
fi
# 4.4 查找全局可写文件(排除 /proc /sys /dev)
world_writable=$(find / -xdev -type f -perm -0002 2>/dev/null | grep -vE '^/(proc|sys|dev)' | head -5)
if [ -z "$world_writable" ]; then
check "全局可写文件检查" "PASS" ""
else
check "全局可写文件检查" "FAIL" "存在全局可写文件: $world_writable,请收紧权限: chmod o-w <file>"
fi
echo ""
# ---------- 5. 异常进程检查 ----------
echo "--- 5. 异常进程 ---"
# 5.1 检查高 CPU 进程(阈值 80%)
high_cpu=$(ps aux --sort=-%cpu | awk 'NR>1 && $3 > 80 {print $11, "CPU:"$3"%"}')
if [ -z "$high_cpu" ]; then
check "高 CPU 进程检查" "PASS" ""
else
check "高 CPU 进程检查" "WARN" "存在高 CPU 进程: $high_cpu,请确认是否为挖矿等恶意进程"
fi
# 5.2 检查常见挖矿进程名
miner=$(ps aux | grep -iE "(xmrig|minerd|kdevtmpfsi|kinsing|watchdogs)" | grep -v grep)
if [ -z "$miner" ]; then
check "挖矿进程检查" "PASS" ""
else
check "挖矿进程检查" "FAIL" "发现疑似挖矿进程: $miner,请立即终止并排查: kill -9 PID"
fi
echo ""
# ---------- 6. 网络连接检查 ----------
echo "--- 6. 网络连接 ---"
# 6.1 检查异常外连(排除常见端口 80/443/53/22)
estab=$(ss -antp 2>/dev/null | grep ESTAB | awk '{print $5}' | grep -vE ':(80|443|53|22)$' | head -5)
if [ -z "$estab" ]; then
check "异常外连检查" "PASS" ""
else
check "异常外连检查" "WARN" "发现非常见端口的外连: $estab,请确认是否为业务需要"
fi
# 6.2 检查监听端口(排除常见服务端口)
listen=$(ss -tlnp 2>/dev/null | awk 'NR>1 {print $4}' | grep -vE ':(22|80|443|3306|6379|11211)$' | head -5)
if [ -z "$listen" ]; then
check "异常监听端口检查" "PASS" ""
else
check "异常监听端口检查" "WARN" "发现非常见监听端口: $listen,请确认是否为后门或未授权服务"
fi
echo ""
echo "===== 检查完成 ====="
echo "PASS: $PASS FAIL: $FAIL WARN: $WARN"
if [ "$FAIL" -gt 0 ]; then
echo ">>> 存在 $FAIL 项未通过,请按上方建议立即修复!"
else
echo ">>> 所有关键检查项均通过。"
fi
说明:该脚本将检查结果分为
PASS(符合基线)、FAIL(必须修复)和WARN(建议关注)三档。FAIL项通常意味着存在明确的安全风险(如 root 可登录、空密码账户、关键文件权限错误),应优先处理;WARN项多为加固建议(如默认 SSH 端口、异常外连),需结合业务场景判断。建议将该脚本加入 crontab 每日执行,并将输出重定向到日志文件,便于持续跟踪安全状态:
chmod +x /usr/local/bin/security_baseline_check.sh
echo "0 9 * * * /usr/local/bin/security_baseline_check.sh > /var/log/security_baseline.log 2>&1" | crontab -
security_check.sh 执行结果示例
以下是一次实际运行 security_check.sh 后的输出示例,展示了脚本生成的完整巡检报告效果:
===== 系统安全巡检报告 2026-08-31 08:00:01 =====
--- 1. 最近登录记录 ---
admin pts/0 203.0.113.10 Sat Aug 31 07:55 still logged in
admin pts/0 203.0.113.10 Sat Aug 31 07:30 still logged in
root pts/1 198.51.100.23 Sat Aug 31 06:12 - 06:15 (00:03)
admin pts/0 203.0.113.10 Fri Aug 30 22:40 - 23:10 (00:30)
root pts/0 203.0.113.10 Fri Aug 30 18:05 - 18:20 (00:15)
--- 2. SSH 登录失败统计 ---
156 203.0.113.66
89 198.51.100.77
12 203.0.113.10
3 192.0.2.15
--- 3. 新增用户检查 ---
admin 1000
deploy 1001
mysql 1002
--- 4. 高 CPU 进程 ---
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1234 98.7 2.1 123456 45678 ? S 06:00 45:32 /tmp/.xmr-stak
root 567 3.2 0.4 56789 12345 ? S 05:30 12:10 /usr/sbin/sshd
admin 2345 1.1 0.2 34567 8901 ? S 07:00 0:45 -bash
--- 5. 异常计划任务 ---
*/5 * * * * /tmp/.update.sh >/dev/null 2>&1
如何解读巡检结果
拿到上述报告后,应按下述思路逐项分析,快速定位潜在安全问题:
- 最近登录记录:重点核对登录来源 IP 是否属于办公网或已知运维网段。若出现陌生 IP、非工作时间登录、或
root直接登录(说明未禁用 root SSH),应立即排查。示例中198.51.100.23的 root 登录需确认是否为管理员本人操作。 - SSH 登录失败统计:这是判断是否遭受暴力破解的核心指标。示例中
203.0.113.66在短时间内失败 156 次,明显是爆破攻击源,应通过 Fail2ban 或防火墙封禁该 IP,并确认是否已有账户被攻破。 - 新增用户检查:对比输出与已知账户清单,出现陌生 UID ≥ 1000 的账户即为后门账户。示例中
deploy、mysql需确认是否为业务所需,若无法说明来源应立即冻结并删除。 - 高 CPU 进程:CPU 占用率异常高的进程是挖矿病毒的最典型特征。示例中
/tmp/.xmr-stak占用 98.7% CPU,且路径位于/tmp下,几乎可以判定为挖矿木马,需按第 8.1 节流程处置。 - 异常计划任务:计划任务是攻击者维持持久化的常用手段。示例中
/tmp/.update.sh每 5 分钟执行一次,路径可疑,应查看脚本内容并清理,同时检查 crontab 是否被篡改。
提示:巡检脚本的价值在于「持续对比」。建议将每日输出保存为日志,与历史报告对比,任何「新增的陌生 IP、新出现的账户、新出现的计划任务、CPU 突然飙高」都是需要立即关注的安全信号。若发现异常,应结合第 7 节应急响应流程与第 8 节处置实战进行排查。
9.2 使用 Ansible 批量管理
对于多台服务器,可使用 Ansible 统一执行安全加固:
# 安装 Ansible
yum install -y ansible
# 编写加固 Playbook
cat > /etc/ansible/harden.yml << 'EOF'
---
- hosts: all
become: yes
tasks:
- name: 禁用 root SSH 登录
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
notify: restart sshd
- name: 安装 Fail2ban
yum:
name: fail2ban
state: present
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
EOF
# 执行加固
ansible-playbook -i hosts harden.yml
10. 总结与最佳实践清单
CentOS 7 云服务器的安全运维与应急响应是一项系统工程,需要从预防、监控、响应三个层面持续投入。以下是本教程的核心要点总结:
安全运维最佳实践清单
- 禁用 root 直接 SSH 登录,使用密钥认证;
- 修改 SSH 默认端口,配置 Fail2ban 防暴力破解;
- 遵循最小权限原则,为账户配置独立 sudo 权限;
- 防火墙与安全组仅开放必要端口,管理端口限制来源 IP;
- 定期更新系统安全补丁,配置自动更新;
- 部署 AIDE 文件完整性监控与日志远程备份;
- 定期执行安全巡检,关注异常登录与高 CPU 进程;
- 制定并演练应急响应预案,明确责任人。
应急响应核心原则
- 先隔离,后处置:第一时间切断攻击通道;
- 保留现场:取证完成前不重启、不删除关键证据;
- 彻底清除:清除后门后必须全面加固,防止二次入侵;
- 复盘改进:每次事件后总结经验,持续完善安全体系。
安全运维没有终点,而是一个持续迭代的过程。建议读者结合自身业务场景,将本教程中的方案落地为日常制度,并定期进行安全演练,真正做到「防患于未然,处置于及时」。
425

被折叠的 条评论
为什么被折叠?



