如何调优Virtualmin部署的高流量网站并抵御DoS攻击?
如何调优Virtualmin部署的高流量网站并抵御DoS攻击?
兄弟,这种情况真的太闹心了——就这么个简单的循环脚本就能把你的8GB Xeon机器搞垮,肯定是防护和配置的环节没跟上。咱们一步步来梳理,从最外层的Cloudflare到内部的Nginx、PHP-FPM,把漏洞补上:
先把Cloudflare的前端防护拉满
你已经在用Cloudflare了,这可是抵御这类简单DoS的第一道防线,得把它的功能用透:
- 开启Rate Limiting(速率限制):这是核心!针对单IP设置请求频率上限,比如单IP每分钟最多60次请求(根据你的正常访问量调整),超过就临时封禁10分钟。甚至可以单独对根路径
/设置更严格的限制,毕竟攻击就是冲着这个来的。 - 启用Bot Management(机器人管理):免费版就有基础的检测能力,能识别这种脚本发起的自动化请求,直接拦截或者弹出验证码挑战,把恶意请求挡在门外。
- 紧急情况开Under Attack Mode(攻击模式):如果攻击正在进行,一键开启这个模式,Cloudflare会先给所有访问者加个验证页面,过滤掉绝大多数自动化请求,给你争取调整时间。
Nginx层面再加一层拦截
Cloudflare之后就是Nginx,这里可以再加一层本地防护,避免漏网的请求打到后端:
- 配置请求频率限制:用Nginx的
limit_req_zone模块,先在http块里定义规则:
然后在你的网站limit_req_zone $http_cf_connecting_ip zone=req_limit:10m rate=60r/m;server块里应用规则:
这里用limit_req zone=req_limit burst=10 nodelay;$http_cf_connecting_ip是因为Nginx拿到的是Cloudflare的IP,这个变量能获取真实访客IP。规则意思是单IP每分钟最多60次请求,允许10次突发请求,超过直接返回503。 - 限制并发连接数:用
limit_conn_zone防止单个用户占满连接:
这样单IP最多只能同时建立10个连接,避免一个脚本占满所有连接资源。# 在http块添加 limit_conn_zone $http_cf_connecting_ip zone=conn_limit:10m; # 在server块添加 limit_conn conn_limit 10; - 禁用不必要的HTTP方法:只保留常用的GET、POST、HEAD,其他方法直接拒绝:
if ($request_method !~ ^(GET|POST|HEAD)$ ) { return 403; }
优化PHP-FPM配置避免资源耗尽
你当前的PHP-FPM配置其实有隐患:pm.max_children=50,每个进程memory_limit=128M,50*128=6400M,接近8G内存,一旦请求量上来,系统会开始用swap,性能直接暴跌。调整建议:
- 降低pm.max_children:计算可用内存,比如系统+MariaDB占用3G,剩下5G,5120/128=40,所以设成35-40比较合适,留些余量给系统和其他进程。
- 开启慢请求日志:找到PHP-FPM配置里的
slowlog和request_slowlog_timeout,比如:
这样能记录处理时间超过5秒的请求,看看是不是首页的PHP逻辑有性能瓶颈,被攻击放大了影响。slowlog = /var/log/php-fpm/slow.log request_slowlog_timeout = 5s - 启用进程闲置超时:static模式下默认
pm.process_idle_timeout=0(不关闭闲置进程),改成10s,让闲置进程自动退出,节省资源:pm.process_idle_timeout = 10s
应用层缓存与防护补漏
从代码和缓存层面减少后端压力:
- 缓存首页静态内容:把
/的响应缓存到Nginx,不用每次都去请求PHP-FPM和数据库。配置示例:
这样首页请求会被缓存60分钟,攻击请求直接命中缓存,不会打到后端。# 在http块添加缓存路径 proxy_cache_path /var/cache/nginx/home_cache levels=1:2 keys_zone=home_cache:10m max_size=10g inactive=60m use_temp_path=off; # 在server块的location /里添加 proxy_cache home_cache; proxy_cache_valid 200 60m; proxy_cache_key "$host$request_uri$cookie_session"; - 简单的请求验证(可选):如果允许改代码,可以给首页请求加个简单的验证,比如检查请求头里的自定义标识,或者给合法用户的cookie加个校验,过滤掉无标识的脚本请求。
MariaDB的针对性优化
你说加RAM没用,可能是缓存配置没到位:
- 调整InnoDB缓冲池大小:
innodb_buffer_pool_size设成4G左右(8G机器的一半),这样绝大多数数据库数据都能存在内存里,减少磁盘IO,避免大量请求拖垮数据库。 - 开启慢查询日志:记录执行时间超过2秒的查询,看看首页的数据库查询是不是没加索引,导致每次请求都要全表扫描,被攻击时放大了压力。
按照这个顺序调整,先搞Cloudflare和Nginx的前端防护,这是最快见效的,再一步步优化后端,应该就能抵御这种简单的DoS攻击了!
备注:内容来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

