一次诡异的Ansible密码问题排查,最后真相?
背景
在做大批量运维的时候,DBA需要掌握和使用ansible。今天有同事使用ansible遇到了一个奇怪现象,和我交流了一下,我发现这个现象很奇怪,也很有趣,我认为是个BUG,于是排查,之后有了这篇文章。现象
同时使用的是ansible2。7。8,我使用的是最新版python3。11ansible2。14,我们都复现了这个现象。这个问题简而言之是,使用比较特殊的密码组合作为主机密码,ansible在使用上会遇到问题,导致正确的密码而无法连接。
以下是我的环境:
角色
hostname
IP
使用的密码
ansibleserver
192168199121
192。168。199。121
不涉及
有问题的受控机
19216819999
192。168。199。99
1fander
没问题的受控机
192168199131
192。168。199。131
Root123〔root192168199121〕catetcansiblehosts〔fandervm〕192。168。199。99ansibleuserrootansiblesshpass1fander〔root192168199121〕ansible192。168。199。99mping192。168。199。99UNREACHABLE!{changed:false,msg:Invalidincorrectpassword:Permissiondenied,pleasetryagain。,unreachable:true}同事疑问1特殊密码,ansible无法连接会报错
同时设置了一个形如1xxxxxx的密码,使用sshroot192。168。199。99连接是完全没有问题的,但使用ansible连接则会报错,Invalidincorrectpassword:Permissiondenied,pleasetryagain。无法连接。这个密码经过我的研究,是有规律,1位到任意长度的数字‘’任意长度字符,ansible会报错。
也就是,以下密码会报错1fander12fander
以下密码不会报错1afander1fander同事疑问2此特殊密码,ansible无法连接会报错,但有时却能连接不报错排查过程1。ansiblevvvvv排查
v参数可以让ansible输出debug日志,v越多越详细。当然了,可能并不需要五个v,我不知道要打多少个v时,我就把v打满。(mysqlbinlog我打3个v)
如图红圈和横线,这两处很关键。
红圈告诉我,我在执行ansible时,其实底层调用的是sshpass和ssh。
横线这一处,报有个文件不存在,我对比了执行正常连接的机器(192。168。199。131),是不会报这个的,所以此处属于异常,需要排查。
这些日志输出其实一团糟,可以粘贴到notepad,用以下方法美化输出。
粘贴到notepad只有两行,通过替换r为换行符即可。
首先,我先把r替换为fanderissb
然后,再以扩展模式,替换回来
现在就比较好阅读了,这一处就是不正常的。
经过研究,这些debug日志其实来源于我前面红圈的命令行sshpassxxx的输出。
查阅资料和整理,原理大概是这样的:
正确连接是长这个样子的,命令结果是输出root,前面的0是命令?的返回码,0代表执行正常。
而我们密码有问题的服务器返回码是5,输出是空
sshpassd10sshvvvCoControlMasterautooControlPersist60soStrictHostKeyCheckingnooUserrootoConnectTimeout10oControlPathroot。ansiblecpe2f9f7759b192。168。199。99binshcechorootsleep0
在这句命令中,ControlPersist60s是ssh的参数,代表建立一个长链接,保持60秒,这个长链接就是建立在ControlPathroot。ansiblecpe2f9f7759b的路径下。
实际上,就是这个ControlPersist,可以解答同事疑问2此特殊密码,ansible无法连接会报错,但有时却能连接。
为了方便解释,我把ansible服务器的这个ControlPersist调大到600秒。〔root192168199121〕catetcansibleansible。cfg〔defaults〕hostkeycheckingFalse〔sshconnection〕sshargsCoControlMasterautooControlPersist600
首先,我登录远端服务器,先把密码改回常规密码。〔root19216819999〕echoRoot123passwdstdinrootChangingpasswordforuserroot。passwd:allauthenticationtokensupdatedsuccessfully。
接着,我配置好ansible服务器的hosts文件。〔root192168199121〕catetcansiblehosts〔fandervm〕192。168。199。99ansibleuserrootansiblesshpassRoot123
然后,开始测试。完全没有问题,能连通。〔root192168199121〕ansible192。168。199。99mping192。168。199。99SUCCESS{ansiblefacts:{discoveredinterpreterpython:usrbinpython},changed:false,ping:pong}
执行psef能观察到,我们第一次连接完后,ssh并没有断开,有一个背景执行的长链接,他实际上是一个多路复用的socket连接,后续我们再连远端服务器时就是复用他,不需要重新验证密码。〔root192168199121〕psefgrepsshroot8601017:18?00:00:00usrsbinsshdDroot945860017:18?00:00:04sshd:rootpts0,pts1root92201022:40?00:00:00ssh:root。ansiblecpe2f9f7759b〔mux〕root92671009022:41pts000:00:00grepcolorautossh
这个时候,我把远端的服务器密码修改为有问题的密码〔root19216819999〕echo1fanderpasswdstdinrootChangingpasswordforuserroot。passwd:allauthenticationtokensupdatedsuccessfully。
此时,我的ansible服务器的hosts配置里仍然用的旧密码〔root192168199121〕catetcansiblehosts〔fandervm〕192。168。199。99ansibleuserrootansiblesshpassRoot123
密码是错误的,那么我还能连吗?答案是能。这就是连接复用,不需要重新验证密码,直接复用前面的socket连接。
所以,这时你通过ansible,密码乱输或者不输密码都能连。〔root192168199121〕catetcansiblehosts〔fandervm〕192。168。199。99ansibleuserroot我这里直接去掉了密码〔root192168199121〕date;ansible192。168。199。99mshellalsSunNov1322:49:15CST2022我复用这个链接的时间192。168。199。99CHANGEDrc0anacondaks。cfg
那么这个长链接是创建后的600秒自动销毁吗?(提醒,前面我修改的ControlPersist600s)
答案否。因为我在创建连接后,中途复用过这个连接通道,时间是22:49:15,所以他消失时间不是创建时间22:40:2810分钟,而是22:49:1510分钟,也就是22:59:15。〔root192168199121cp〕pwdroot。ansiblecp〔root192168199121cp〕state2f9f7759b;dateFile:‘e2f9f7759b’Size:0Blocks:0IOBlock:4096socketDevice:fd00h64768dInode:68415916Links:1Access:(0600srw)Uid:(0root)Gid:(0root)Access:2022111322:40:28。6805779860800Modify:2022111322:40:28。6155779880800Change:2022111322:40:28。6155779880800Birth:SunNov1322:59:00CST2022〔root192168199121cp〕state2f9f7759b;datestat:cannotstat‘e2f9f7759b’:NosuchfileordirectorySunNov1322:59:30CST2022超过22:59:15,socket消失了。
那同事的疑问2,就可以解释了,有问题的密码依然不能通过ansible连接,能连接的假象是因为曾经用正确的密码建立过长链接(这个是ssh的参数功能,不是ansible),后面连接时复用了此连接,没有使用密码认证,所以也就不会报错了。待ControlPersist超时后,socket销毁,有问题的密码连接就开始报错了。
我们继续排查同事的疑问1。
根据我前面整理的原理,我标记1、2、3、4数字的这几步,我按这个顺序从下往上开始一一排除。
其实,本来应该从最顶上的4开始排查的,但4需要阅读源码,所以我从简单的1开始排查。2。排查ssh
首先,我测试标记为1的步骤,手敲这个密码,ssh是否认正常。结果是连接正常。
3。排查sshpass
然后,测试标记为2的步骤,测试sshpass传输密码是否正常的。结果也是连接正常。〔root19216819999〕sshpassp1fandersshCoControlMasterautooControlPersist60soStrictHostKeyCheckingnooUserrootoConnectTimeout10oControlPathroot。ansiblecpe2f9f7759b192。168。199。99binshcechorootsleep0root
这里,我调整了原命令,因为原命令用的是sshpassd10,这个文件描述符文件我不知道如何制造,所以我改为用sshpassp来测试。我去掉了vvv,因为如果一切正常,我不需要刷屏的debug日志。4。使用paramiko连接方式辅助排查
标记为3的步骤,我不知道如何测试,但我知道ansible除了ssh连接,还有一种叫paramiko的连接方式,他是旧版ansible的默认连接方式,他比较低效,他不使用ControlPersist,也就不会建立Controlsocket,而之前我们连接报错时,日志的关键信息就是Controlsocketroot。ansiblecpe2f9f7759bdoesnotexist
当然了,他也不会使用sshpass和不会把密码写入那个数字为10的文件描述符。所以,如果我能在paramiko的连接方式能复现报错,那么就和标记为3的步骤无关。〔root192168199121inventory〕catetcansibleansible。cfg〔defaults〕hostkeycheckingFalsecallbackwhitelisttimertransportparamiko
结果是,我使用paramiko的连接方式,也能复现连接报错。
他这个python抛出异常非常好,终于让我知道为什么密码会错误了,原来传进去的密码不是1fander,而是1。也就是问题肯定不在标记为3的步骤,而是标记为4的步骤。
根据报错,我在authhandler。py文件里打了两个print。
我们再看看输出。
那么,标记为1、2、3的步骤我们都排除了,问题出在标记为4的步骤,也就是现在的问题是:
为什么ansible传入给sshpass和ssh的密码不正确,应该传入1fander,但最终传入1?5。排查ansiblek
我们再来做个测试,不使用ansiblehosts文件传递密码,使用k参数手敲密码。发现一切正常。6。水落石出,是ansible的hosts设置问题
那问题完全能定位出来了,这个疑似bug,不是ssh也不是sshpass的问题,而是ansible的问题。并且,我们能确定,这个和ansible读取解析etcansiblehosts文件有关。
经过我查阅资料,ansible读取解析etcansiblehosts相关的代码在这个路径下,ini。py文件。cdusrlocalpython3libpython3。11sitepackagescdansiblecore2。14。0py3。11。eggansiblepluginsinventorylessini。py
通过阅读注释,发现这个不是bug,而是官方知道的问题,所以属于一个坑。
最后
我经常阅读源码都是通过阅读注释就解决的,这很有趣,适合我这种萌新coder。现在是2022年11月13日的23:56分,由于能力和时间的关系,我就写到这里了。大家应该看懂了解决办法,请大家避免这个坑,这个坑不单止针对密码,在hosts文件的所有变量设置都应该这么做(上图横线)。有兴趣深入研究的同学可以继续看看源代码。
读湘西故事笔记(十五)湘西名镇茶峒湘西有个很出名的古镇,位于湖南贵州重庆三省(市)交界处,素有一脚踏三省之称,与浦市里耶王村并称湘西四大名镇,它就是花垣县的茶峒。大文豪沈从文写有一篇著名的小说边城的背景便是这里,近
在广州邂逅粉色浪漫,紫花风铃木正盛放!文图羊城晚报全媒体记者何奔广州有一种少女粉,回头率高达100!近日,广州天河区临江大道与广州大道交界处,寺右万科中心楼下,16棵紫花风铃木构建春天童话长廊,成为当季网红打卡地。游客
手慢无!2023龙庆峡冰灯冰雪嘉年华门票免费领!头条创作挑战赛龙庆峡冰灯冰雪嘉年华门票免费送龙庆五十载冰雪映芳华龙庆峡冰灯冰雪嘉年华以冰雪为媒,用极地海洋等主题元素,呈现20世纪80年代以来国家在南极科考等方面的发展成就,体现海
树山猛将迎新之旅获评全国乡村旅游精品线路近日,文化和旅游部公布了乡村四时好风光瑞雪红梅欢喜过年全国乡村旅游精品线路名单,其中,树山乡村微旅行猛将迎新之旅位列其中。树山乡村微旅行猛将迎新之旅,是树山乡村微旅行的冬季旅游线路
四川平武云端之上美似仙境来源原创稿天接云涛连晓雾,星河欲转千帆舞。冬日清晨,四川省绵阳市平武县城近郊持续出现冬日云海景观。高空俯瞰,云海波涛翻滚,浩瀚缥缈,蔚为壮观。天接云涛连晓雾。胡宇摄凭栏远眺,漫漫云
寿宁守护木拱廊桥,擦亮文化名片!寿宁县文体和旅游局栏目协办下党峦峰桥龚健摄徐徐展开北宋传世名画清明上河图,只见画卷中部一座状若飞虹的木拱桥横跨汴河,全卷的情节高潮就发生在此处,令观者过目难忘。千百年来,木拱桥传统
山西稷山坐拥7处国家级文化宝藏山西运城稷山县文化底蕴深厚,县内有稷王庙大佛寺青龙寺宋金墓法王庙玉壁城遗址北阳城砖塔等7处国家级文化保护单位。图说玉璧城遗址来源网络位于稷山县内的稷山稷王庙,又称后稷祠,始建于元至
节后继续约起来!兵团这两条线路值得一去乡村四时好风光景点概览animateanimateanimateanimateanimateanimateanimateanimate精选线路在新春佳节之际,文化和旅游部推出乡村四
贵阳青岩古镇人头攒动1月25日,阳光明媚的贵州省贵阳市花溪区青岩古镇,红火的灯笼五颜六色的宫灯彩旗喜庆的春联等交相辉映,呈现出热烈喜庆欢乐祥和的节日氛围,吸引着众多游客前来观光休闲品美食,感受浓浓的年
过年丨新春好风光!平顶山河滨公园游人如织赏景忙大河网讯尽管已经到了春节假期的尾声,但是平顶山市民出游的热情依旧不减。1月27日,大河网记者来到平顶山市河滨公园内,实地探访市民游园的景象。河滨公园动物园里,游客通过风车走廊。高高
打卡潮点澳门色彩最缤纷的三片街区,带你这样逛!兔年大吉正值农历新春假期,不少旅客来澳感受浓厚的节日气氛!除了富丽堂皇的路氹城酒店大三巴议事亭前地等著名景点,其实澳门还有不少色彩缤纷的街区值得你去探索!今天,就带大家走街串巷,发