网站管理整改措施

上周三凌晨两点,网站我收到运维告警:主站首页被篡改,管理跳转到了一个博彩页面。整改登录服务器一看,措施web目录下多了三个PHP文件,网站修改时间集中在凌晨1点47分。管理这不是整改第一次了——三个月前发生过一次类似情况,当时只做了应急清理,措施没动根子上的网站问题。这次我决定把整改措施彻底落实下去,管理下面就是整改具体做法。

一、措施先把入口堵死

服务器上跑着五个站点,网站其中三个用的管理是同一套老版CMS。版本号我都不好意思说,整改还是2019年的。这次被篡改的正是其中一个。我做的第一件事是登录后台,把能关的功能全关了——文件上传、在线编辑、数据库备份导出,这些平时用不上的全禁掉。后台登录地址从/admin改成了一个随机字符串,长度16位,大小写加数字。登录失败次数限制从5次降到3次,超过就锁IP半小时。

数据库账号权限也收紧了。之前图省事,所有站点共用一个MySQL账号,权限是ALL。现在每个站点独立账号,只给SELECT、INSERT、UPDATE、DELETE,DROP和FILE权限全部收回。改完这些,我顺手查了一下访问日志,发现攻击者是从一个废弃的插件入口进来的——那个插件目录还在,但代码已经两年没更新了。直接删掉整个目录,不留后患。

二、文件监控不能只靠人眼

第一次被黑的时候,我是靠用户反馈才知道的。这次我装了个轻量级的文件完整性监控工具,AIDE。配置很简单,把web目录、配置文件目录、计划任务目录都加进去,每天凌晨三点跑一次校验。一旦有文件被修改或新增,第二天早上我就能收到邮件报告。上周的告警就是AIDE先发现的——比用户反馈早了六个小时。

另外,我把所有PHP文件里常见的后门特征字符串提取出来,写了个shell脚本,每小时扫一遍。比如eval($_POST、base64_decode、system(这些。误报肯定有,但总比漏报强。脚本跑了一周,抓到了两个可疑文件,其中一个确实是webshell,另一个是开发留下的调试代码——已经让开发删了。

三、备份策略得改改了

之前的备份是每天凌晨四点全量打包,存到同一台服务器的/backup目录下。这等于把鸡蛋放在同一个篮子里——服务器被拿下,备份也跟着完蛋。现在改成:本地保留最近三天的增量备份,远程用rsync同步到另一台机房的一台独立存储服务器上,走内网专线,端口非标准。远程备份保留最近14天,每周日做一次全量归档,刻到移动硬盘里锁柜子。

恢复流程我也实际演练了一次。从远程拉回备份、解压、导入数据库、切换DNS,整个流程花了23分钟。这个时间可以接受,但还有优化空间——数据库导入那步太慢,后面考虑用xtrabackup做物理备份。

四、日志和告警要能看懂

服务器上原来开着Nginx的access log和error log,但从来没看过。这次我把日志接入了GoAccess,生成实时HTML报表,每小时刷新一次。重点关注几个指标:404错误突增、同一IP的POST请求频率、User-Agent里带sqlmap或nikto的请求。阈值设得比较低,宁可多收几条告警,也不想再漏掉异常。

告警通道从邮件改成了钉钉机器人加短信。邮件经常被忽略,钉钉群里有运维、开发和主管,谁看到谁处理。短信只发给两个人——我和运维主管,用于夜间紧急告警。上周那次篡改,钉钉告警在1点52分发出,我2点05分登录服务器,比上次快了将近四十分钟。

整改到现在两周多,没再出现新的入侵迹象。但我知道这事没完——攻击者也在进化。下一步打算把WAF上起来,目前在看ModSecurity和雷池,还没定。另外准备把PHP版本从7.2升到8.1,老版本漏洞太多,补丁都停更了。这些做完再写一篇记录。