您当前的位置:网站首页>碎碎语>Linux系统中SSH服务基于key认证实践的过程

Linux系统中SSH服务基于key认证实践的过程

2022年11月17日 投稿作者:admin 围观人数:525
Linux系统中SSH服务基于key认证实践的过程

  众所周知ssh是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议,它默认工作在tcp的22号端口,具体实现的软件有:openssh(centos默认安装的),dropbear。ssh协议目前有两个版本v1和v2,v1基于CRC-32做MAC,不安全。v2基于DH算法做密钥交换,基于RSA或DSA实现身份认证。所以目前大多流行的Linux都是使用的V2版本。

  简单了解了下ssh,我们再来说说它的两种用户登录认证方式,第一种基于用户名口令的方式,这种认证方式想必大家都应该知道,就是我们要想登录远端Linux系统,我们必须要输入相应的用户名口令才可以登录到远程Linux系统,这种方式是交互式方式登录。第二种就是我们今天要说的基于key的认证方式。

  首先我们来了解下ssh加密通讯的过程

Linux系统中SSH服务基于key认证实践的过程 [db:标签] 碎碎语  第1张

  从上图可以看到,客户端上必须存在一对密钥对,我们都知道密钥是成对出现,况且用A的公钥加密只有A的私钥才可以解密。正是因为非对称加密的这个特性,我们不难理解ssh通信也是利用这个特性来确定数据安全的。在服务端也有一对公钥和私钥,它存在的目的也是为了加密和解密数据。ssh加密通讯的流程大致上这样的,客户端要和服务端加密通信,首先客户端需要拿到服务端的公钥,拿到服务端的公钥后,就可以用服务端的公钥对要发送到数据加密,然后发送到服务端,服务端收到这个密文的数据,它会用自己的私钥去解密,从而实现了客户端到服务端的数据加密。同理服务端要把数据发送给客户端也是一样的过程,拿到客户端的公钥用客户端的公钥加密,然后发给客户端,客户端用自己的私钥解密,从而实现了你来我往的加密通讯。

  我们想一下,服务端和客户端通讯都是用对方的公钥来加密数据,那么客户端是怎么拿到服务端的公钥的呢?服务端又是怎么样拿到客户端的公钥的呢?

  来看一下服务端和客户端在第一次连接的时候,公钥交换的过程

Linux系统中SSH服务基于key认证实践的过程 [db:标签] 碎碎语  第2张

  首先客户端向服务端发送ssh连接请求,服务端收到请求后,会把自己的公钥和会话ID 一并发送给客户端,客户端收到服务器发来的公钥后,它又把自己的公钥和服务器发送过来的会话ID 做异或运算,把得到的结果用服务端的公钥来加密,然后把加密后的密文通过网络发送给服务端,服务端收到客户端发送过来的密文后,它会用自己的私钥去解密,然后把得到的结果和之前的会话ID做异或计算,最终得到客户端的公钥。这样的一个过程后,客户端就拥有了服务端的公钥,服务端也拥有了客户端的公钥,有了对方的公钥后,后续就可以用对方的公钥来加密数据。

  使用过Linux的人都知道,在我们第一次和服务器建立ssh远程连接的时候,会有一个确认,问我们是否继续连接,我们输入yes后才能输入密码,这是我为什么呢?其实在服务端发送自己的公钥到客户端的时候,因为客户端没有办法确认它收到的公钥是不是对方服务器发送过来的,它就会把收到的公钥做md5和sha256,提取出公钥的指纹,然后提示我们说我收到了一份md5为xxx的公钥,请问你确认这个公钥吗?如果我们确认,就表示相信这个公钥是服务器发送过来的,这样一来才可以有下面的,把自己的公钥和会话ID做异或运算,把结果用刚才收到的公钥加密。我们想象,如果不是服务器发过来的公钥,而是黑客发送过来的公钥,如果我们确认了,后续的密文黑客拿到后,黑客就以用自己的私钥来解密,得到客户端的公钥和数据,然后他得到真正的数据后,黑客可以任意改动,然后再用服务器的公钥加密,发送给服务端,这样一来服务端得到的数据就是黑客修改后的数据,不是真正客户端发送的数据。这就是所谓的中间人攻击,它是利用自己的公钥来回冒充服务端和客户端角色。

  了解了ssh加密通讯的过程和密钥交换的过程,我们再来看看,ssh基于用户名口令和密钥登录验证的过程。

Linux系统中SSH服务基于key认证实践的过程 [db:标签] 碎碎语  第3张

  基于用户名口令登录是这样的流程:首先客户端发起ssh连接请求,服务端会把自己的公钥发送给客户端,客户端收到服务端的公钥后,把密码经过服务端的公钥加密后发送给服务端,服务端收到加密后的密码用自己的私钥进行解密,得到客户端发送过来的密码,然后它会拿这个密码进行验证,把验证的的结果用客户端的公钥加密并发送给客户端,客户端收到结果后,用自己的私钥解密,从而实现了验证过程,如果验证通过,那么客户端就登录成功,反之客户端登录失败。

