热身运动??
在开始之前,先来个热身运动。虽然标题党写着快速打造一个ssh客户端,但是和跑步一样,在运动前还是需要先热身一下,不然到时候身体(大脑)会吃不消。所以,在开始前,我们先来科普一下ssh的一些东西。
先来说说ssh,这里的ssh是指由IETF的网络小组(Network Working Group)所制定的为建立在应用层和传输层基础上的安全协议。(对于了解这个协议的请忽略本段文字??)点这里了解更多ssh介绍
写过java web应用的同学应该还知道另一个ssh(struts+spring+hibernate),当然今天的主角并不是它。??
其实接触过后端开发的同学对于ssh应该都不陌生,可能每天你都在使用它,没错,当你要远程登录服务器的时候,大多数情况下都离不开它,俨然已经成为Linux系统的标准配置。所以,如果你使用的是Linux操作系统,那么默认情况下就已经自带ssh的客户端了,于是乎你直接可以在Linux的shell中执行:
ssh user@host就可以安全的登录到了远程主机host。对于ssh的更多命令或者玩法今天就不多介绍了,因为这不是今天的主要目标,今天的主要任务是实现一个和Linux操作系统中默认自带的ssh命令行客户端一样的使用go语言开发的ssh命令行客户端,当然由于时间篇幅有限,这次并不会实现原生ssh命令行客户端的全部功能,主要是能够实现远程登录到远程host,并能进行命令行操作。对于其他高级命令,如端口转发等将在后续完成。
工欲善其事必先利其器??
既然说了要快速打造,那么必然需要借助一些现有的工具包了,这边为了完成这个客户端,笔者对原生的go语言的ssh包进行了一下封装做了一个小工具包gosshtool,可以从github找到。有了它,再来做ssh的客户端就轻松多了。
开始设计??
首先,要完成一个命令行的ssh客户端,我们先来看下Linux下自带的ssh客户端是怎么工作的。这里所说的怎么工作,会站在比较高层的角度,因为ssh的整个通讯协议比较复杂,这里不过多介绍,原因是go提供的ssh包已经把底层的一些协议实现了,这里没必要自己再写一套实现出来,如果你确实对底层协议有兴趣,可以自己去网上查阅文档。那么站在比较高层角度来看,是如何的呢? >我们还原一个最常见的场景:某一天,你想登录远程主机,于是你打开了Linux的shell, 输入
- ssh user@host
然后输入密码后顺利的登录了host这个主机,接着你在shell输入一些命令,比如
- ls
查看远程主机当前目录下所有文件。
上述场景的过程,我们可以简单画一个图,来看看你这些操作是怎么与远程主机通讯的,如下图: 
根据上图,我们开始设计,首先要想办法读取用户的键盘输入,如:输入pwd 在go语言中,我们可以使用os和bufio两个包,关键代码如下:
- inputReader := bufio.NewReader(os.Stdin)
- input, err := inputReader.ReadString('\n')
如上代码,我们就可以读取以换行结束的字符串。