脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - 解决go语言ssh客户端密码过期问题

解决go语言ssh客户端密码过期问题

2020-06-08 11:18cuidi Golang

这篇文章主要介绍了go语言ssh客户端解决密码过期问题,本文给大家分享了解决的方法和原理,非常不错,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

go语言的ssh包居然不支持密码过期重置的功能!

版本:go v1.14.1 linux环境下安装的。

ssh包:git clone https://github.com/golang/crypto.git

是2020年4月1号左右下载的。

先描述一下问题的现象,以及必须得解决这个问题的原因:
正常的ssh客户端,如果密码过期了,或者不符合密码规则,在登陆的时候终端都会提示一段话,比如过期之类的。然后会提示你在终端输入旧密码,再输入新密码,然后确认,从而完成密码修改。

然而用这个ssh包,执行ssh.Dial的时候,如果遇到密码过期,这个函数会直接返回一个错误,并不会给你修改新密码的机会!

而我的项目恰恰需要这个功能。因为我的项目是服务器通过ssh客户端推送脚本到一个设备,其中就有修改密码的脚本,目的就是想修改目标设备的密码。如果该设备的密码没有过期,我还可以通过旧密码登陆上,然后执行修改密码的脚本。但是如果密码过期,则在ssh登陆的时候就会提示修改密码,如果像go语言这样直接返回失败,我就没法修改成功密码了。而其他语言或者终端软件,都有重置密码这个功能。我认为这可能是go语言太年轻了,没有完善这个功能的原因吧(至少我没有找到)。

再说一下解决的方法和原理:

我是自己修改了ssh包中的client_auth.c文件解决的。

具体的修改是方法是增加了一个自定义的认证方式changePassword,来代替后面要讲的“password”认证,并实现规定的Auth方法和method方法。这两个方法是ssh包里规定必须要实现的,只有实现了这两个方法,才算是实现了auth接口,才能作为ssh client的一种配置去连接ssh服务器。其实我也可以直接修改“password”的代码,但是由于不太敢动,所以重新写了一个,它的还保留着。~~~~

ssh中之前就定义好了几个同样的类型,代表认证方式,包括“password”,“publickey”,"keyboardinactive","gcc"这几个。这几种都是按照ssh协议规定来的。参考的文档是rfc4252。

正常的ssh连接输入用户名密码的方式,走的都是“password”这个认证方式,包括密码过期需要重置,也是走这个认证方式。每个认证方式都会实现Auth这个接口,这个接口会发送密码,然后接收服务端的响应。问题就出现在这个实现上!如果密码过期,服务器会响应一个change password的响应,这个响应报文在rfc4252中是有明确规定的。

但是go语言的ssh包居然不会去识别这种响应!直接返回失败!这个太坑了!
于是我自己的认证方式changePassword的Auth实现上,增加了对这种响应的识别,并仍然根据rfc4252文档规定的后续发送报文的格式,发送了包含新旧密码的报文。服务端收到这个报文就会重置为新的密码。这样我需要的功能就完成了。

谈谈探索历程:

1.一开始不觉得go语言会这么坑,居然没有按照rfc来实现功能。但是实在没办法,才开始读源码包。网上也没有文章讲解,都是靠着自己一点点的摸索硬着头皮看。

2.刚开始看代码没有看rfc,不知道他那些认证方式怎么来的,密码过期应该走哪种认证方式。我看有一个keyboardinteractive很像是正确答案,因为新旧密码都是需要输入,还有确认,觉得应该是这个认证。于是按照这个做,但是还是各种报错,一度想放弃。结果后来无意中在代码中看到注释,提到了rfc4252,就看了一下,才发现很多功能都是按照这个来实现的,然后发现密码过期走的还是password的认证,不是keyboardinteractive这个。~~~~

总结

到此这篇关于go语言ssh客户端解决密码过期问题的文章就介绍到这了,更多相关go语言ssh客户端内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://segmentfault.com/a/1190000022400722

延伸 · 阅读

精彩推荐
  • GolangGO语言字符串处理Strings包的函数使用示例讲解

    GO语言字符串处理Strings包的函数使用示例讲解

    这篇文章主要为大家介绍了GO语言字符串处理Strings包的函数使用示例讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加...

    Jeff的技术栈6882022-04-14
  • GolangGo语言实现自动填写古诗词实例代码

    Go语言实现自动填写古诗词实例代码

    这篇文章主要给大家介绍了关于Go语言实现自动填写古诗词的相关资料,这是最近在项目中遇到的一个需求,文中通过示例代码介绍的非常详细,需要的朋...

    FengY5862020-05-14
  • GolangGolang实现四种负载均衡的算法(随机,轮询等)

    Golang实现四种负载均衡的算法(随机,轮询等)

    本文介绍了示例介绍了Golang 负载均衡的四种实现,主要包括了随机,轮询,加权轮询负载,一致性hash,感兴趣的小伙伴们可以参考一下...

    Gundy_8442021-08-09
  • GolangGo语言range关键字循环时的坑

    Go语言range关键字循环时的坑

    今天小编就为大家分享一篇关于Go语言range关键字循环时的坑,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来...

    benben_20154202020-05-23
  • GolangGo语言基础单元测试与性能测试示例详解

    Go语言基础单元测试与性能测试示例详解

    这篇文章主要为大家介绍了Go语言基础单元测试与性能测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助祝大家多多进步...

    枫少文7812021-12-05
  • Golanggo语言获取系统盘符的方法

    go语言获取系统盘符的方法

    这篇文章主要介绍了go语言获取系统盘符的方法,涉及Go语言调用winapi获取系统硬件信息的技巧,具有一定参考借鉴价值,需要的朋友可以参考下 ...

    无尽海3862020-04-24
  • GolangGolang 语言极简类型转换库cast的使用详解

    Golang 语言极简类型转换库cast的使用详解

    本文我们通过 cast.ToString() 函数的使用,简单介绍了cast 的使用方法,除此之外,它还支持很多其他类型,在这没有多多介绍,对Golang 类型转换库 cast相关知...

    Golang语言开发栈6112021-12-02
  • Golang深入浅析Go中三个点(...)用法

    深入浅析Go中三个点(...)用法

    这篇文章主要介绍了深入浅析Go中三个点(...)用法,需要的朋友可以参考下...

    踏雪无痕SS6472021-11-17