Linux系统中SSH服务基于key认证实践的过程 [db:标签] 碎碎语  第4张

  基于密钥登录验证的过程是:首先客户端要生成一对密钥对(这个密钥对是针对的是用户,不是主机的公钥私钥,前面说到的都是主机的公钥和私钥),并手动的将生成的公钥添加到服务器(默认添加到服务器的某个用户家目录的.ssh/authorized_keys,我们要用那个用户连接服务器,就把公钥添加到那个用户的家目录的.ssh/authorized_keys文件中去),服务端有了客户端用户的公钥后,在客户端发起ssh连接请求的时候,服务端会生成一串随机字符,用相应的客户端用户的公钥加密此随机字符串,然后发送给客户端,客户端收到了服务端发送过来的加密的随机字符后,客户端就会用自己的私钥来解密,然后把解密后的随机字符发送给服务端,服务端收到客户端发送过来的随机字符后,它就会进行对比,如果和之前发送的随机字符相同,那么服务端就允许免密码登录。

  通过上面的介绍,不难发现我们要基于key验证登录,必须要在客户端生成一对用户密钥对,并且要将生成的用户公钥放在服务端的某一个用户的家目录的.ssh/authorized_keys文件中,这个用户就是我们将来用于key验证登录服务器的用户。接下来我们来试验试验。

  1、在客户端生成用户密钥对

[qiuhom@docker~]$ssh-keygen-trsaGeneratingpublic/privatersakeypair.Enterfileinwhichtosavethekey(/home/qiuhom/.ssh/id_rsa):Enterpassphrase(emptyfornopassphrase):Entersamepassphraseagain:Youridentificationhasbeensavedin/home/qiuhom/.ssh/id_rsa.Yourpublickeyhasbeensavedin/home/qiuhom/.ssh/id_rsa.pub.Thekeyfingerprintis:SHA256:CbICoBfN3670ucEBjhDR/ltyYoe/jJMIWCkCK5Lt5eAqiuhom@dockerThekey'srandomartimageis:+---[RSA2048]----+|.+=||+o+||++oo..o.||Bo=.o=.o..||+*.+o..oS||.E..B.=.||.+%o.||.=o+.||..+o|+----[SHA256]-----+[qiuhom@docker~]$ll.ssh/总用量8-rw-------1qiuhomqiuhom167511月216:54id_rsa-rw-r--r--1qiuhomqiuhom39511月216:54id_rsa.pub[qiuhom@docker~]$

  说明:在Linux里我们用ssh-keygen命令来生成用户密钥对,-t 选项表示以那种加密算法来生产密钥。生成好的密钥对,默认放在当前用户的家目录下.ssh/目录下,分别叫id_rsa 和id_rsa.pub,从名字上我们就可以知道id_rsa是私钥id_rsa.pub是公钥。心细的你一定看到,我们用ssh-keygen来生成密钥,它会问我们需要把密钥文件存放在什么地方默认是当前用户的家目录下的.ssh目录下,当然我们也可以用-f选项来指定存放的位置,除此之外它还让我们输入密码,这里的密码表示加密私钥的密码,我们都知道拿到对方的私钥是很危险,所以系统默认会提示我们,如果按回车就表示生成的私钥不加密,当然我们也可以用 -P(大写)选项来指定加密私钥的密码。

  2.把用户生成的公钥放到服务器的用户家目录里的.ssh/authorized_keys,我们可以用scp命令放到服务端去,也可以通过U盘拷贝过去,但是这样太麻烦。这里我们用专门的工具,ssh-copy-id来把用户公钥文件信息拷贝到服务端对应的用户家目录

[qiuhom@docker~]$ssh-copy-id-i.ssh/id_rsa.pubroot@192.168.0.151/usr/bin/ssh-copy-id:INFO:Sourceofkey(s)tobeinstalled:".ssh/id_rsa.pub"Theauthenticityofhost'192.168.0.151(192.168.0.151)'can'tbeestablished.RSAkeyfingerprintisSHA256:GuKvtBmWnYyxogf1nyNvp02ccon/doAKhVdF7Qy7PvA.RSAkeyfingerprintisMD5:88:cf:f9:df:37:16:d7:e2:c4:99:a4:97:ab:49:f0:8e.Areyousureyouwanttocontinueconnecting(yes/no)?yes/usr/bin/ssh-copy-id:INFO:attemptingtologinwiththenewkey(s),tofilteroutanythatarealreadyinstalled/usr/bin/ssh-copy-id:INFO:1key(s)remaintobeinstalled--ifyouarepromptednowitistoinstallthenewkeysroot@192.168.0.151'spassword:Numberofkey(s)added:1Nowtryloggingintothemachine,with:"ssh'root@192.168.0.151'"andchecktomakesurethatonlythekey(s)youwantedwereadded.[qiuhom@docker~]$

  说明:-i选项指定公钥文件的存放位置,默认是从当前用户的家目录下的.ssh/公钥文件名称。 因为我们拷贝公钥之前,服务端是没有客户端用户的公钥,所以我们拷贝用户公钥的时候,还需要输入密码进行验证。这里需要说明一点,我们上述实验服务端的sshd服务是默认工作在22端口,如果没有工作在默认端口需要用-p(小写)选项来指定端口。

到此我们就做好了ssh基于key免密码登录验证。

  在上面的密钥生成和发放都是基于人工去做的,这样一台两台服务器没有什么问题,但是服务器多了,怎么办呢?如果我们需要管理很多台服务器,我们这里就需要写脚本去完成了,以下提供本人写的脚本,实现的功能是自动生成密钥,并自动发送到指定的主机。

[qiuhom@docker~]$catssh_keygen.sh#!/bin/bashremote_host_ip=$1remote_host_user=$2remote_host_port=$3remote_host_passwd=$4local_rsa_file=~/.ssh/id_rsalocal_rsa_pub_file=~/.ssh/id_rsa.pub[$#-ne4]&&echo"Usage:sh$0RemotehostIpRemotehostUserRemotehostPortRemotehostPasswd"&&exit5[!-e${local_rsa_file}]&&ssh-keygen-trsa-P''-f${local_rsa_file}>/dev/null2>&1expect

标签

Linux系统中SSH服务基于key认证实践的过程
版权说明
免责声明:本文文章内容由技术导航发布,但不代表本站的观点和立场,具体内容可自行甄别.