Saturday, November 26, 2016

运维之简单密码引起的血案

正在努力搬砖,一阵急促的电话铃想起,同事紧急告知,论坛访问很慢,其它技术人员已经折腾了半天找不到原因,需要尽快处理。

首先简单了解了一些情况,运营的同事说前几天有管理员帐号被泄漏(咋泄漏的?设置简单密码,真像把后备箱那块砖拿过去拍他),被人用工具自动发帖,好家伙,一晚上发了上万个帖子。上午在qq群里看他们聊天,说费了很多时间才把这些垃圾帖子删掉。论坛的discuz程序没有做任何改动,怀疑是被恶意攻击。论坛不能访问已经大半天,来不及详细了解情况,挽起袖子,开干了。

再登录系统前,查阅资料确认整个论坛的逻辑拓扑,如下图所示:

 

按这个拓扑结构,逐级进行检查和排错,具体步骤为:



(一)负载均衡器进行检查
1、检查系统负载、内存使用情况:输出表明是正常的;
2、检查磁盘空间使用情况,未发现有分区被塞满;
3、检查系统日志,为发现异常输出;
4、检查应用程序运行情况,执行命令 ipvsadmin ,有转发数而且数字不断变化,这可以确认应用程序keepalived 及lvs都是正常的。
由上面几点可确定负载均衡毫无问题,模拟故障切换,用户的请求也能自动切换到辅助负载均衡器。

(二)检查应用服务器
1、查看几个服务器的负载,load值好几十,严重超标;
2、查看磁盘空间使用情况,为发现使用率大于80%的分区;
3、查看系统日志,未发现文件系统损坏,内核异常之类的问题;
4、查看内存使用情况,未发现耗尽内存而占用交换分区swap的情况;
5、检查应用程序php及nginx,nginx无异常,而php偶尔有慢日志输出;
初步判断,是php引起的负载异常。关闭php片刻,系统负载很快降到正常水平。怀疑被人恶意攻击,通过查看tcp状态,也无有价值的线索。

 

如果被攻击,同一个ip的tcp连接数应该可能是很大的一个值。一般的经历,是上千上万的水平。尝试用iptables禁掉几个连接数多的源ip,效果不明显,负载还是很高。关掉php,负载降低,再启动,负载很快又爬升起来。看来,问题还不在这里。

(三)检查与应用服务器紧密关联的文件服务器
论坛程序是以nfs的方式共享给多个应用服务器使用的,这样的目的在于减少服务器之间的数据同步,假如不以共享的形式,则每个应用服务器都应保存一份完全相同的数据文件。因为一些数据文件随时间推移会不断发生变化,那么为了保证用户访问的一致性,就必须实时同步这些更新数据。
1、  检查系统负载、内存使用情况,发现一切正常;
2、  检查磁盘空间使用情况,未发现被塞满的分区;
3、  检查系统日志,未发现异常输出;
4、  检查nfs相关进程和配置,未发现异常;
以前发生过论坛访问异常的情况,引起的原因就是共享文件系统(nfs)分区文件系统损坏,导致nfs客户端(即php应用服务器)不能写入缓存。为了确认这个猜测,在文件服务器及客户端,都进行了创建和删除文件测试,一切正常。

(四)检查缓存服务器。
数据缓存使用的应用程序是memcached,这种服务器系统,仅仅运行这么一个应用,因为是内存存储数据,因此一般情况下,怀疑有故障,只需重启memcached,让它再重新缓存就好。
1、  检查系统负载、内存使用情况,一切正常;
2、  检查系统日志,无异常;
3、  检查网络状况,也很正常;
重启memcached,对应用服务器的负载毫无帮助,看来问题也不在这里。

(五)检查数据库服务器。
仅仅剩下它了,问题很显然,就与这个相关。吸一口带雾霾的空气,登录主数据库及从数据库服务器系统,进行如下常规排查。
1、  检查系统负载、内存使用情况,一切正常;
2、  检查磁盘空间使用情况,未发现被塞满的磁盘分区;
3、  检查系统日志,未发现异常输出;
4、  检查网络连接情况,主服务器连接数很少,而从服务器的连接数很多;这至少说明,在系统层面,主数据库服务器的正常的,从服务器系统,在系统层面看来,也基本认为是正常的。

本集群使用的论坛程序discuz本身支持数据库读写分离,因此主服务器的任务是承担数据更新的任务,而查询一类的工作,则由只读状态的从服务器(slave)承担。我们先层主服务器的应用层面进行排查,步骤如下:
(1)、检查mysql的错误日志及满查询日志,为发现异常输出;
(2)、检查mysql进程是否正常,执行mysql –p 登录一下,能进入mysql客户端命令行,守护进程正常;
(3)、mysql客户端执行命令 show full processlist;输出寥寥几行,一切在可以接受的范围;
由此判定,数据库主服务器无异常。

现在,山穷水尽,水落石出,问题多半就是这个从数据库服务器的问题了。系统层面的检查,为发现有用的线索。查mysql错误日志,未见异常;查mysql慢查询日志,果然有输出,而且还不断有新的输出。

登录mysql客户端,执行show full processlist; 天啦,好半天才输出完毕,线程数超过1000了(我设定的mysql最大连接数是1000),而输出的内容,大部分是慢查询里边的东东。用mysql –p –e “show processlist;”>/root/sql_out 把这些sql形成一个文本文件,转发给程序员。他们看半天,也没有得出一个结论。有人建议杀掉看是异常的sql语句,但杀掉后,还是不行。大家还是怀疑被攻击,通过dns处理,把请求先定向到360,起到一定的攻击过滤作用。从监控见面看,确实有结果cc攻击被拦截。但对应用服务器的负载降低不起什么作用,并且论坛还是处于打不开的状态。

