CentOS服务器从开发环境切换到生产环境,或者新业务首次对外发布,上线前的安全检查不是走一遍防火墙命令就完事。很多事故都发生在“以为检查过了”的节点上——SSH端口暴露、SELinux被一关了之、日志没人收集、内核参数还是安装时的默认值。下面这份清单按“先系统、再网络、后应用、最后审计”的顺序展开,每一项都对应可直接执行的命令或配置,适合CentOS 7/8以及各类衍生发行版在业务上线前逐项核对。

系统基础状态与最小化原则

上线前先确认系统版本和内核状态,避免带着测试期的内核漏洞上线。执行 uname -a 和 cat /etc/redhat-release 记录当前内核与发行版本,检查 /etc/yum.conf 是否还残留测试用的第三方源。生产环境建议只保留Base、Updates和必要的官方Extra源,第三方源如果业务确实需要,必须固定版本并关闭自动更新。用 rpm -qa --last 查看最近安装的软件包,凡是上线前临时装的编译工具、图形界面、开发库,一律用 yum remove 清理。最小化安装的CentOS不应该出现gcc、make、X11相关包,除非业务编译型服务明确依赖。

接着检查开机自启服务。systemctl list-unit-files --type=service --state=enabled 会列出所有开机启动项。除了sshd、crond、rsyslog、network以及业务自身服务外,多余的postfix、chronyd、firewalld如果不用就禁用。特别注意CentOS 7默认开启的auditd不要随意关闭,它不仅是安全审计需要,很多等保和合规检查也会看这个服务状态。如果确实因为性能原因要关闭,必须在运维文档中记录原因和审批人。

账户、权限与认证策略

先处理账户层面。cat /etc/passwd 检查是否存在UID为0的账户,除了root外不允许任何其他账户UID为0。用 awk -F: '($3==0){print $1}' /etc/passwd 可以快速列出。同时检查空密码账户,awk -F: '($2==""){print $1}' /etc/shadow 的结果必须为空。业务运行账户要单独创建,禁止直接用root跑业务进程,且业务账户的登录shell设为/sbin/nologin,只通过服务管理工具启动。

SSH配置是上线检查的重灾区。编辑 /etc/ssh/sshd_config,确认 PermitRootLogin 的值为 no 或 prohibit-password,PasswordAuthentication 设为 no 并强制使用密钥登录,如果业务方确实需要密码登录,必须设置足够复杂的密码策略并限制来源IP。同时把 MaxAuthTries 设为 3,LoginGraceTime 设为 30,X11Forwarding 设为 no。修改后执行 sshd -t 验证配置语法,再 systemctl reload sshd 生效。不要直接重启sshd服务,reload足够让配置生效且不会断开当前连接。

密码策略方面,编辑 /etc/login.defs 确认 PASS_MAX_DAYS 不超过90,PASS_MIN_DAYS 设为1,PASS_WARN_AGE 设为7。如果系统使用PAM模块,检查 /etc/pam.d/system-auth 中 pam_pwquality.so 的配置,至少包含 minlen=12 和 remember=5,防止用户改回旧密码。对于已有账户,用 chage -l 账户名 逐个检查密码过期时间,测试账户一律锁定或删除。

网络暴露面与防火墙策略

用 ss -tulnp 查看当前所有监听端口,对照业务实际需要,只保留必须对外开放的端口。如果看到0.0.0.0:8080、0.0.0.0:3306这类监听,说明服务直接绑定了所有网卡,需要修改服务配置让其只监听内网IP或127.0.0.1。数据库、Redis、Memcached这类组件严禁对公网开放,即使有密码也不行。检查 /etc/hosts.allow 和 /etc/hosts.deny 是否有历史遗留的放行规则,生产环境建议清空这两个文件,统一用firewalld或iptables管理。

防火墙策略要按最小权限重新梳理。如果使用firewalld,先 firewall-cmd --list-all 查看当前生效的zone和规则。不要把默认zone设为trusted,不要为了省事直接 firewall-cmd --set-default-zone=trusted。正确做法是默认zone保持public,只开放22、80、443等必要端口,来源IP能限制就限制。对于管理端口如SSH,建议使用 rich rule 限制来源IP段,例如:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port protocol="tcp" port="22" accept'

执行完所有规则后 firewall-cmd --reload 并再次确认规则生效。如果服务器在云平台上,还要检查云安全组是否与系统防火墙策略一致,两边都要收紧,不能只依赖一层。

SELinux与内核安全参数

很多运维上线第一件事就是 setenforce 0 然后改 /etc/selinux/config 为 disabled,这在生产环境是高风险行为。SELinux不是摆设,它能挡住大量提权和容器逃逸攻击。上线前应该执行 getenforce 确认状态为 Enforcing,如果业务确实因为SELinux报错无法运行,先用 ausearch -m avc -ts recent 查看具体拒绝日志,再用 semanage 或 audit2allow 生成针对性的策略模块,而不是整体关闭。对于Web服务写目录、数据库改端口这类常见场景,都有现成的布尔值和端口标签可以调整。

内核参数同样需要检查。编辑 /etc/sysctl.conf 或 /etc/sysctl.d/99-security.conf,确认以下参数已设置:

net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
kernel.randomize_va_space = 2

修改后执行 sysctl -p 让配置生效。这些参数能防止IP欺骗、SYN Flood和ICMP重定向攻击,属于上线前必须打好的底子。

