ssh工作流程及其原理
SSH
SSH(Secure Shell Protocol,安全的壳的协议)它可以通过数据包加密技术将等待传输的数据包加密后再传输到网络上。ssh协议本身提供两个服务器功能:一个是类似telnet的远程连接使用shell的服务器;另一个就是类似ftp服务的sftp-server,提供更安全的ftp服务。
- telnet-明文传输-端口号23
- ssh-加密传输-端口号22
对称加密和非对称加密
- 对称加密
对称加密就是client和server双方使用同一个密钥进行加密和解密,正应如此,它才叫对称加密。
常见的对称加密算法:DES、AES、3DES等
优点:算法简单、加解密容易、效率高
缺点:安全性不高、如果密钥被窃取,密文很容易被破解 - 非对称加密
非对称加密有两个密钥,一个公钥,一个私钥。公钥公开给所有人,但是私钥必须严格保密。公钥和私钥都可以用来加解密,但是公钥加密之后的密文只能由私钥来解密,反之亦是如此。client将通过公钥加密后的密文发给server,server通过私钥来解密密文。彻底解决了对称加密中密钥传输中容易被窃取的问题。
常见的非对称加密:RSA、ECC
优点:安全,黑客无法通过拦截获取密钥,也就无法解密密文
缺点:加密算法复杂,安全性以来算法和密钥,效率低
ssh工作流程
再整个ssh工作流程中,为实现ssh的安全连接,server与client要经历五个阶段:
版本号协商阶段 | SSH目前包括SSH1和SSH2两个版本,双方通过版本协商确定使用的版本 |
密钥和算法协商阶段 | SSH支持多种加密算法,双方根据本端和对端支持的算法,协商出最终使用的算法 |
认证阶段 | SSH客户端向服务器端发起认证请求,服务器端对客户端进行认证 |
会话请求阶段 | 认证通过后,客户端向服务器端发送会话请求 |
交互会话阶段 | 会话请求通过后,服务器端和客户端进行信息的交互 |
版本协商阶段
- server端打开端口22,等待client连接
- client向server端发起Tcp初始连接请求,Tcp建立连接后,server向client发送第一个报文,包括版本标志字符串,格式为“SSH-<主协议版本号><次协议版本号><软件版本号>”,协议版本号由主版本号和次版本号组成,软件版本号主要为调试使用。
- client收到报文后,解析该数据包,如果server的协议版本号比自己的低,且client能支持server的低版本,就使用server的低版本协议号。否则使用自己的协议版本号。
- client回复server的第一个报文,包含了client决定使用的协议版本号。server比骄client发过来的协议版本号,决定是否同client一起工作。如果协商成功,则进入密钥和算法协商阶段,否则server断开Tcp连接。
说明:上述的所有报文都采用明文传输
密钥和算法协商阶段
- server和client分别发送算法协议报文给对方,报文中包含自己支持的公钥算法列表、加密算法列表、MAC算法列表、压缩算法列表等等
- server和client根据对端和本段支持的算法列表得出最终使用的算法
- server和client利用DH交换算法、主机密钥对等参数,生成会话密钥和会话ID。
由此,server和client就取得了相同的会话密钥和会话ID。对于后续传输的数据,两端都会使用会话密钥进行加解密,保证了数据传输的安全,再认证阶段,两端会使用会话用于认证过程
会话密钥的生成
- client请求连接server,server将公钥发送给client。
- server生成会话ID,并将会话ID发送给client
- 若client第一次连接到此server,则会将server的公钥数据记录到client的用户主目录内的~/.ssh/known_hosts。若是已经记录过该服务器的公钥数据,则客户端会去比对此次接收到的与之前的记录是否有差异。client生成会话密钥,并用服务器的公钥加密后,发送给server。
- server用自己的私钥将收到的数据解密,获得会话密钥。
- server和client都知道了会话密钥,以后的传输都将被会话密钥加密
认证阶段
SSH提供两种认证方法:
- 基于口令的认证(password认证):client向server发出password认证请求,将用户名和密码加密后发送给server,server将该信息解密后得到用户名和密码的明文,与设备上保存的用户名和密码进行比较,并返回认证成功或失败消息。
- 基于密钥的认证(publickey认证):client产生一对公共密钥,将公钥保存到将要登录的server上的那个账号的家目录的.ssh/authorized_keys文件中。认证阶段:client首先将公钥传给server端。server端收到公钥后会与本地该账号家目录下的authorized_keys中的公钥进行对比,如果不相同,则认证失败;否则server生成一段随机字符串,并先后用client公钥和会话密钥对其加密,发送给client。client收到后将解密后的随机字符串用会话密钥发送给server。如果发回的字符串与server端之前生成的一样,则认证通过,否则,认证失败。
ssh免密登录
- 本地client生成公私钥
[root@node1 .ssh]# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:TcWomPIpvx1dCl4AXso8cekYDpPiOJvSvCgAoE+RIMM root@node1 The key's randomart image is: +---[RSA 3072]----+ |=. . .o o. o. | |oE+ ++.*. ... | |oo o +**... | |= o . =.o+ | |.O o .S o . | |= + . o. + o | |o. . o o o | |o . .. . | |. ... | +----[SHA256]-----+
- 可以看见在~/.ssh下生成了两个文件
[root@node1 .ssh]# ll 总用量 8 -rw-------. 1 root root 2590 10月 17 16:17 id_rsa -rw-r--r--. 1 root root 564 10月 17 16:17 id_rsa.pub
- 上传公钥到server
[root@node1 .ssh]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.133.150 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" The authenticity of host '192.168.133.150 (192.168.133.150)' can't be established. ECDSA key fingerprint is SHA256:Sua4JrcWKpvMpdUgK0I93xAHHfHDVo16/eFjC0IjafY. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@192.168.133.150's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'root@192.168.133.150'" and check to make sure that only the key(s) you wanted were added.
- 我们可以在server的~/.ssh下看见
[root@localhost .ssh]# ll total 4 -rw-------. 1 root root 564 Oct 17 16:20 authorized_keys
- 测试客户端免密登录
[root@node1 .ssh]# ssh 192.168.133.150 ???????????????????????????????? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ################################ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Activate the web console with: systemctl enable --now cockpit.socket This system is not registered to Red Hat Insights. See https://cloud.redhat.com/ To register this system, run: insights-client --register Last login: Mon Oct 17 16:10:42 2022 from 192.168.133.1 [root@localhost ~]#