以超级系统管理员的帐号登录论坛后台,关闭论坛后,服务器负载立即恢复正常水平;再打开论坛,负载立马飙升。邪门了啊,居然在技术层面查不出问题所在。折腾了一天,头都大了。在qq群嚷了几句:“谁改了程序没有?谁在后台做什么设置没有啊?…..”,有人冒出来一句:“删垃圾贴的时候,为了快速删除,设置了页面显示帖子的数量值”。

 

发现问题,意识到问题的严重性。

 

论坛后台更改这个设置,几秒钟后,应用服务器的负载降下来了,从数据库的连接数也趋于正常,论坛也可以跟以前一样,可以浏览、发帖……

这一切,追溯起来,就是某些论坛管理员设置该死的简单密码。

是不是想杀人?


(转自51CTO技术博客) 

-----------------------------------------------------------------------------

说到系统排查,由于本身就是做运维的,深知其中的艰辛。

身处现在这个环境,不说同行相轻,就是整个公司对于运维的工作都不能理解,认为这简直就是个消耗部门,领导们看重的只有销售做出的业绩,看重他们卖出了多少产品,对于公司十几个服务器里面的应用数据从来都是抱着可有可无的态度,加之领导各种想表现揽活,这个运维干的是更加艰难,从软件刚研发出来的测试,到部署应用,到客户培训,再到后期系统维护,每天基本都是24小时待命,现场客户都不联系工程经理,电话直接都是干运维的接,所以有时候觉得运维简直就是个出卖体力的活计了……


牢骚发完,能好受点了,还是来说说运维行业吧。

众所周知,一个网站或者一个项目要创建和运营,绝不是一个人可以完成的(个人玩玩那种不算)。至少需要产品、设计、程序开发(前端、后台)、测试、系统维护(部署、运营、维护)、平台运营等等若干职位。

在团队的认知中,某些职位的人总喜欢强势认为自己很重要,是处于主导地位的。于是在这些人的意识里,其它职位或人员都是辅助和次要的,是围绕着他的。在这样的环境里,造成人员冲突的几率就大,相互协作的意识就几乎不存在。如果项目最高领导(老板)也有这种认识,那么情况就更佳糟糕。

在大部分不规范的或者不是以技术做驱动的公司里,一个比较典型的情况就是:对于系统运维人员,如果系统长期稳定运行,一些人就会认为,这些人是不是多余的?反之,如果故障频发,一些人有开始抱怨,运维是干啥的啊,怎么老出问题?

造成这些问题的原因可能是多方面的,可能是认识问题,也可能是项目本身的问题(比如交易型网站运维的地位就要比宣传型网站运维的地位高)。对于我们个人来说,我建议找工作的时候,尽量找交易型的,毕竟公司的存在是以系统平台来赚钱,系统停止就意味着损失,因此个人在组织中的地位自然就比那种宣传型的网站高了不少。对于认识方面的问题,情况比较复杂,需要做更多的分析和考虑。

回到我们的主题上来。随便是一个程序员或者测试人员跑过来,就要求干这干那。没有书面文档,也没有一个流程。这样次数多了,运维人员多半就会感觉被支配,不耐烦,疲于应付。第二种情况是:出现故障,先推给运维。这个真的最要命,也最容易起纠纷。想必不少运维同行也有此遭遇。

主动

搞技术的人,性格内向的比较普遍,不知道是不是因为长时间跟机器打交道的原因。但不能怎样,主动与人沟通依然是很重要的工作。我们得告诉其它人,运维实际上在干很多事情(选机房、做系统架构、技术选型、日常维护、半夜爬起来跑机房、24小时响应…此处神略65535字),要说出来,项目列得越详细越好!有些事情在其它人看来(比如开发人员)似乎很简单,不就是上架服务器,安装个系统么?那么我们就要跟他较真:哪个机房带宽质量好?哪个机房服务到位?怎么装系统更快、更符合要求(不要给我们讲一路回车,一根到底、程序数据一锅端)?做了要说,而且要多说,才能让别人了解我们其实下了很多功夫,做了很多工作。我时不时会给其它人强调,你们设计的界面在美观、程序再怎么牛逼,系统崩溃了,仅仅是一堆占据硬盘空间的二进制而已!就算没崩溃,找的机房线路垃圾,能跑的起来才是怪事呢!

措施

没有人保证系统运行中不发生问题或故障,除非把电源给关闭掉。我经常的措施是:
(1)       收集相关资源的联系方式:机房、供货商、服务提供商(cdn之类的);
(2)       收集相关技术人员的联系方式:技术负责人、程序员、测试等等;
(3)       根据业务,故障报警发相关人员;
(4)       联系接口人员告知故障发生,获取故障现象并简单描述
(5)       要求相关人员协调排查;
(6)       告知自己排查的情况(查了哪些项目、数值是什么状况、修改了什么、数据截图等);
(7)       故障排除,总结经验;
(8)       内部讨论一下,看能否大事化小(小事化了要看具体情况)。如果不是己方的责任,过分强调过错或过失,又会回到相互推卸责任这个老路上来。

流程

没有流程,必定会引起一团糟,比如前边说的,随便是个人就跑过来提要求;流程太繁琐,也不行,会严重影响效率。在这里,不强调怎么做流程,但起码,我们可以相互约定一个接口人,有什么需求,尽量通过接口人。

No comments: