CentOS服务器要搭建高防环境,核心不是装某个“神奇软件”,而是从系统内核、网络层、访问控制、服务隔离到监控响应做一整套收紧动作。很多人以为高防就是买个大带宽或者套个CDN,实际上服务器本身的配置如果松散,流量打进来后业务照样秒挂,甚至不用大流量,几万条恶意连接就能耗尽资源。下面直接讲具体做法。
内核参数先做抗压调优
CentOS默认的内核参数偏向通用场景,面对SYN Flood、CC攻击或者大量并发连接时,很容易出现半连接队列溢出、TIME_WAIT堆积、文件句柄耗尽。首先要调整的是TCP层面的参数。编辑/etc/sysctl.conf,加入以下配置:
net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_fin_timeout = 15 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 0 net.ipv4.tcp_max_tw_buckets = 1440000 net.ipv4.ip_local_port_range = 1024 65535 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 3 net.core.somaxconn = 65535 net.core.netdev_max_backlog = 65535 net.ipv4.tcp_max_orphans = 65535 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 fs.file-max = 6553500 net.ipv4.ip_forward = 0
保存后执行sysctl -p让配置生效。这里特别要注意tcp_tw_recycle在CentOS 7以上内核中已经废弃,强行开启会导致NAT环境下连接异常,所以设为0。syncookies开启后可以防止SYN半连接占满队列,但会消耗一定CPU,高防场景下这点开销必须接受。文件句柄上限要同步调整/etc/security/limits.conf,给业务运行用户设置nofile至少65535,否则内核放开了但用户态进程还是会被限制。
防火墙策略必须精细化
CentOS 7及以上默认使用firewalld,但高防环境建议直接使用iptables或者nftables,因为规则更直观、匹配效率更高,也方便做自定义链和限速。先关闭firewalld:
systemctl stop firewalld systemctl disable firewalld yum install iptables-services -y systemctl enable iptables
基础策略上,默认拒绝所有入站,只放行业务端口和管理端口。不要用“先全开后封”的思路,那样漏掉一条规则就是灾难。示例:
iptables -F iptables -X iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT service iptables save
如果SSH端口改过,就放行改后的端口。管理端口最好再叠加来源IP白名单,比如只允许公司出口IP访问22端口,其他一律DROP。对于业务端口,可以加连接数限制和新建连接速率限制,防止单IP占满资源:
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 --connlimit-mask 32 -j DROP iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 50 --connlimit-mask 32 -j DROP iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/s --limit-burst 200 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -m limit --limit 100/s --limit-burst 200 -j ACCEPT
connlimit模块在部分CentOS内核中需要额外加载,如果报错就检查内核模块。限速规则要放在ACCEPT之前,否则先匹配到放行规则就失效了。另外对于UDP类服务,如果没有业务需求,直接全DROP,不要留任何UDP端口对外开放。
SSH登录安全是最后一道门
高防服务器被攻破最常见的原因不是流量打挂,而是SSH弱口令被爆破。必须做几件事:第一,禁用root直接登录,创建普通用户再su切换;第二,改用密钥登录,禁止密码认证;第三,修改默认22端口;第四,安装fail2ban自动封禁爆破IP。修改/etc/ssh/sshd_config:
Port 22022 PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AllowUsers youruser MaxAuthTries 3 LoginGraceTime 30 ClientAliveInterval 60 ClientAliveCountMax 3
重启sshd服务后,务必保留一个当前会话不要断开,防止配置错误把自己锁在外面。fail2ban安装后配置jail.local,监控sshd日志,连续失败5次就封禁24小时:
[sshd] enabled = true port = 22022 filter = sshd logpath = /var/log/secure maxretry = 5 bantime = 86400 findtime = 600
这样即使有人扫到端口,尝试几次后IP就被封,爆破成本大幅提高。
Web服务层的高防配置
如果是Nginx作为Web服务器,高防配置的重点是限制请求速率、限制并发连接、过滤恶意User-Agent、关闭版本号泄露。在http段加入:
limit_req_zone $binary_remote_addr zone=req_per_ip:20m rate=30r/s; limit_conn_zone $binary_remote_addr zone=conn_per_ip:20m; server_tokens off; client_body_timeout 10; client_header_timeout 10; send_timeout 10; keepalive_timeout 15; large_client_header_buffers 4 16k;
然后在server段应用:
limit_req zone=req_per_ip burst=50 nodelay; limit_conn conn_per_ip 30;
rate和burst要根据业务实际调整,太严会误伤正常用户,太松又挡不住CC。对于静态资源,可以单独设置更高的速率限制,因为正常用户访问静态资源频率高。同时建议在Nginx前面加一层CDN或者高防IP,把四层流量清洗放在上游,服务器只处理干净的流量。如果预算有限,至少要把DNS解析到有基础防护的节点上。
应用层和数据库的隔离
很多服务器被打挂是因为数据库和应用放在同一台机器上,攻击流量导致应用层大量请求,数据库连接池被耗尽,整个系统崩溃。高防环境下,如果条件允许,数据库必须独立部署,并且只监听内网地址。MySQL配置中设置bind-address为内网IP,关闭外网访问。应用服务器与数据库服务器之间用内网通信,不经过公网。如果只能单机部署,至少要限制数据库连接数,并且给应用设置合理的超时时间,避免慢查询堆积。
Redis这类缓存服务同样不能暴露公网,很多入侵事件就是因为Redis无密码且绑定0.0.0.0,被写入SSH公钥或者挖矿程序。配置redis.conf:
bind 127.0.0.1 protected-mode yes requirepass yourstrongpassword rename-command CONFIG "" rename-command FLUSHALL "" rename-command FLUSHDB ""
重命名危险命令可以防止拿到权限后清库或修改配置。
系统层面的加固与审计
高防不是只防外部攻击,内部配置错误同样致命。系统装完后要做基础加固:关闭不必要的服务,比如postfix、chronyd之外的自启动项全部关掉;限制cron和at的访问权限,只允许root使用;对关键目录设置不可修改属性,比如/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow用chattr +i锁定,需要修改时再解锁。日志方面,rsyslog要配置远程日志或者至少保留本地日志半年以上,方便事后溯源。auditd可以记录关键文件的访问和修改,对/usr/bin、/etc、/var/log等目录设置审计规则。
定期检查异常连接和进程是必须的。用ss -antp查看当前连接,重点关注ESTABLISHED数量异常多的IP;用ps aux按CPU和内存排序,看有没有陌生进程;用crontab -l检查所有用户的计划任务,防止被植入持久化后门。还可以安装rkhunter或者chkrootkit做定期扫描,虽然不能百分百发现rootkit,但能多一层保障。
监控与自动响应
高防环境的最后一块拼图是监控。没有监控,被打挂了都不知道什么时候开始的。至少要做三件事:第一,用Zabbix或者Prometheus监控CPU、内存、网络流量、连接数、磁盘IO,设置阈值告警;第二,写一个简单的脚本,每分钟检查Nginx错误日志和系统日志,发现异常IP自动加入iptables黑名单;第三,对业务做健康检查,比如每30秒请求一次首页,如果连续失败就自动重启服务或者切换备用节点。
自动封禁脚本的思路很简单,解析Nginx access log,统计每个IP在最近一分钟的请求次数,超过阈值就加入黑名单:
#!/bin/bash
tail -n 10000 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | while read count ip; do
if [ "$count" -gt 200 ]; then
iptables -A INPUT -s "$ip" -j DROP
echo "$(date) blocked $ip with $count requests" >> /var/log/block_ip.log
fi
done
这个脚本可以放在crontab里每分钟执行一次,但要注意别把搜索引擎蜘蛛或者CDN回源IP误封了,最好先维护一个白名单文件,脚本里跳过白名单IP。
CentOS高防环境的搭建本质上是把每一个可能被攻击的入口都收紧,从内核参数到防火墙,从SSH到Web服务,从数据库到监控响应,每一层都要有明确的限制和兜底策略。没有单点方案能解决所有问题,但把这些配置都落实后,服务器面对常见攻击时的存活能力会提升一个量级。
