ssh原理及使用

SSH简介

安全外壳协议(Secure Shell Protocol,简称SSH)是一种建立在应用层基础上的加密的网络传输协议,主要用来在客户端和服务器之间建立安全通信隧道。使用SSH进行远程登录,信息传输是加密的,即使信息被中途截获也不会泄露。

1
2
注:
* SSH仅仅是一个协议标准,其具体的实现有很多,既有开源实现的OpenSSH,也有商业实现方案。使用范围最广泛的当然是开源实现OpenSSH。

Linux下安装SSH Server

使用SSH时,被登录的主机需要安装并运行SSH Server。SSH实现有很多种,比如在Linux中可以用 OpenSSH:

1
2
3
4
sudo systemctl status ssh # 可以查看系统是否有ssh server可用
sudo apt-get install openssh-server #安装openssh
sudo systemctl enable ssh
sudo systemctl start ssh

数据加密方式

对数据进行加密的方式主要有两种:对称加密(密钥加密)和非对称加密(公钥加密)。

对称加密指加密解密使用的是同一套秘钥。Client端把密钥加密后发送给Server端,Server用同一套密钥解密。对称加密的加密强度比较高,很难破解。但是,Client数量庞大,很难保证密钥不泄漏。如果有一个Client端的密钥泄漏,那么整个系统的安全性就存在严重的漏洞。为了解决对称加密的漏洞,于是就产生了非对称加密。非对称加密有两个密钥:“公钥”和“私钥”。公钥加密后的密文,只能通过对应的私钥进行解密。想从公钥推理出私钥几乎不可能,所以非对称加密的安全性比较高。

SSH的加密原理中,使用了RSA非对称加密算法。

SSH工作原理

SSH 协议是基于客户端-服务器模型的,其工作过程如下:

  1. 客户端发起连接请求:首先,用户需要启动一个 SSH 客户端程序,并向服务器发起 SSH 连接请求。连接请求包含服务器的 IP 地址和用户的登录凭据(用户名和密码或 SSH 密钥)。

  2. 服务器响应连接请求:一旦服务器收到连接请求,它会检查用户提供的登录凭据。如果凭据验证成功,服务器就会向客户端发送加密的连接确认信息。

  3. 客户端和服务器建立加密连接:在收到连接确认信息后,客户端会生成一个随机的会话密钥,用于加密通信。然后,客户端会向服务器发送一个加密的请求,包含会话密钥和其他的连接信息。

  4. SSH 会话开始:一旦客户端和服务器成功建立加密连接,SSH 会话就开始了。在会话期间,客户端可以向服务器发送各种命令和数据,并接收服务器的响应。所有的通信都经过密钥加密,以确保数据安全。

  5. SSH 会话结束:当用户关闭 SSH 客户端程序时,SSH 会话就会结束。客户端程序会清除会话密钥和其他的临时数据,以确保不会有敏感信息留存在客户端。

img

远程登录模型

ssh安全验证原理,简单来说就是SSH Server会有一对密钥,公有密钥(PubKey)和私有密钥(PriKey)。当客户端用户请求连接服务器的ssh时,服务器会把公有密钥作为回应发送给请求连接的用户,私有密钥只在本地保管。然后客户端拿到公有密钥后用其加密目标用户的密码发送给服务器,服务器完成验证后建立连接。

客户端需发送以下命令并输入用户user123的密码即可:

1
ssh user123@server

大致过程如下图所示:

img

整个过程是这样的:
(1)远程主机收到用户的登录请求,把自己的公钥发给用户。
(2)用户使用这个公钥,将登录密码加密后,发送回来。
(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。

口令登录

客户端输入以下命令,

1
ssh user123@192.168.254.128

如果是客户端第一次连接服务器,那么在执行上述命令后,客户端会显示

1
2
3
4
The authenticity of host '192.168.254.128 (192.168.254.128)' can't be established.
ED25519 key fingerprint is SHA256:TRtIeYojTIb5o/2C2k8VRN7HrQ3xA8NioVO4H418ykM.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

并且在输入 yes 之后,经过比对后,如果用户接受这个远程主机的公钥,系统会出现一句提示语: Warning: Permanently added ‘192.168.254.128’ (ED25519) to the list of known hosts.

输入 yes 之后,就能连接到远程服务器了。

公钥登录

使用密码登录,每次都必须输入密码,非常麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。

所谓”公钥登录”,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求输入密码。

这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个:

$ssh-keygen

演示口令登录

演示公钥登录

安全性问题:

中间人攻击”(Man-in-the-middle attack)

SSH之所以能够保证安全,原因在于它采用了公钥加密,这个过程本身是安全的,但是实际用的时候存在一个风险:

如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的加密登录密码,再用自己的私钥解密成明文,用这个密码登录远程主机,那么SSH的安全机制就不存在了。

如图:

img

ssh针对中间人攻击的解决方法:

1
2
3
* 私有密钥是只有server才有的,也就是即使中间有人截获了步骤3中client发送的带有password信息的包,也没有办法破解得知user123的密码。

* 但是有可能有攻击者可以截获步骤1 client发送的请求包,从而伪装成 server发送自己的PubKey_attacker,然后 client 再向其发送自己用PubKey_attacker加密的password,就会被攻击者用PriKey_attacker 解密,从而得到password明文密码。所以一般要求用户在收到PubKey 时自行对比验证发送该公有密钥的主机是已知的安全主机。这就是为什么我们会看到 Are you sure you want to continue connecting (yes/no)?。 信任的主机一般都保存在$HOME/.ssh/known_hosts文件中。