一、问题发生、排查以及解决
某天H博士在登录B服务器时发现一个严重的问题,问题是H博士在执行脚本出现一个异常,这个异常是过去我执行脚本只需输入一次密码,现在要输入五六次,只有输入五六次后才能正确执行完脚本。这个问题非常严重。我记得那天ZH向我请教了几个关于Linux授权的问题。而后第二天H博士就开始反馈这个异常。于是ZH先处理,一直找不到问题在哪,于是便叫我来,一同排查是什么原因。
H博士那边给我们提供一个方案,他怀疑是SSH密钥失效导致的,于是我们按照H博士提供的方案一一执行,发现还是不行。
而且在验证H博士提供的方案之前,我参考我之前写过的文章:Linux远程传输文件免密码
试验开发服务器,按照我这边试验的,A服务器上的用户可以免密登录B服务器,而B服务器上的用户可以免密登录A服务器,前提是将彼此ssh-keygen -t rsa 生成密钥放入.ssh/authorized_keys即可。
我按照我之前写过试了试,完全没有问题。
由此排除了是密钥的问题。
接着怀疑是权限的原因,最后我给H博士经常使用的用户授予最大权限chmod 777或chown -R 用户 文件夹。但发现仍解决不了这个问题。
最后ZH和我一时想不到有效的办法,ZH就准备重装系统了,先从B服务器开始入手。
而我最初想着重装太费劲了,主要是备份很多东西和安装很多奇葩环境,一直在想如何解决这个问题。
某天灵感突然一来,明确我们的问题(登录某个用户执行该用户所属目录的脚本需要输入多次密码),我使用root用户新建了一个用户,按照H博士之前提供的方案,切换到新用户,执行相关命令,然后验证是否需要输入密码,最后发现完全不要。我此时还没有意识到是用户组权限问题。
为了解决这个问题,归纳一下,我试了如下方法:
- 认为是权限问题,授予该用户最大权限;
- 认为是密钥问题,使用该用户执行重新生成密钥步骤;
- 两台服务器存放密钥验证免密(最初定位错了问题,认为是两台服务器需要交互操作);
- 重新新建用户验证是否免密;
- 修改ssh配置文件。
最后均不能解决这个问题,后来我只能表示黔驴技穷,ZH也想不到更好的办法,基本上搜索引擎我们能搜的,能尝试的都尝试了,都不能解决这样的问题,ZH还亲自读脚本和执行脚本一步步用echo输出调试,还是不能定位问题根源在哪。最后我们采用最后的方案,重装系统,回归原来的环境。
ZH当时重复说了多次,我就仅仅动了一下用户权限,其它什么都没有动(这是一条非常关键的信息,当时我并未重视起来,仅仅是表面的以为没有权限,授个权就行了)。
自到ZH重装以后,再次授权,复现了这个问题,然后我叫他别动,我在此新建一个用户,发现执行免密登录所需步骤后,可以不用输入密码。最后他再次快速重装,什么都没有动,然后我使用H博士常使用的用户验证是否输入密码(在此安装免密步骤执行了),最后发现不要,问题就这么解决了。
后来过了一段时间,ZH再次给我反馈有这么一个问题,我问他做了什么操作,他回答到H博士经常操作的是A用户,但是我们部署微服务的是放在B用户上,B用户需要读A用户下的某个文件,于是他给B用户递归授权A用户目录,最后再次验证A用户是否需要输入密码,最后发现需要输入了。最后我使用ll命令查看了/home下的用户权限,发现有问题,譬如/home/A的用户和用户组应该是A A,而不是A B这样的,此次我发现A B。最后我断定一定是A用户的权限组不明确 生成的密钥与权限组有非常大的关联,如果权限组变了,密钥是无法识别的,于是造成A用户执行脚本时需要输入多次密码。
经常多次试验,果真是这个原因。
但因为B用户上部署的微服务程序需要访问A用户下的目录,这个问题不解决会有很大的影响,最后我们的方案是,/home下的A用户和B用户各自做各自的事情,不能交叉,例如A用户除了执行脚本外,还可以执行部署微服务,脚本执行每天人为地固定执行,而程序是自动化的,B用户仅仅是部署,完全没有这个必要,于是A用户只做两件事情,一件事情是执行脚本,另外一件事情是部署微服务,因为后续脚本将会自动化,所以A用户最终的职责就是部署微服务,由此我们推出了一个新的原则,叫做用户专一原则(一个用户只做一件事情或一类事情)。
二、总结
这个问题说大不大,说小也不小,足足磨了我们半个多月的时间,当然了,半个多月虽然还有其它的开发任务,但这个问题卡在这,让人着实不爽。虽然最终解决了,但我仍不高兴,因为明明我可以在几个小时内或不用几个小时就能快速解决这个问题,但最后却足足耽搁了半个多月。
1.之后我在想为什么这个问题这么长才定位到原因?
我想关键在于问题复现步骤上,首先我没有与ZH仔细沟通,询问他做了什么操作(没有具体到原来是给B用户授予A用户的权限),而仅仅是得到一个大致不精确的回答了授了一下权限。如果试想当初我追根刨底,具体到执行了什么命令,我想用不了这么长时间就能快速解决,因为问题本身并不难。
由此推出,原因在于我没有仔细询问ZH在该服务器上做了哪些操作,执行哪些具体命令,导致我错误的定位问题,如扫雷式排查,一个个试。
可见,遇到问题并不可怕,可怕的是没有找问题发现者,仔细询问是如何发现这个问题的,以及在发现这个问题时做了那些操作(因为这些操作可能是导致问题发生的引子)。
2.以后将如何避免这样类似的问题?
我总结出如下两个原则:
- (1)面对他人发现的问题,首先要仔细询问他是如何发现的或在此做了些什么(非常关键,需要重点留意),在与问题发现者的不断沟通中,得到更多的信息,这些信息实际上有助于问题的正确定位(这一刻我明白了磨刀不误砍柴工);
- (2)在(1)的基础上,根据从(1)所知的信息和结合以往的经验,找到问题的可能原因,定位问题并解决,另外必要时可请教相关专业人士提供帮助,在请教前,记得将问题陈述清楚(如问题是如何发现的、问题发现前做了哪些事情、为了解决这个问题根据问题可能原因尝试用哪些方法去解决等)。