在分布式系统集群中,需要设置集群中个机子之间能够通过SSH无密码访问,这几乎是每个分布式系统环境搭建初期的必备操作。那么如何来配置集群中机子进行无密码访问的呢?SSH又是如何处理无密码访问的呢?
经过半年的努力,笔者的项目小组终于完成了新的作业调度,资源管理监控模块,并集成进了skyfs-mapreduce框架中。每一个程序员都知道,新开发一个模块,无论大小,集成时总难免会有Bug,而笔者的项目小组完成了几大模块,意想不到的Bug应该会不少。于是项目组长X与项目成员H商议在进行大规模测试之前,为了避免反复重新打包程序并部署集群,决定先在自己的主机上搭建一个小的集群,将测试用例跑全后再迁入大规模测试。
很快两个人就配置好了无密码访问,并搭建好了小集群,而且跑过了测试。但是这时候问题来了,发现不能通过git提交代码了。回想后才发现,之前在配置SSH无密码访问时将git的无密码私钥和公钥覆盖了,于是乎又找项目管理人员帮忙重新授权git无密码访问权限。那么如何在不影响到git等其它已经设置了SSH无密码访问的同时,设置机子与其它机子无密码访问呢?
带着这些问题,笔者开始了SSH学习之旅,那么接下来,各位读者就跟随笔者一起来简单了解一下SSH吧。
SSH架构
SSH(全称OpenSSH,以下简称SSH)是由服务端(sshd)和客户端(ssh)两部分组成的,之间通过通信协议(传输层协议、用户认证协议和连接协议及各种高层的网络安全应用协议)进行通信.
在SSH的通信协议框架(见图1)中,传输层协议(TheTransport Layer Protocol)提供服务端认证,数据机密性,信息完整性等的支持;用户认证协议(The User Authentication Protocol)则为服务端提供客户端的身份鉴别;连接协议(The Connection Protocol)将加密的信息隧道复用成若干个逻辑通道,提供给更高层的应用协议使用;各种高层应用协议可以相对地独立于SSH基本体系之外,并依靠这个基本框架,通过连接协议使用SSH的安全机制。
图2 :OpenSSH通信协议框架
对于SSH这样以提供安全通讯为目标的协议,完备的密钥机制是必不可少的。由于SSH协议是面向互联网网络中主机间的相互访问与信息交换,所以主机密钥成为其基本的密钥机制。换言之,SSH协议要求每一个使用本协议的主机都必须至少有一个自己的主机密钥对,服务方通过对客户方主机密钥的认证之后,才能允许其连接请求。一个主机可以使用多个密钥对,针对不同的密钥算法(版本2支持RSA,DSA,ECDSA,版本1只支持RSA)而拥有不同的密钥对。
认证流程
笔者通过ssh –v ServerIP来跟踪SSH的通讯认证流程。认证过程概括如下:
① 客户端先读取本地ssh配置文件,并向服务端发起连接请求。
② 服务端确认连接。
③ 客户端检查本地秘钥。
④ 客户端和服务端双方协商SSH版本号及协议。
⑤ 服务端提供各种加密和认证方式,如RSA/DSA主机密钥,数据加密算法,消息摘要等。
⑥ 客户端选择加密认证方式。
⑦ 客户端根据选择的认证方式发起登录验证申请。
⑧ 服务端对客户端提供的密码等信息进行校验,若认证通过进入⑨;若认证失败,
则试图进行下一种认证方式认证,直到成功或失败,或超时退出。
⑨ 客户端校验成功,则服务端创建一个session(进程),同时发送环境变量,将该session给客户端用,此次认证结束。
其中⑤的主机密钥用于确认服务端的身份;数据加密算法用于加密通信数据;消息摘要用于校验数据的完整性,登录认证方式。
由上面可知,无密码访问其实就是在⑧的时候提供一种认证方式,使客户端无需输入密码就能够校验成功。显然我们知道这种认证方式是基于主机秘钥机制,只要在服务端有客户端的公钥,那么客户端就能通过自己的私钥来通过服务端的校验。
那么当我们希望主机A能SSH无密码访问主机B时,只需要将在主机A上生成秘钥对,并将主机A的公钥追加到主机B的授权文件(默认是authorized_key)即可,类似的,如果需要主机B能无密码访问主机A时,那么同样的只需要将主机B的公钥追加到主机A的授权文件即可。若主机A或B中已经有秘钥对,那么则无需再生成,可以直接复用已经存在的秘钥对。如果不希望复用,那么可以生成不同加密算法的秘钥对(不覆盖已经存在的),再进行配置。
总结
通过本次学习,主要了解了SSH的架构,协议框架及认证流程,掌握了如何配置SSH无密码访问及复用已存在的秘钥对来配置SSH无密码访问。