客户在广东广州市天河区做跨境电商独立站,主要卖电子产品配件,每天正常访客大概两千人左右。那天下午三点,客户在微信上连续发了好几条消息:”网站打不开了,怎么刷新都是超时。”
登录服务器,iftop一看,入站流量达到了800多Mbps,正常情况这个服务器带宽只有50M,瞬间被灌满了。再查看nginx日志,每秒请求数从平时的几十跳到了两万多,所有请求的URL都是随机生成的,类似/abc123、/xyz789,服务器根本处理不过来,直接拒绝服务了。
初步判断和应急处理
这种情况明显是流量攻击,目的就是耗尽服务器资源,让正常用户无法访问。
先把nginx的访问日志快速翻了一下,攻击来源IP非常分散,看不出明显的集中段,基本上每个IP只发几个请求就换下一个,说明是僵尸网络在攻击,手动封IP根本封不完。
第一件事是在宝塔面板的Nginx防火墙里把CC防御等级调到最高,启用”人机验证”模式。这个模式会对每个新访问者弹出一次验证,通过之后才能正常访问,挡掉了一部分脚本请求。但作用有限,因为攻击流量太大了,防火墙本身处理不过来。
第二层防护
在阿里云控制台上把服务器的带宽临时提升到了500M,同时启用了云盾的基础防护。发现云盾已经识别到异常流量,自动触发了清洗机制。
然后联系机房,把攻击流量牵引到高防IP上。客户没有提前买高防服务,只能走应急流程开通了一个按量付费的高防IP,把域名解析切到高防IP上。高防机房在山东济南,国内三大运营商都有接入,清洗完再回源到上海的服务器。
这个过程用了大概二十分钟。高防IP生效之后,攻击流量被拦截在了高防机房,回源到服务器的请求量降到了正常水平,网站恢复访问。
攻击结束后的分析
攻击持续了将近两个小时,总流量消耗了好几百G,在阿里云控制台上能看到详尽的流量走势图。攻击来源IP大部分来自境外,以欧美为主,也有少量东南亚IP。从攻击手法来看,不是针对特定URL的CC攻击,而是随机路径的流量型攻击,目的就是消耗带宽。
客户的网站用的是Nginx+WordPress,本身服务器配置并不高,2核4G,正常业务够用,但这种规模的攻击根本扛不住。如果提前配了高防IP,攻击发生的时候直接切换解析,影响会小很多。
给客户的建议
攻击停了之后跟客户讨论了三个方案:
第一个方案是更换服务器IP,然后隐藏真实IP。攻击者知道现在的服务器IP,随时可能卷土重来。换了IP之后所有流量先经过高防IP再转发到服务器,对外只暴露高防IP,服务器真实IP不再公开。缺点是如果网站代码里有一些对外暴露IP的接口,可能还会被发现。
第二个方案是把网站迁移到支持高防的机房,比如阿里云BGP高防机房或者腾讯云高防专区。这种方案不需要额外配置,购买高防实例之后直接把服务器部署在高防机房内部,天然防护。缺点是成本比普通服务器高不少。
第三个方案是接入Cloudflare或者国内类似的全站加速服务,流量经过中间层清洗之后再回源。优点是不用换服务器,配置简单,缺点是需要DNS走境外或者走特定线路,跨境延迟不稳定。
客户选择了第一个方案,先换IP,同时长期采购一个高防IP服务。每年这部分费用大概三四千块钱,他看了之后说可以接受,毕竟网站一旦被攻击打不开,损失的一天销售额也不止这个数。
顺手处理的问题
换IP的过程中,顺手做了一件事:检查了MySQL的连接数配置。攻击的时候MySQL的连接数被大量占用,虽然攻击目标是Web端口,但间接拖慢了数据库响应。
把max_connections从默认的151调整到了300,并且开启了wait_timeout短连接回收,避免被占满之后正常请求也进不来。
还检查了PHP-FPM进程池的pm.max_children配置,从50调到了80。客户说攻击当天PHP报错”connection refused”,就是因为进程池满了来不及释放。
客户那边的情况
后来跟客户聊天,他说之前就听说过同行被DDoS攻击,没想到自己会碰上。这个站做了两年多,目前月销售额稳定在七八十万,攻击当天下午确实影响了不少订单,客户打不开页面就直接去别家买了。
他问了一句:”有没有办法让对方打不过来?”我说从技术上可以做到一定程度的防护,但无法完全杜绝。高防能清洗大部分流量,但如果攻击规模特别大,比如达到T级别,那就要看高防服务的上限在哪里了。目前他选的这个套餐峰值防护是几十G,对于跨境电商独立站来说基本够用。
一点总结
小规模攻击靠服务器自身的防火墙和Nginx限流可以挡一挡,稍微大一点就得依赖机房层面的防护了。提前买高防IP就像买保险,平时用不上,真出事的时候能救命。如果业务对在线时长要求比较高,提前部署好高防方案比出事再来处理要划算得多。
