一个简单的密码引发的血案
作者:(sery@163.com田义)
我正想搬砖,一个急促的电话提醒我,同事紧急告诉我,论坛访问很慢,其他技术人员折腾了半天也找不到原因,需要尽快处理。
首先简单了解一下一些情况。我的运营同事说前几天管理员账号被泄露了(怎么?设置一个简单的密码,就像拿后备箱里的砖头拍他一样),用工具自动贴。好家伙,我一晚上发了几万条帖子。早上看他们在qq群里聊天,说删这些垃圾帖子花了不少时间。论坛的discuz程序没有做任何改动,疑似恶意***。很长一段时间没去论坛,没时间详细了解情况。我卷起袖子,开始了。
登录系统前,查阅资料确认整个论坛的逻辑拓扑,如下图所示:
注:图中省略了管理网络(服务器由***)管理。
按照这个拓扑,一步一步的检查调试。具体步骤是:
(1)检查负载平衡器。
1.检查系统负载和内存使用情况:输出显示正常;
2.检查disk空的使用情况,没有发现有分区被填充;
3.检查系统日志,输出异常结果;
4.检查应用程序的运行状态,并执行命令ipvsadmin。有转发号且号码不断变化,可以确认应用keepalived和lvs正常。
从以上几点可以确定负载均衡没有问题。通过模拟故障转移,用户的请求可以自动切换到辅助负载平衡器。
(2)检查应用服务器。
1.查了几台服务器的负载,负载值几十,严重超标;
2.检查磁盘空的使用情况,找到使用率超过80%的分区;
3.看系统日志,没有文件系统损坏、内核异常等问题。
4.检查内存使用情况,没有发现占用交换分区的内存耗尽情况;
5.检查应用程序php和nginx。nginx没有异常,php偶尔有日志输出慢的情况;
最初,php导致了异常负载。当php关闭一会儿,系统负载迅速下降到正常水平。怀疑是恶意***,通过检查tcp状态,没有什么有价值的线索。
如果是***,同一个ip的tcp连接数大概应该是一个比较大的值。一般体验都是几万级别。尝试用iptables禁用几个连接比较多的源ip,效果不明显,负载还是很大。关掉php,降低负载,重启,负载又迅速爬上来。看来问题还不在这里。
(3)检查与应用服务器密切相关的文件服务器。
论坛程序通过nfs与多个应用服务器共享,以减少服务器之间的数据同步。如果不是共享的,每个应用服务器应该保存一个相同的数据文件。因为有些数据文件会随着时间不断变化,为了保证用户访问的一致性,需要实时同步这些更新的数据。
1.检查系统负载和内存使用情况,发现一切正常;
2.检查磁盘空的使用情况,没有发现被阻塞的分区;
3.查看系统日志,未发现异常输出;
4.检查nfs相关流程和配置,未发现异常;
以前出现论坛访问异常,是因为共享文件系统(nfs)分区的文件系统损坏,导致nfs客户端(即php应用服务器)无法写入缓存。为了证实这个猜测,文件服务器和客户端都经过了创建和删除文件的测试,一切正常。
(4)检查缓存服务器。
用于数据缓存的应用程序是memcached,这是一个服务器系统。它只运行这样的应用程序。因为内存存储数据,一般情况下怀疑有故障。只需重启memcached,让它再次缓存。
1.检查系统负载和内存使用情况,一切正常;
2.查系统日志,没有异常;
3.检查网络状态,这也是正常的;
重启memcached对应用服务器的负载没有帮助。看来问题也不在这里。
(5)检查数据库服务器。
只剩下它了,问题显然与此有关。吸一口雾霾空气,登录主数据库和从数据库服务器系统,进行以下常规调查。
1.检查系统负载和内存使用情况,一切正常;
2.检查disk空的使用情况,没有发现磁盘分区被填满;
3.查看系统日志,未发现异常输出;
4.检查网络连接。主服务器的连接数很小,而从服务器的连接数很大。至少说明在系统层面上,主数据库服务器是正常的,从服务器系统在系统层面上基本被认为是正常的。
本集群使用的论坛程序Discuz支持数据库读写分离,所以主服务器负责数据更新,而处于只读状态的从服务器(slave)负责查询。首先,我们检查主服务器的应用程序级别,步骤如下:
(1)、检查mysql的错误日志和全查询日志,输出一个异常结果;
(2)检查mysql进程是否正常,执行mysql–P登录,可以进入MySQL客户端命令行,守护进程正常;
(mysql客户端执行命令showfullprocesslist输出几行,一切都在可以接受的范围内;
因此,可以判断数据库主服务器没有异常。
现在山穷水尽,水落石出,问题多是来自数据库服务器的这个问题。检查系统级别,寻找有用的线索。查看mysql错误日志,未发现异常;查看mysql的慢速查询日志,果然有输出,而且不断有新的输出。
一个sql语句这么长,篇幅有限,不打算全文输出截图。登录mysql客户端,执行showfullprocesslist天啊,我花了很长时间才完成输出。线程数超过1000(我设置的mysql连接数上限是1000),输出内容大部分是慢速查询。使用mysql-p-e"显示进程列表列表;">/root/sql_out把这些sql形成一个文本文件,转发给程序员。他们看了很久,没有得出结论。有人建议把异常的sql语句杀了,杀了之后还是不行。人家还是怀疑自己是***,通过dns把请求定向到360,起到一定的过滤***。从监控会上看,确实有cc***被拦截的结果。但对应用服务器的减负没有任何作用,论坛依然处于无法打开的状态。
用超级系统管理员的账号登录论坛后台,关闭论坛后,服务器负载会立即恢复正常水平;再打开论坛,马上负载飙升。真是个错误!技术层面的问题我查不出来。折腾了一天,头都大了。在qq群里喊了几句:“谁改的程序?谁在后台做什么设置?......",有人说:“删除垃圾帖子时,为了快速删除,设置了页面显示的帖子数量”。
数学是我政治老师教的。我想不出当多个版块被多人访问时应该显示多少条记录,但大家都相信这一定是一个恐怖的数字。
发现问题,意识到问题的严重性。
在论坛后台更改此设置。几秒钟后,应用服务器的负载下降,来自数据库的连接数趋于正常。论坛也可以像以前一样浏览和发布...
这一切,说回来,就是一些论坛管理员设置了该死的简单密码。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)