CentOS服务器上线后默认配置离安全标准差距很大,很多被入侵的案例都不是因为漏洞多高明,而是基础加固没做。下面直接按操作顺序讲一套完整的加固流程,从登录、账户、防火墙、内核参数到审计和文件完整性,每一步都给出可直接执行的命令和判断标准。

1. 先处理SSH登录暴露面

默认22端口、允许root密码登录,是扫描器最喜欢的目标。第一件事是修改SSH配置,不要只改端口,要同时限制登录方式和来源IP。编辑/etc/ssh/sshd_config,至少调整以下参数:

Port 22022
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers deploy
MaxAuthTries 3
LoginGraceTime 20
ClientAliveInterval 300
ClientAliveCountMax 2

Port不要用2222这类常见高位端口,选一个业务环境不冲突的端口。PermitRootLogin直接设为no,日常操作全部通过普通用户sudo完成。如果确实有自动化脚本需要root权限,用sudoers里限定命令的方式解决,不要开放root登录。PasswordAuthentication设为no之前,必须确认公钥已经写入对应用户的~/.ssh/authorized_keys,并且权限正确:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

改完执行sshd -t检查配置语法,再systemctl restart sshd。不要急着断开当前会话,另开一个终端测试新端口和密钥登录是否正常,确认无误后再关闭旧会话。如果服务器在云平台,安全组或防火墙规则要同步放行新端口,否则重启后可能直接失联。

2. 账户与权限基线

CentOS默认会有一些系统账户,但真正需要登录的账户应该极少。用awk -F: '$3==0{print $1}' /etc/passwd检查UID为0的账户,正常情况下应该只有root。再用awk -F: '($2==""){print $1}' /etc/shadow检查是否存在空口令账户,任何输出都不应出现。对于长期不登录的账户,直接锁定:

usermod -L 用户名
chage -E 0 用户名

sudo权限要按最小化原则分配。不要直接给用户ALL=(ALL) ALL,而是按需配置。例如只允许deploy用户重启nginx:

deploy ALL=(root) /usr/bin/systemctl restart nginx

同时设置sudo日志记录,在/etc/sudoers中加入Defaults logfile="/var/log/sudo.log",所有sudo操作都会留痕。密码策略方面,修改/etc/login.defs中的PASS_MAX_DAYS为90,PASS_MIN_DAYS为7,PASS_WARN_AGE为14。对于已有账户,用chage命令逐个调整。如果系统支持PAM,在/etc/security/pwquality.conf中设置密码复杂度:minlen=12,minclass=3,拒绝连续重复字符。

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

CentOS 7和8默认的firewalld比iptables更易管理,但很多人只加放行规则,不调整默认区域策略。正确做法是把默认区域改为drop,然后只放行明确需要的端口:

firewall-cmd --set-default-zone=drop
firewall-cmd --permanent --zone=drop --add-port=22022/tcp
firewall-cmd --permanent --zone=drop --add-port=80/tcp
firewall-cmd --permanent --zone=drop --add-port=443/tcp
firewall-cmd --reload

如果服务器只对特定IP开放SSH,不要用端口放行,而是用rich rule绑定来源IP:

firewall-cmd --permanent --zone=drop --add-rich-rule='rule family="ipv4" source address="203.0.113.5" port port="22022" protocol="tcp" accept'

这样即使端口被扫描到,非授权来源也无法建立连接。对于数据库端口如3306、6379,除非有明确的外部访问需求,否则一律不开放。内部服务之间的通信走内网网卡,firewalld可以针对不同网卡绑定不同zone,外网网卡drop,内网网卡trusted或work,避免内网服务暴露到公网。

4. 内核参数与网络层加固

系统默认的内核参数对服务器场景不够严格,尤其是SYN洪水、ICMP重定向和IP转发。编辑/etc/sysctl.conf或/etc/sysctl.d/99-security.conf,加入以下内容:

net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 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
net.ipv4.icmp_echo_ignore_all = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.log_martians = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 2

icmp_echo_ignore_all设为1会让服务器不响应ping,这能减少一部分扫描器探测,但也会影响监控系统。如果监控依赖ping,可以保持为0,但icmp_echo_ignore_broadcasts必须设为1。执行sysctl -p让配置生效。rp_filter开启严格反向路径过滤,能有效防止IP欺骗。log_martians记录源地址不合法的数据包,方便事后排查。

5. 服务最小化与开机自启管理

用systemctl list-unit-files --type=service --state=enabled查看所有开机自启服务,逐个确认是否必要。常见的可以关闭的服务包括:postfix(如果不用本地邮件发送)、chronyd(如果不用NTP同步可换用其他方案)、avahi-daemon、cups、rpcbind。关闭命令:

