SSH是一种网络协议,主要用于计算机之间的加密登陆和网络传输。
基本使用
使用用户名为user的用户登陆远程主机host。
ssh user@host
如果本地用户名与远程用户名一致,登录时可以省略用户名。
ssh host
SSH的默认端口是22,也就是说,你的登录请求会送进远程主机的22端口。使用p参数,可以修改这个端口。
ssh -p 2222 user@host
SSH登陆流程
SSH登陆分为两种:密码登陆和公钥登陆。下面首先讲一下基于密码的登陆流程。
密码登陆
如果你是第一次登录对方主机,系统会出现下面的提示:
ssh user@host
The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
假定经过风险衡量以后,你决定接受这个远程主机的公钥。
Are you sure you want to continue connecting (yes/no)? yes
系统会出现一句提示,表示host主机已经得到认可。
Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.
然后,会要求输入密码。
Password: (enter password)
如果密码正确,就可以登录了。
当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。
密码登陆流程解析
(1)主机A向主机B发送连接请求
(2)主机B将自己的公钥发送给主机A
(3)主机A通过密钥协商技术生成一个随机密钥,然后使用接收到的主机B的公钥对此随机密钥进行加密,发送给主机B
(4)主机B收到加密后的密钥后,使用自己的私钥对密文进行解密,得到对称加密要使用的密钥明文。至此,会话密钥生成完毕。
(5)主机A使用会话密钥对账号密码等信息进行加密发送给主机B
(6)主机B收到加密后的账号密码信息后,使用会话密钥进行解密,得到明文的账号密码信息,进行身份认证。
(7)身份认证完成后主机B通知主机A,从而SSH密码登陆流程结束。
密码登陆的风险
主机A怎么验证主机B的身份呢?如果有主机C冒充主机B截获了登录请求,将自己伪造的公钥发送给主机A,怎么办?尽管信息是加密过的,通信过程也是合法的,但是通信信息都被主机C截获了,其实这就是所谓的“中间人攻击”(Man-in-the-middle attack)。其实,对主机B进行验证就是对主机B发送过来的公钥的合法性进行验证的过程。
SSH主要用于机器之间的安全登录,因此通常不会通过权威的机构去签发证书,它主要是通过验证数据指纹的方式来验证公钥的合法性的。第一次SSH登陆远程主机时,会出现以下警告:
ssh user@host
The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
用户需要把目标主机管理员公布的公钥的数据指纹与主机A计算得到的数据指纹进行比对,如果一致,则说明该公钥是合法的;如果不一致则说明不合法。这就完成了公钥合法性的验证。
公钥登陆
所谓"公钥登录",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。
这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个:
ssh-keygen
运行上面的命令以后,系统会出现一系列提示,可以一路回车。其中有一个问题是,要不要对私钥设置口令(passphrase),如果担心私钥的安全,这里可以设置一个。
运行结束以后,在$HOME/.ssh/目录下,会新生成两个文件:id_rsa.pub和id_rsa。前者是你的公钥,后者是你的私钥。
这时我们需要手动把公钥的内容复制到要登录机器B的相应用户(如root)家目录下的指定文件中:/home/root/.ssh/autorized_keys;或者ssh-copy-id root@hostB命令直接完成这个操作。
ssh-copy-id root@hostB
好了,从此你再登录,就不需要输入密码了。
公钥登陆流程解析
(1)主机A与主机B协商产生会话密钥
(2)主机A会向主机B发送一个登录请求(如:root@192.168.1.2),发送的信息包括用户名root和root的公钥指纹,且所有信息都是通过会话密钥加密过的。
(3)主机B通过会话密钥解密主机A发送的数据得到请求登录的用户名root和root的公钥指纹,然后读取root用户家目录下的所有公钥数据(/root/.ssh/autorized_keys文件中),并分别通过单向加密算法获取各公钥的数据指纹与主机A发送过来的数据指纹做对比,从而找到主机A上的root用户的公钥。
(4)主机B使用找到的root用户的公钥对一个随机数进行加密发送发送给主机A
(5)主机A使用root用户的私钥对主机B发送的随机数密文进行解密,然后把解密结果发送给主机B。
(6)主机B验证主机A解密后的数据与自己发送的数据一致,则对root用户的身份验证成功。
SSH原理总结
总的来说,无论密码登陆还是公钥登陆,SSH通信流程都分为以下步骤:
(1)生成会话密钥: 这个会话密钥,不是密钥对儿中公钥或私钥,而是通过密钥协商技术生成密钥。这个密钥会被通过被登录机器的密钥对进行加密后传输,用于后续所有(通过对称加密方式进行的)加密通信。
(2)用户身份认证(登录):使用密码进行认证(密码登陆)或者使用密钥对进行认证(公钥登陆),这个过程中传输的所有数据都是通过上一步生成的密钥加密过的。
(3)数据加密通信: 后面就行基于第1步生成的密钥进行数据加密传输的通信过程了。
网友评论