买完云服务器、部署完业务,很多人的运维就止步于"能跑就行"。可服务器的安全状态不是一次配好就永远有效的:装了某个服务顺带开了一个端口、给某个账号加了 sudo 却忘了回收、系统内核停留在几年前的版本、某个关键文件权限被改成了 777……这些"基线偏移"日积月累,就是风险慢慢累积的过程。所谓安全基线检查,就是定期对照一套标准,把这台服务器的账号、端口、补丁、权限、配置逐项核对一遍,找出偏离项并修回去。
这篇文章给出一份可直接照着做的云服务器安全基线检查清单,覆盖五个方面:账号与权限(UID 0 账号、空口令、长期未登录、sudoers)、端口与服务(ss -lntp、关闭无用服务)、补丁(dnf/apt 更新、内核版本、是否需要重启)、文件权限(SUID、关键文件)、SSH 配置与日志审计。每一项都给出检查命令、判断标准和修复方向,命令区分 RHEL/CentOS/Rocky 与 Debian/Ubuntu 两套。
这份清单适用于单机或少量服务器的手工核查。如果你的服务器规模较大,建议把清单里的检查项做成脚本或接入自动化工具定期跑,把"人工巡检"变成"自动核查"。无论如何,涉及的删账号、改权限、装补丁操作都会给出风险提示和回滚方式,请在操作前确认影响范围。
一、为什么需要基线检查:从"能跑"到"可控"
安全基线这个概念听起来很正式,其实很朴素:它就是"这台服务器在一个健康状态下应该长什么样"的标准描述。账号该有哪些、端口该开哪些、补丁该打到什么程度、关键文件权限该是多少——这些就是基线。基线检查就是拿现状和标准比,找出不一样的地方。
它的价值在于"可重复"和"能发现问题"。手工凭感觉看服务器,每次关注的点和结论都可能不一样;而按固定清单逐项过一遍,就不会漏项,也便于不同人、不同时间得到一致的判断。对于只有一两台服务器的中小企业 IT 或个人站长,这就是最低成本的常态化安全运维。
基线检查最好定期做,比如每季度一次,或者每次上线新服务、改过防火墙之后再做一次。它也适合作为"接手一台老服务器"时的第一件事——在搞清楚它到底开了什么、跑了什么之前,任何优化都无从谈起。
二、账号与权限核查
账号是最容易被忽视、也最危险的一块。一个多余的账号可能就是一个后门。
检查 1:有没有非预期的 UID 0 账号
UID 为 0 的账号就是 root,拥有最高权限。系统里除了 root,不应该有第二个 UID 是 0 的账号——如果有,那几乎可以确定是被入侵后留下的后门。
# 列出所有 UID 为 0 的账号(正常应该只有 root 一个)
awk -F: '$3==0 {print $1, $3}' /etc/passwd
# 顺带看看 UID 和 GID 异常的账号
awk -F: '($3==0 || $4==0) {print $1, $3, $4}' /etc/passwd
判断标准很简单:除了 root,任何 UID 为 0 的账号都要查明来源,确认是恶意或多余的,立即处理。
检查 2:有没有空口令账号
空口令账号等于没有密码,能从某些通道直接登录,风险很大。
# 检查是否存在空口令账号(第 2 字段为空或只有 ::)
awk -F: '($2=="") {print "空口令:", $1}' /etc/shadow
# 更宽松地看:所有账号的口令字段状态
sudo awk -F: '{print $1, $2}' /etc/shadow | grep -E '^[^ ]+ *$|^[^ ]+ *!?$' | head
/etc/shadow 第二字段的含义要记住:! 或 * 表示该账号口令被锁定、无法用密码登录(这是好事,系统账号通常如此);$6$ 开头是加密后的口令哈希;空则表示可以空口令登录(危险)。
# 查看是否有账号允许空口令(部分系统可在 PAM 里检查)
sudo grep -r "nullok" /etc/pam.d/ 2>/dev/null
nullok 出现在 PAM 配置里意味着允许空口令登录,应该去掉。
检查 3:长期未登录的账号
用 lastlog 找从未登录或很久没登录的账号。长期不用的账号是"僵尸账号",一旦泄露就是隐患,应该锁定或删除。
# 查看每个账号最后一次登录时间
sudo lastlog
# 只看从未登录过的账号
sudo lastlog | grep -i "Never logged in"
处理时注意区分:系统服务账号(如 bin、daemon、sshd)本来就不会交互登录,不能用"未登录"来判断它们是多余的。真正要关注的是"人类用户"账号里长期不用的,以及能交互登录却从没登录过的。
# 锁定一个不再使用的账号(保留账号但禁止登录)
sudo usermod -L <用户名>
# 更彻底:把登录 shell 改为 nologin
sudo usermod -s /usr/sbin/nologin <用户名>
风险提示:usermod -L 锁定账号或删除账号前,务必确认该账号没有被业务、定时任务、服务进程使用。删错账号可能导致服务无法启动。回滚方式:usermod -U <用户名> 解锁;删错的账号视情况重建。生产环境操作前先备份 /etc/passwd、/etc/shadow、/etc/group。
检查 4:sudoers 与提权权限
sudoers 决定了谁能提权。要确认没有多余的提权授权,尤其要留意"免密提权"和"给普通用户全权限"的配置。
# 查看 sudoers 主文件(用 visudo 编辑,不要直接改)
sudo cat /etc/sudoers | grep -vE '^\s*#|^\s*$'
# 查看 sudoers.d 里的所有片段
sudo ls -l /etc/sudoers.d/
sudo grep -rE 'ALL' /etc/sudoers.d/ 2>/dev/null
# 找出所有能执行 sudo 的用户
sudo grep -rE '^\s*[^#].*ALL' /etc/sudoers /etc/sudoers.d/ 2>/dev/null
重点关注两类配置:一是 ALL=(ALL) NOPASSWD: ALL 这种"免密全权限",除非必要不应存在;二是给了一些不必要用户提权。编辑器一律用 visudo,它会做语法检查,避免改坏导致谁都提不了权。
# 正确编辑 sudoers 的方式
sudo visudo
# 如果 sudoers 写坏了导致无法 sudo,用 root 直接编辑(或进救援模式)修复
# 单用户/救援模式下:mount -o remount,rw / ;然后编辑 /etc/sudoers
另外也检查一下有没有非预期的 SUID 提权工具、以及 wheel/sudo 组的成员。
# 查看特权组成员
getent group sudo # Debian/Ubuntu
getent group wheel # RHEL 系
三、端口与服务核查
"开了哪些端口"直接等于"暴露面有多大"。用 ss 列出所有监听,逐个确认是否必要。
# 列出所有监听端口及对应进程
sudo ss -lntup
# 只列 TCP 监听(更清爽)
sudo ss -lntp
# 只列 UDP 监听
sudo ss -lnup
拿到列表后,按下面的标准逐项判断。
| 检查项 | 判断标准 | 处理方向 |
|---|---|---|
| 对外监听的服务 | 只保留业务必需的端口 | 关闭无用服务 |
| 监听地址 | 后端服务应绑 127.0.0.1 或内网 | 收窄到内网 |
| 数据库/缓存端口 | 不应出现在 0.0.0.0 | 绑内网 + 安全组限制 |
| 管理端口 | 应限制来源 | 白名单或走 VPN |
| 未知进程监听 | 查清来源 | 确认恶意则清除 |
高风险的典型是:3306、6379、27017、9200、11211 这些后端服务监听在 0.0.0.0 且安全组放行了公网。看到这类情况,优先级最高。
同时盘一下正在运行的服务,关掉用不上的。
# 列出正在运行的服务
systemctl list-units --type=service --state=running
# 列出所有已启用(开机自启)的服务
systemctl list-unit-files --type=service --state=enabled
# 停用并禁止某个无用服务开机自启(示例)
sudo systemctl stop <服务名>
sudo systemctl disable <服务名>
风险提示:停用服务前,务必确认它不是业务依赖(尤其注意共享的中间件、监控代理、日志代理)。建议在业务低峰期操作,并记下 systemctl enable --now <服务名> 作为恢复命令。
四、补丁与内核版本核查
补丁是"用最低成本消除已知风险"的手段。一台长期不打补丁的服务器,等于把一堆已知问题原样保留着。
检查 5:查看系统版本与可用更新
# RHEL / CentOS / Rocky / AlmaLinux
cat /etc/redhat-release
sudo dnf check-update # 列出可用更新(退出码 100 表示有更新)
sudo dnf updateinfo list security # 只列安全相关更新(若仓库支持)
# Debian / Ubuntu
lsb_release -a
sudo apt update
sudo apt list --upgradable
# 只关注安全更新
sudo apt-get -s upgrade | grep -i security
先看有没有更新,决定是"立刻打"还是"排期打"。安全相关的更新优先级最高;内核、glibc、OpenSSL、OpenSSH 这类基础组件的更新尤其重要。
# 查看当前内核版本
uname -r
# 查看已安装的内核包
# RHEL 系:rpm -qa | grep kernel
# Debian/Ubuntu:dpkg -l | grep linux-image
检查 6:是否需要重启才能生效
打补丁后有个常见陷阱:内核和某些库的更新不会立即生效,必须重启。判断依据是有没有生成 /var/run/reboot-required 这类标记,或者当前运行内核是否与已安装的最新内核一致。
# Debian / Ubuntu:检查是否需要重启
ls -l /var/run/reboot-required 2>/dev/null && cat /var/run/reboot-required.pkgs 2>/dev/null
# RHEL 系:用 needs-restarting(需 dnf-utils 包)
sudo dnf install -y dnf-utils
sudo needs-restarting -r # -r 检查是否需要重启
sudo needs-restarting -s # 检查哪些服务需要重启
# 通用:对比正在运行的内核与已安装的最新内核
uname -r
rpm -q kernel | sort -V | tail -1 # RHEL 系
dpkg -l | grep linux-image | tail -1 # Debian/Ubuntu
如果运行的内核比已安装的最新内核旧,就需要择期重启。重启前要安排好维护窗口,并确认服务能自动拉起。
# 打补丁(示例)
# RHEL 系:
sudo dnf update -y
# 只打安全补丁(若发行版支持)
sudo dnf update --security -y
# Debian / Ubuntu:
sudo apt update && sudo apt upgrade -y
sudo apt full-upgrade -y # 处理依赖关系变化时使用
风险提示:dnf update/apt upgrade 可能升级内核、glibc 等基础组件,存在与业务不兼容的可能。生产环境应先在测试环境验证,或至少先做快照/备份,并安排在维护窗口执行。重启前确认有带外管理(云控制台)可用,避免重启后系统起不来却无法介入。回滚方式:RHEL 系可 dnf history undo,云服务器可回滚快照。
五、文件权限核查
权限配错是又一个高频问题。核心是找"不该有的 SUID/SGID"和"过于宽松的关键文件权限"。
检查 7:查找 SUID/SGID 文件
SUID 文件在执行时以文件属主的权限运行,如果属主是 root,就等于一个提权入口。系统自带的 SUID 程序是正常的,但多余的、可被滥用的 SUID 文件是隐患。
# 查找所有 SUID 文件(-perm -4000)
sudo find / -xdev -perm -4000 -type f -ls 2>/dev/null
# 查找所有 SGID 文件(-perm -2000)
sudo find / -xdev -perm -2000 -type f -ls 2>/dev/null
# 结合 RPM/DPKG 校验,找出"包管理之外"的 SUID 文件(更精准)
# RHEL 系:用 rpm 校验文件是否属于某个包
sudo find / -xdev -perm -4000 -type f -exec rpm -qf {} \; 2>/dev/null | grep "not owned"
# Debian/Ubuntu:
sudo find / -xdev -perm -4000 -type f -exec dpkg -S {} \; 2>/dev/null | grep "no path found"
-xdev 表示不跨越文件系统(避免扫描挂载的网络盘)。判断标准:如果一个 SUID 文件不属于任何软件包(not owned/no path found),或者它的作用你完全不清楚,就应该重点审视。常见系统 SUID 程序如 passwd、sudo、su、mount 是正常的;如果你发现某个莫名其妙的自定义二进制带 SUID,要高度警惕。
# 去掉某个不必要的 SUID 位(谨慎,确认不影响功能)
sudo chmod u-s /path/to/file
检查 8:关键文件与目录权限
下面这些文件/目录的权限如果过松,可能被篡改或读取敏感信息。
# 检查关键文件的权限(第一列是权限、属主、属组)
ls -l /etc/passwd /etc/shadow /etc/group /etc/gshadow
ls -ld /etc /root /home /var/log
# 检查是否有全局可写的目录或文件(高风险)
sudo find / -xdev -type d -perm -0002 ! -perm -1000 2>/dev/null # 全局可写且无 sticky 位
sudo find / -xdev -type f -perm -0002 2>/dev/null | head -50 # 全局可写文件
权限的"正确值"参考:
| 文件/目录 | 期望权限 | 说明 |
|---|---|---|
/etc/passwd |
644 | 可被读,不应被写 |
/etc/shadow |
000 或 640(root 可读) | 绝不能全局可读 |
/etc/group |
644 | — |
/etc/gshadow |
000 或 640 | — |
/root |
700 | 只有 root 可进 |
/etc/ssh/sshd_config |
600 | 含配置,不应被普通用户改 |
用户 ~/.ssh |
700 | 见 SSH 密钥文章 |
用户 ~/.ssh/authorized_keys |
600 | — |
# 修正关键文件权限(示例,按上表调整)
sudo chmod 644 /etc/passwd /etc/group
sudo chmod 000 /etc/shadow /etc/gshadow # 或 640,视发行版而定
sudo chmod 700 /root
# 排查全局可写的目录(临时目录 /tmp 通常是 1777,带 sticky 位,属正常)
sudo find / -xdev -type d -perm -0002 ! -perm -1000 2>/dev/null
风险提示:修改 /etc/shadow、/etc/gshadow 的权限时,不同发行版和 PAM 配置对权限要求可能不同,改错会导致无法登录或认证失败。改之前务必确认当前值,并用另一个已登录的会话验证。建议逐项小改、改完立即验证。
六、SSH 配置与日志审计核查
SSH 是公网服务器最常被攻击的入口,它的配置要重点核查。用 sshd -T 查看实际生效的配置(比看文件更可靠,它会合并所有片段)。
# 查看 SSH 生效的关键配置
sudo sshd -T | grep -iE 'passwordauthentication|permitrootlogin|pubkeyauthentication|permitemptypasswords|maxauthtries|port'
# 期望值(加固目标):
# passwordauthentication no (关闭密码登录)
# permitrootlogin no (禁止 root 直登)
# pubkeyauthentication yes (启用密钥)
# permitemptypasswords no (禁止空口令)
# maxauthtries 3 (限制尝试次数)
如果发现 passwordauthentication yes 且服务器在公网,应立即按密钥登录那篇的流程加固。
日志审计方面,确认日志在正常记录,并定期看失败登录的分布。
# 查看认证日志是否在记录
sudo tail -20 /var/log/secure # RHEL 系
sudo tail -20 /var/log/auth.log # Debian/Ubuntu
# 用 journalctl 也可
sudo journalctl -u sshd --since "1 day ago" | tail -20
# 统计失败登录 Top IP
sudo grep "Failed password" /var/log/secure 2>/dev/null | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# Debian/Ubuntu 换成 /var/log/auth.log
七、一份可勾选的基线检查清单
把上面所有内容整理成一张表,做成日常巡检的勾选项。
| 序号 | 检查项 | 检查命令(要点) | 通过标准 | 状态 |
|---|---|---|---|---|
| 1 | UID 0 账号 | awk -F: '$3==0{print $1}' /etc/passwd |
只有 root | ☐ |
| 2 | 空口令账号 | awk -F: '($2==""){print $1}' /etc/shadow |
无空口令账号 | ☐ |
| 3 | 长期未登录账号 | lastlog |
无多余人类账号 | ☐ |
| 4 | sudoers 授权 | grep -r ALL /etc/sudoers* |
无多余免密提权 | ☐ |
| 5 | 监听端口 | ss -lntup |
只开业务必需端口 | ☐ |
| 6 | 后端服务暴露 | ss -lntp \| grep 3306 |
未监听 0.0.0.0 | ☐ |
| 7 | 无用服务 | systemctl list-unit-files --state=enabled |
无多余自启服务 | ☐ |
| 8 | 系统更新 | dnf check-update / apt list --upgradable |
无高危未打补丁 | ☐ |
| 9 | 内核版本 | uname -r vs 已装内核 |
一致或已排期重启 | ☐ |
| 10 | 是否需要重启 | needs-restarting -r / 查 reboot-required |
无待重启 | ☐ |
| 11 | SUID 文件 | find / -xdev -perm -4000 |
无非预期 SUID | ☐ |
| 12 | 关键文件权限 | ls -l /etc/shadow /etc/passwd |
符合期望值 | ☐ |
| 13 | 全局可写文件 | find / -xdev -type f -perm -0002 |
无异常 | ☐ |
| 14 | SSH 加固 | sshd -T \| grep password |
关闭密码登录 | ☐ |
| 15 | 日志审计 | 看失败登录 Top IP | 日志正常、无异常成功登录 | ☐ |
每次巡检时,逐项对照,把"不通过"的项列出来,安排修复并在下一次复查时确认闭环。
常见问题
Q:多久做一次基线检查?
建议每季度一次,加上"重大变更后"(上线新服务、改过防火墙/SSH、装过新软件)。对于暴露在公网的服务器,补丁检查可以更频繁,比如每月看一眼有没有安全更新。
Q:发现一个 UID 0 的可疑账号,怎么处理?
这是最高优先级的事。先不要急着删——它可能是入侵后的后门。正确做法是:保留现场、检查该账号相关的进程和登录记录、排查是否还有其他后门(新增公钥、定时任务、异常进程),确认影响范围后再清理,并考虑重装系统。删账号只是最后一步,前面的排查更重要。
Q:补丁要不要全部打?会不会影响业务?
优先打安全补丁,尤其是内核、OpenSSL、OpenSSH、glibc 这类基础组件。业务相关的更新(比如某个中间件的小版本)要评估兼容性。生产环境建议先在测试环境验证,或用云快照做好回滚准备,并安排在维护窗口执行。
Q:SUID 文件很多,哪些需要关注?
默认系统自带的 SUID 程序是正常的,不用动。需要关注的是"不属于任何软件包"的、位置奇怪的、名字陌生的 SUID 文件。用 rpm -qf/dpkg -S 判断它是否属于某个包,是个高效的筛选方法。
Q:手工逐项检查太慢,有更高效的办法吗?
可以写成一个 shell 脚本,把上面清单里的命令串起来,输出一份报告;也可以接入成熟的安全检查工具(如开源的基线核查工具或云厂商的安全中心)。核心是让"检查"这件事可重复、可自动化,而不是每次靠人重来。
总结
安全基线检查的实质,是定期把服务器现状和"健康状态的标准"做一次对照。它不复杂,但贵在坚持和覆盖全面。
账号方面,重点查 UID 0 账号、空口令账号、长期未登录账号和 sudoers 授权——这几项直接关系到"谁能提权、谁能登录",是风险最高的一类。
端口与服务方面,用 ss -lntup 盘清所有监听,只留业务必需的;后端服务必须绑内网,绝不能监听在 0.0.0.0 并放行公网。
补丁方面,定期看可用更新、优先打安全补丁、记住内核更新需要重启才生效,重启前备好快照和控制台入口。
文件权限方面,用 find -perm -4000 找 SUID、核对关键文件权限、排查全局可写文件,这些都是能被利用的薄弱点。
最后,把这份清单做成可勾选、可重复的表,甚至写成脚本自动跑。安全不是一次性配置的结果,而是持续核查、持续修正的过程。基线守住了,风险就很难悄悄积累起来。
企业QQ咨询




