CentOS服务器上线后如果只做默认安装,等于把一台没锁门的机器直接扔到公网上。很多运维人员以为改个SSH端口、装个fail2ban就算加固完成,实际上攻击者突破一台主机往往只需要一个未修复的内核漏洞、一个权限过高的Web进程,或者一个泄露了明文密码的配置文件。下面直接按操作顺序,从系统底层到应用层,把每一处需要加固的环节和具体命令讲清楚。

1. 最小化安装与内核补丁管理

系统安装阶段就应选择Minimal Install,不要装图形界面、开发工具组和无关服务。已经装好的系统可以用yum list installed检查包清单,用yum remove把gcc、telnet-server、rsh-server、talk-server这类不必要的组件卸载。内核补丁是最高优先级,CentOS 7使用yum update kernel,CentOS 8及以上用dnf update kernel,更新后必须重启生效。生产环境建议配置yum-cron自动安装安全更新,但内核更新最好手动控制时间窗口,避免自动重启导致业务中断。检查当前内核版本和已修复CVE可以用rpm -q --changelog kernel | grep CVE,至少保证没有2023年以前的高危内核提权漏洞。

2. 账户与口令策略硬性收紧

先处理默认账户和空口令账户:awk -F: '($2==""){print $1}' /etc/shadow可以列出无密码账户,确认后立即passwd -l锁定。root登录必须禁止,修改/etc/ssh/sshd_config中的PermitRootLogin no,同时设置AllowUsers或AllowGroups只允许指定运维账户通过SSH登录。口令复杂度在/etc/security/pwquality.conf中配置,minlen=12、dcredit=-1、ucredit=-1、ocredit=-1、lcredit=-1,强制密码至少包含大小写字母、数字和特殊字符。PAM模块在/etc/pam.d/system-auth和password-auth中增加remember=5防止重复使用旧密码。账户锁定策略用pam_faillock,连续失败5次锁定600秒,防止暴力破解。

3. SSH服务深度加固

SSH是公网暴露面最大的入口,除了改端口和禁root,还需要做协议级限制。编辑/etc/ssh/sshd_config,设置Protocol 2、MaxAuthTries 3、LoginGraceTime 30、ClientAliveInterval 300、ClientAliveCountMax 0。禁用空密码和弱加密算法,Ciphers指定aes256-gcm@openssh.com,aes128-gcm@openssh.com,MACs指定hmac-sha2-256,hmac-sha2-512,KexAlgorithms指定curve25519-sha256。HostKey只保留Ed25519和RSA 4096,删除DSA和ECDSA小位数密钥。X11Forwarding no、AllowTcpForwarding no可以阻断端口转发隧道。如果业务允许,使用密钥登录并设置PasswordAuthentication no,私钥必须加passphrase保护。重启sshd前用sshd -t检查配置语法。

4. 防火墙策略从默认拒绝开始

firewalld或iptables的第一条规则必须是拒绝所有入站,然后按业务端口逐个放行。firewall-cmd --set-default-zone=drop,再添加需要的服务:firewall-cmd --permanent --add-service=ssh --zone=work,或者直接放行特定端口和源IP。出站流量同样需要限制,防止服务器被入侵后反向连接外网下载恶意工具。用firewall-cmd --direct --add-rule ipv4 filter OUTPUT 0 -p tcp --dport 80 -j ACCEPT这种方式只允许必要的出站端口。对公网开放的端口越少越好,数据库端口3306、6379、27017严禁直接对公网监听,必须绑定到127.0.0.1或内网网卡。定期用ss -tlnp检查监听端口,发现异常立即排查。

5. 文件系统权限与关键文件加锁

对/bin、/sbin、/usr/bin、/usr/sbin等系统二进制目录设置不可更改属性,防止攻击者替换命令:chattr +i /bin/ls /bin/ps /bin/netstat /usr/bin/top。对/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow设置chattr +i,需要修改账户时先chattr -i再操作。对/tmp目录设置noexec、nosuid、nodev挂载选项,防止攻击者在临时目录执行恶意脚本。检查全局可写目录find / -type d -perm -0002,对不需要的目录移除写权限。SUID和SGID文件是提权重灾区,用find / -perm -4000 -o -perm -2000列出所有特殊权限文件,只保留/usr/bin/passwd、/usr/bin/sudo等必要项,其余全部chmod -s。

6. 日志审计与实时监控

日志是发现入侵痕迹的唯一依据,先确认rsyslog或systemd-journald正常运行,然后配置/etc/rsyslog.conf将authpriv、kern、cron等日志发送到独立目录,并设置日志轮转防止磁盘写满。关键日志文件/var/log/secure、/var/log/messages、/var/log/audit/audit.log设置chattr +a只允许追加,防止攻击者清除痕迹。安装auditd并配置审计规则,对/etc/passwd、/etc/shadow、/etc/ssh/sshd_config的写入操作、对/bin、/sbin的修改操作、对所有sudo命令执行都记录审计日志。auditctl -w /etc/passwd -p wa -k passwd_changes,auditctl -w /etc/ssh/sshd_config -p wa -k sshd_config_changes。同时部署ossec或wazuh这类HIDS,实时监控文件完整性变化和异常登录行为。