systemctl disable --now postfix
systemctl disable --now avahi-daemon
systemctl disable --now cups
systemctl disable --now rpcbind

对于必须运行的服务,检查其监听地址。用ss -tlnp查看所有TCP监听,如果某个服务监听0.0.0.0但只需要本机访问,就修改服务配置绑定127.0.0.1。例如Redis默认bind 127.0.0.1但很多教程让改成了0.0.0.0,这是非常危险的做法。MySQL如果只被本机应用调用,在my.cnf中设置bind-address=127.0.0.1,不要开放3306到公网。

6. 系统更新与自动安全补丁

CentOS 7已经停止维护,CentOS 8也提前停止维护,还在用这两个版本的系统必须尽快迁移到CentOS Stream、Rocky Linux或AlmaLinux。如果暂时无法迁移,至少保证yum源可用,并定期执行yum update --security只更新安全补丁。安装yum-cron实现自动安全更新:

yum install -y yum-cron
systemctl enable --now yum-cron

编辑/etc/yum/yum-cron.conf,设置update_cmd为security,apply_updates为yes,这样系统会自动安装安全更新,但不会安装功能更新。对于生产环境,自动更新有风险,建议先在测试环境验证,或者只开启自动下载不自动安装,由人工在维护窗口执行更新。

7. 日志审计与登录告警

默认rsyslog会记录系统日志,但不会记录所有登录尝试的详细信息。安装并配置auditd,对关键文件和系统调用进行审计:

yum install -y audit
systemctl enable --now auditd

在/etc/audit/rules.d/audit.rules中加入以下规则,监控账户、权限和关键文件变更:

-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k sshd
-w /var/log/secure -p wa -k auth_log
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_cmd

重启auditd后,用ausearch -k identity查看相关事件。对于登录失败,/var/log/secure中会有记录,可以用脚本定时分析,发现连续失败就触发告警。简单的做法是用fail2ban自动封禁暴力破解IP:

yum install -y epel-release
yum install -y fail2ban
systemctl enable --now fail2ban

在/etc/fail2ban/jail.local中配置SSH防护,bantime设为3600,maxretry设为3,findtime设为300。fail2ban会读取SSH日志,对3次失败登录的IP自动加入防火墙封禁1小时,能挡掉大部分自动化扫描。

8. 文件系统与权限加固

对关键目录和文件设置不可变属性,防止被篡改。chattr +i可以让文件即使root也无法修改,除非先去掉该属性。对/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow设置不可变:

chattr +i /etc/passwd
chattr +i /etc/shadow
chattr +i /etc/group
chattr +i /etc/gshadow

需要修改账户时先chattr -i,改完再恢复。对/tmp目录设置粘滞位和noexec,防止攻击者在临时目录执行恶意程序。如果/tmp是独立分区,在/etc/fstab中修改挂载选项为defaults,noexec,nosuid,nodev。如果不是独立分区,可以用mount --bind配合重新挂载实现,但操作复杂且容易出错,建议至少确保/tmp的权限是1777。

9. 完整性监控与入侵检测

安装AIDE对系统文件做基线快照,之后定期检查文件变化:

yum install -y aide
aide --init
cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

配置/etc/aide.conf,至少监控/etc、/bin、/sbin、/usr/bin、/usr/sbin、/var/log等目录。之后每天执行aide --check,对比文件哈希和权限变化。如果发现异常,说明可能有文件被篡改。对于更实时的检测,可以部署ossec或wazuh,但需要额外的管理端,小型环境用AIDE配合cron定时检查已经足够。

10. 备份与恢复准备

安全加固的最后一步是确保能恢复。没有备份的加固是危险的,因为一旦配置错误导致服务不可用,恢复时间会很长。至少对/etc目录、数据库和网站文件做定期备份。用tar配合cron每天备份关键配置:

tar czf /backup/etc-$(date +%F).tar.gz /etc

备份文件不要放在服务器本机,同步到对象存储或另一台服务器。同时记录所有加固操作,形成变更日志,方便排查问题时回溯。每次修改配置前先备份原文件,例如cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F),这样即使改错也能快速回滚。

这套流程执行完后,服务器的基础安全水平会明显高于默认状态。但安全不是一次性的,需要定期复查:每周检查日志、每月检查账户和权限、每季度做一次全面审计。CentOS系统本身的生命周期问题也要重视,停止维护的版本继续使用,意味着新漏洞不会有官方补丁,这是最大的风险。