SSH 原理

引用自

用法

$ ssh username@remotehost

原理

  1. 公钥加密技术

    1. 用户请求登陆远程主机(通过ssh)
    2. 远程主机收到用户的登陆请求,把自己的公钥发给用户。
    3. 用户使用这个公钥,将登陆密码加密后,发送给远程主机。
    4. 远程主机用自己的私钥,解密,如果密码正确,则同意登陆。
  2. 中间人攻击

    1. 假设有人截获了用户发送的登陆请求,然后冒充远程主机,发送了伪造的公钥给用户,由于ssh协议不是像https那样有证书中心(CA)公证,所以用户很难知道真伪。
    2. 如果用户没有发现是假的,将自己的密码通过伪造的公钥加密后发送给伪造远程主机,那么远程主机通过自己的私钥解密后,则知道了用户的登陆密码。
    3. 所以,ssh使用了口令登陆和公钥登陆。
  3. 口令登陆

    1. 第一次登陆远程主机时,系统会提示:
    1
    2
    3
    4
    $ ssh username@remotehost
      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)?

    系统会将对方发过来的公钥通过md5计算,生成一个128位的公钥指纹。一般是需要远程主机提供自己的公钥指纹,如在网站上公布,用户自行对比。若接受这个公钥,则下一步则提示输入密码。

    1. 远程主机的公钥被用户接受后,会在保存在本地的$HOME/.ssh/known_hosts中,下次再连接该主机的时候,系统会认出它的公钥已经保存在本地,跳过警告部分,直接提示输入密码。
  4. 公钥登陆

    1. 用户将自己的公钥存储在远程主机上,登陆的时候,远程主机向用户发送一段随机字符串,用户用自己的私钥加密该字符串,发送给远程主机。远程主机用用户事先存储在本地的公钥进行解密,若成功即验证成功。不再需要密码。那么如何生成公钥并发送给远程主机呢?步骤如下:

      1. 用户自己生成公钥:$ ssh-keygen
      2. 运行完该命令后,会在$HOME/.ssh/目录下,生成两个文件:id_rsa.pubid_rsa,前者是公钥,后者是私钥。
      3. 将公钥传送给远程主机:$ ssh-copy-id username@remotehost

      自此,就可以通过公钥登陆方式来登陆,而不需要输入密码。

    2. 远程主机会将用户的公钥追加到$HOME/.ssh/authorized_keys文件中的末尾。

SSH本地端口转发

主机A与主机B之间无法互相连接,主机C可以与A、B互相通信。

在主机A上:

$ ssh -L 需要监听的本地端口:目的主机ip:目的主机端口 远程主机ip

例子:

$ ssh -L 2121:B:21 C

原理:

  1. A向本地端口2121发送数据。
  2. A上的本地ssh客户端读2121端口,加密数据,将其通过ssh连接传到C上的ssh服务器。
  3. C上的ssh服务器将数据解密,将其传到主机B的21端口,即(B, 21)。
  4. 主机B将数据返回给C的ssh服务器,然后C将其加密,传给A的ssh客户端,A端的ssh客户端将数据转到本地端口2121。

从而达到 (A, 2121)<----> (B, 21)的互相通信的效果。

SSH远程端口转发

$ ssh -R 需要监听的远程端口:目的主机ip:目的主机端口 远程主机ip

例子(在C上运行该命令):

$ ssh -R 2121:localhost:21 A

原理:与上述相同。

本地端口转发和远程转发的区别(ssh权威指南P376)

  • 当应用程序客户端位于ssh连接本地时使用本地端口转发。
  • 当应用程序客户端位于ssh远程服务器的时候使用远程转发。