7. 服务与进程最小化

用systemctl list-unit-files --state=enabled查看所有开机自启服务,停用不需要的:systemctl disable bluetooth.service cups.service avahi-daemon.service postfix.service。对必须运行的服务,检查其运行用户和权限。Web服务不要用root运行,Nginx配置user nginx,Apache配置User apache。PHP-FPM的listen.owner和listen.group设置为nginx,避免使用666权限的socket文件。数据库服务禁止以root运行,MySQL/MariaDB使用mysql用户,MongoDB使用mongod用户。对每个对外服务设置资源限制,在systemd unit文件中添加MemoryMax、CPUQuota、TasksMax,防止单个服务被攻击后拖垮整机。

8. SELinux强制模式落地

很多运维因为业务报错直接setenforce 0关闭SELinux,这等于放弃了内核级强制访问控制。正确做法是保持Enforcing模式,用audit2why分析拒绝日志,再用semanage和setsebool调整策略。Web目录需要httpd_sys_content_t标签,上传目录需要httpd_sys_rw_content_t,PHP写文件需要httpd_unified布尔值开启。数据库数据目录需要mysqld_db_t标签,SSH改端口需要semanage port -a -t ssh_port_t -p tcp 2222。如果业务确实无法在Enforcing下运行,至少使用Permissive模式收集日志,而不是完全关闭。检查当前状态用getenforce,永久修改在/etc/selinux/config中设置SELINUX=enforcing。

9. 内核参数网络层加固

编辑/etc/sysctl.conf或/etc/sysctl.d/99-security.conf,开启SYN洪水防护:net.ipv4.tcp_syncookies=1,net.ipv4.tcp_max_syn_backlog=2048。关闭IP源路由防止欺骗:net.ipv4.conf.all.accept_source_route=0,net.ipv4.conf.default.accept_source_route=0。开启反向路径过滤:net.ipv4.conf.all.rp_filter=1,net.ipv4.conf.default.rp_filter=1。禁止ICMP重定向:net.ipv4.conf.all.accept_redirects=0,net.ipv4.conf.all.send_redirects=0。记录可疑包:net.ipv4.conf.all.log_martians=1。限制core dump防止敏感信息泄露:fs.suid_dumpable=0,kernel.core_uses_pid=1。修改后执行sysctl -p生效。

10. 定时任务与启动项排查

攻击者获取权限后最常见的持久化手段就是写入crontab或启动脚本。检查/etc/crontab、/etc/cron.d/、/var/spool/cron/下所有文件,用crontab -l查看当前用户任务,用ls -la /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/检查系统级定时任务。启动项检查systemctl list-unit-files --type=service --state=enabled,以及/etc/rc.d/rc.local、/etc/profile.d/、~/.bashrc、~/.bash_profile中是否有可疑命令。对每个定时任务和启动脚本,确认其指向的可执行文件路径、文件所有者和修改时间,发现异常立即隔离并分析。

11. 数据库与Web应用层加固

数据库即使只监听内网,也需要设置强密码、删除匿名用户、移除测试数据库。MySQL执行mysql_secure_installation,然后手动执行DELETE FROM mysql.user WHERE User='',DROP DATABASE IF EXISTS test,FLUSH PRIVILEGES。限制root只能从localhost登录,业务账号按最小权限分配,禁止使用GRANT ALL ON *.*。Web应用检查配置文件中的数据库密码是否明文存储,使用环境变量或独立权限600的配置文件。对上传目录禁止执行脚本,Nginx配置location ~* \.(php|pl|py|jsp|sh|cgi)$ { deny all; }。对管理后台路径加访问控制和IP白名单,防止暴力破解后台密码。

12. 备份与应急响应准备

加固的最后一步是做好最坏打算。关键配置文件和数据库至少每天备份一次,备份文件加密后传输到独立存储,不要和源数据放在同一台服务器。备份恢复流程必须定期演练,确认备份可用。准备应急响应脚本,包含收集系统信息、网络连接、进程列表、登录日志、最近修改文件的命令集合。建立变更管理流程,所有系统修改记录在案,出现异常时可以快速定位变更点。定期进行安全扫描,使用OpenVAS或Nessus对公网IP做漏洞扫描,使用Lynis做本地安全审计,根据报告持续改进。

CentOS安全加固不是一次性的项目,而是持续的过程。每次业务变更、每次系统更新、每次新增服务,都需要重新评估安全策略。把上述步骤写成标准化脚本和检查清单,纳入新服务器上线流程,才能让每一台CentOS从出生就处于受控状态。