文件系统与关键目录权限

检查 /etc/fstab 中挂载选项,/tmp、/var/tmp、/dev/shm 这些可写目录建议加上 noexec、nosuid、nodev 挂载选项,防止攻击者在临时目录放置并执行恶意程序。如果业务需要在这些目录执行脚本,可以单独评估后放开。用 mount 命令确认当前挂载参数是否已生效,修改fstab后需要重新挂载对应分区。

关键文件和目录权限也要逐项核对。ls -l /etc/passwd /etc/shadow /etc/group /etc/gshadow 应分别为644、000、644、000。find / -perm -4000 -type f 列出所有SUID文件,除了/usr/bin/passwd、/usr/bin/su等系统自带文件外,任何业务程序或自定义脚本都不应该设置SUID位。同样用 find / -perm -2000 -type f 检查SGID文件。对于Web目录,确认属主和属组正确,上传目录权限不要给777,按最小权限分配,通常755或750配合正确的属主即可。

日志收集与审计配置

上线前必须确认日志服务正常且日志不会无限增长。systemctl status rsyslog 确认服务运行,检查 /etc/rsyslog.conf 中关键日志路径是否配置,特别是 /var/log/secure、/var/log/messages、/var/log/cron。同时配置日志轮转,编辑 /etc/logrotate.d/syslog,确保日志文件按大小或时间切割,保留周期至少30天。对于业务日志,也要在 /etc/logrotate.d/ 下单独配置轮转规则,避免业务日志写满磁盘。

auditd如果开启,检查 /etc/audit/auditd.conf 中日志路径和磁盘空间配置,max_log_file 建议设为50MB以上,num_logs 至少保留5个。用 auditctl -l 查看当前审计规则,至少应该监控 /etc/passwd、/etc/shadow、/etc/ssh/sshd_config 的写入操作,以及所有用户账户的增删改。如果业务有合规要求,还需要记录所有命令执行历史,可以在 /etc/profile.d/ 下添加脚本将history实时写入文件并加上时间戳。

时间同步与计划任务检查

时间不同步会导致日志分析失真、证书校验失败、分布式系统数据不一致。上线前确认 chronyd 或 ntpd 服务已启用,chronyc tracking 查看同步状态,确保系统时间与标准时间偏差小于1秒。如果服务器在云环境,通常平台会提供内部时间源,配置时优先使用内网NTP地址。同时检查 /etc/localtime 是否正确,避免业务日志出现时区混乱。

计划任务方面,crontab -l 和 ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/ 都要检查。重点关注是否有测试期间遗留的定时任务、是否有从外部下载脚本执行的条目、是否有权限过宽的任务文件。/etc/cron.d/ 下的文件权限必须是600,属主为root,否则cron会拒绝执行。对于业务定时任务,统一用独立账户的crontab管理,不要都堆在root下。

业务服务自身安全检查

系统层面检查完后,还要针对具体业务组件做上线前核对。如果是Web服务,确认Nginx或Apache已隐藏版本号,Nginx在http块中设置 server_tokens off,Apache在配置中设置 ServerTokens Prod 和 ServerSignature Off。检查Web目录下是否存在测试文件、备份文件、数据库配置文件,find /var/www -name "*.bak" -o -name "*.sql" -o -name "*.tar.gz" 的结果应该为空。应用配置文件中的数据库密码、API密钥不能明文写在代码仓库,要用环境变量或配置中心注入。

数据库层面,确认MySQL或PostgreSQL只监听内网地址,root账户不允许远程登录,业务账户权限最小化,只授予对应库的增删改查权限,不授予FILE、SUPER等危险权限。检查是否有匿名账户和空密码账户,MySQL中执行 SELECT user,host,plugin FROM mysql.user 查看。同时确认数据库开启了错误日志和慢查询日志,方便上线后排查问题。

如果业务使用Redis,必须设置 requirepass 强密码,禁止 protected-mode no,bind 参数只绑定内网IP。如果业务使用Docker,检查所有容器是否以非root用户运行,docker info 查看是否有容器运行在privileged模式,docker ps 列出所有容器并逐个检查端口映射,容器管理端口如2375、2376严禁对外暴露。

备份与回滚方案确认

安全检查的最后一步是确认出问题时能快速恢复。上线前至少做一次完整的系统快照或镜像备份,如果是物理机,用rsync或tar对关键目录做冷备。数据库必须在上线前做一次全量备份,并验证备份文件可以正常恢复。业务代码要有明确的版本标记,git tag或发布包版本号清晰可查。回滚方案要具体到命令级别,不能只写“回滚到上一版本”,要写清楚回滚哪些文件、执行哪些SQL、重启哪些服务、预计耗时多久。同时确认运维团队有服务器的带外管理权限,IPMI或云平台控制台可以正常登录,防止SSH配置出错后无法进入系统。

这份清单执行下来,大约需要一到两个小时,但能避免绝大多数上线当天才暴露的安全问题。CentOS服务器上线检查的核心不是堆砌安全工具,而是把系统默认状态改造成符合业务实际的最小权限状态,同时保证每一步操作都有日志可查、有备份可回滚。上线后第一周还要持续观察 /var/log/secure 和业务日志中的异常访问,安全是一个持续动作,不是上线那一刻的静态快照。