文档中心 > 云服务器 ECS

云服务器 ECS Linux SSH 无法远程登录问题排查指引与 SSH 原理概述

更新时间: 访问次数:7730

本文先说明云服务器 ECS Linux 服务器 SSH 无法远程登录问题的排查思路,然后 SSH 服务的相关背景知识进行说明。

注意:本文相关配置及说明已在 CentOS 6.5 64 位操作系统中进行过测试。其它类型及版本操作系统配置可能有所差异,具体情况请参阅相应操作系统官方文档。

 

SSH 无法远程登录问题排查指引

对于云服务器 ECS LinuxSSH 客户端是主要的运维途径。而 管理终端 可以用于临时运维,或者在客户端登录出现异常时,用于问题排查分析。本文就 SSH 无法登录的可能原因及排查方法进行说明。

SSH 登录关联因素示意图

 

SSH 无法登录常见现象及处理办法

针对前述不同因素,常见的问题现象及处理办法说明如下:

客户端问题

客户端无法正常登录时,建议先使用不同的 SSH 客户端基于相同账户信息进行登录测试。如果能正常登录,则判断是客户端配置问题,则需要对客户端配置或软件运行情况做排查分析。

ECS Linux 服务器的登录过程说明,可以参阅产品文档:登录实例

中间网络问题

客户端无法正常通过 SSH 连接服务器时,先通过如下方式进行 telnet 端口测试,判断是否是中间网络异常所致:

1
2
3
4
5
<ol class="linenums">
  
 <li class="L0"><span class="pln">telnet </span><span class="pun"><服务器</span><span class="pln"> IP</span><span class="pun">></span><span class="pln"> </span><span class="pun"><</span><span class="pln">SSH </span><span class="pun">服务端口>比如:</span><span class="pln">telnet </span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> </span><span class="lit">22</span></li>
 
</ol>

正常情况下,如下图所示,会返回服务端 SSH 软件版本号:

如果端口测试失败,则可以参阅如下文档针对客户端到服务器之间的网络做进一步排查分析:

PAM 安全框架相关问题

Linux 系统的 PAM 安全框架,可以加载相关安全模块,对服务器的账户策略、登录策略等进行访问控制。如果相关配置存在异常,或触发了相关策略,就可能会导致 SSH 登录失败。与PAM 安全框架相关的常见案例如下:

Linux 系统环境配置问题

Linux 内的系统环境(比如中毒、账户配置、环境变量配置等)如果出现异常,也可能会导致 SSH 登录失败。与 Linux 系统环境相关的常见案例如下:

SSH 服务及参数配置问题

SSH 服务的默认配置文件为 /etc/ssh/sshd_config。配置文件中的相关参数配置异常,或启用了相关特性或策略,也可能会导致 SSH 登录失败。与 SSH 服务及参数配置相关的常见案例如下:

SSH 服务关联目录或文件配置问题

SSH 服务基于安全性考虑,在运行时,会对相关目录或文件的权限配置、属组等进行检查。过高或过低的权限配置,都可能会引发服务运行异常,进而导致客户端登录失败。与 SSH 服务关联目录或文件配置相关的常见案例如下:

SSH 服务密钥配置问题

SSH 服务采用非对称加密技术,对所传输的数据进行加密。客户端及服务端会交换和校验相关密钥信息的有效性。 SSH 服务密钥配置相关的常见案例如下:

SSH 无法登录问题排查思路

如果根据前述问题场景进行排查和处理后,还是无法正常登录。则建议按照如下步骤进行逐一排查分析:

  1. 多客户端对比测试:
    使用不同的 SSH 客户端及 管理终端 做对比访问测试,以判断是否是个别客户端自身配置或软件运行问题所致。如果管理终端登录正常,也可以通过管理终端进入系统做进一步排查分析。
  2. 网络测试:
    参阅前文中间网络问题小节相关说明,测试网络连通性。
  3. 服务端日志获取:
    通过 管理终端 进入服务器。然后在客户端重新访问测试时,通过如下指令同步获取服务端相关日志信息:
    1
    2
    3
    4
    5
    <ol class="linenums">
      
     <li class="L0"><span class="pln">tailf </span><span class="pun">/</span><span class="pln">var</span><span class="pun">/</span><span class="pln">log</span><span class="pun">/</span><span class="pln">secure</span></li>
     
    </ol>
  4. 客户端日志获取:
    如果客户端是 Linux 环境,则可以通过如下指令,获取详细的 SSH 登录交互日志:
    1
    2
    3
    4
    5
    <ol class="linenums">
      
     <li class="L0"><span class="pln">ssh </span><span class="pun">-</span><span class="pln">vvv </span><span class="pun"><服务器</span><span class="pln"> IP</span><span class="pun">></span><br><br><span class="pun">比如:</span><br><span class="pun">[</span><span class="pln">root@centos</span><span class="pun">~]#</span><span class="pln"> ssh </span><span class="pun">-</span><span class="pln">vvv </span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">0.1</span><br><span class="typ">OpenSSH_5</span><span class="pun">.</span><span class="lit">3p1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">OpenSSL</span><span class="pln"> </span><span class="lit">1.0</span><span class="pun">.</span><span class="lit">1e</span><span class="pun">-</span><span class="pln">fips </span><span class="lit">11</span><span class="pln"> </span><span class="typ">Feb</span><span class="pln"> </span><span class="lit">2013</span><br><span class="pln">debug1</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Reading</span><span class="pln"> configuration data </span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">ssh_config</span><br><span class="pln">debug1</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Applying</span><span class="pln"> options </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">*</span><br><span class="pln">debug2</span><span class="pun">:</span><span class="pln"> ssh_connect</span><span class="pun">:</span><span class="pln"> needpriv </span><span class="lit">0</span><br><span class="pln">debug1</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Connecting</span><span class="pln"> to </span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> </span><span class="pun">[</span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">0.1</span><span class="pun">]</span><span class="pln"> port </span><span class="lit">22.</span><br><span class="pln">debug1</span><span class="pun">:</span><span class="pln"> connect to address </span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> port </span><span class="lit">22</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Connection</span><span class="pln"> timed out</span><br><span class="pln">ssh</span><span class="pun">:</span><span class="pln"> connect to host </span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> port </span><span class="lit">22</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Connection</span><span class="pln"> timed out</span></li>
     
    </ol>
  5. SSH 服务运行状态检查:
    通过
    管理终端 登录服务器,然后通过如下方式检查 SSH 服务运行状态:
    • 检查服务运行状态:
      通过如下指令检查服务运行状态。正常情况下会返回运行状态及相应进程
      PID
      1
      2
      3
      4
      5
      <ol class="linenums">
        
       <li class="L0"><span class="pun">[</span><span class="pln">root@centos </span><span class="pun">~]#</span><span class="pln"> service sshd status</span><br><span class="pln">openssh</span><span class="pun">-</span><span class="pln">daemon </span><span class="pun">(</span><span class="pln">pid  </span><span class="lit">31350</span><span class="pun">)</span><span class="pln"> is running</span><span class="pun">…</span><br><span class="pun">[</span><span class="pln">root@centos </span><span class="pun">~]#</span><span class="pln"> service sshd restart</span><br><span class="typ">Stopping</span><span class="pln"> sshd</span><span class="pun">:</span><span class="pln">                                             </span><span class="pun">[</span><span class="pln">  OK  </span><span class="pun">]</span><br><span class="typ">Starting</span><span class="pln"> sshd</span><span class="pun">:</span><span class="pln">                                             </span><span class="pun">[</span><span class="pln">  OK  </span><span class="pun">]</span></li>
       
      </ol>

       

    • 检查服务监听状态:
      通过如下指令检查服务监听状态。正常情况下会返回相应端口监听信息:
      1
      2
      3
      4
      5
      <ol class="linenums">
        
       <li class="L0"><span class="pln">netstat </span><span class="pun">-</span><span class="pln">ano </span><span class="pun">|</span><span class="pln"> grep </span><span class="lit">0.0</span><span class="pun">.</span><span class="lit">0.0</span><span class="pun">:</span><span class="lit">22</span><br><span class="pln">tcp        </span><span class="lit">0</span><span class="pln">      </span><span class="lit">0</span><span class="pln"> </span><span class="lit">0.0</span><span class="pun">.</span><span class="lit">0.0</span><span class="pun">:</span><span class="lit">22</span><span class="pln">                  </span><span class="lit">0.0</span><span class="pun">.</span><span class="lit">0.0</span><span class="pun">:*</span><span class="pln">                   LISTEN      off </span><span class="pun">(</span><span class="lit">0.00</span><span class="pun">/</span><span class="lit">0</span><span class="pun">/</span><span class="lit">0</span><span class="pun">)</span></li>
       
      </ol>

       

    • 127.0.0.1 登录测试:
      通过
      管理终端 登录服务器,然后 ssh 127.0.0.1。如果能正常登录,则推断是系统防火墙或外部安全组策略等配置异常,导致客户端登录失败。


SSH 连接交互过程简介

注意:本文相关配置及说明已在 CentOS 6.5 64 位操作系统中进行过测试。其它类型及版本操作系统配置可能有所差异,具体情况请参阅相应操作系统官方文档。

SSH 服务在进行数据传输前,会先进行密钥交换和协商确认。完成后再对后续数据进行加密传输,以提高安全性。本文先对 SSH 服务所采用的非对称加密技术进行简要介绍,然后对 SSH 连接过程中的相关交互,及关联文件进行说明。

 

非对称加密技术

SSH 服务基于非对称加密public-key cryptography,也称公开密钥加密)技术实现数据加密传输。该技术会生成一对数学相关的密钥,其中一个用于对数据进行加密,而且只能用于加密,而另一个只能用于解密。使用加密密钥加密后的数据,只能用对应的解密密钥才能解密。而且,只知道其中一个密钥,无法计算出另一个。因此,如果公开了一对密钥中的一个,并不会危害到另一个的秘密性质。通常把公开的密钥称为公钥public key,而不公开的密钥称为私钥private key)。

如果公开的是解密密钥,该场景用于客户端验证持有私钥一方发布的数据或文件的完整性、准确性,以防止数据篡改。相应的密钥称为数字签名(数字证书)。如果公开的是加密密钥,该场景用于客户给私钥所有者上传数据,称为公开密钥加密。 SSH 服务基于该场景实现。

对称密钥加密相比,非对称加密的优点在于不存在共享的通用密钥。由于解密用的私钥无需发送给任何用户,所以可以避免密钥被劫持或篡改。而加密用的公钥即便被劫持或篡改,如果没有与其匹配的私钥,也无法解密数据。所以,截获的公钥是没有任何用处的。

当前,SSH主要采用 RSA 算法(协议 V2 默认算法)和 DSA 算法(协议 V1 仅支持该算法)来实现非对称加密技术。

 

连接交互过程

SSH 服务建立连接时的相关交互过程,如下SSH 服务连接交互示意图 所示:

连接过程中的相关交互步骤,详细说明如下。

服务端准备阶段

服务端在每次启动 SSH 服务时,都会自动检查 /etc/ssh/ 目录下相关密钥文件的有效性。如果相关文件检查发现异常,则会导致服务启动失败,并抛出相应错误信息。 如果文件相关不存在,则会自动重新创建。

默认创建的相关文件及用途说明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<ol class="linenums">
  
 <li class="L0"><span class="pln">ll </span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln">ssh</span><span class="pun">/</span><br><code><span class="pln">bash</span></code></li>
  
 <li class="L1"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-------.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root </span><span class="lit">125811</span><span class="pln"> </span><span class="typ">Aug</span><span class="pln"> </span><span class="lit">13</span><span class="pln">  </span><span class="lit">2015</span><span class="pln"> moduli            </span><span class="pun">→</span><span class="pln"> </span><span class="pun">用于</span><span class="pln"> DH</span><span class="pun">-</span><span class="pln">GEX </span><span class="pun">算法<</span><span class="pln">br</span><span class="pun">></span></code></li>
  
 <li class="L2"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln">r</span><span class="pun">--.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root   </span><span class="lit">2047</span><span class="pln"> </span><span class="typ">Aug</span><span class="pln"> </span><span class="lit">13</span><span class="pln">  </span><span class="lit">2015</span><span class="pln"> ssh_config            </span><span class="pun">→</span><span class="pln"> SSH </span><span class="pun">客户端配置文件<</span><span class="pln">br</span><span class="pun">></span></code></li>
  
 <li class="L3"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-------.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root   </span><span class="lit">3879</span><span class="pln"> </span><span class="typ">Aug</span><span class="pln"> </span><span class="lit">13</span><span class="pln">  </span><span class="lit">2015</span><span class="pln"> sshd_config            </span><span class="pun">→</span><span class="pln"> SSH </span><span class="pun">服务配置文件<</span><span class="pln">br</span><span class="pun">></span></code></li>
  
 <li class="L4"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-------.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root    </span><span class="lit">672</span><span class="pln"> </span><span class="typ">May</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> </span><span class="lit">14</span><span class="pun">:</span><span class="lit">22</span><span class="pln"> ssh_host_dsa_key        </span><span class="pun">→</span><span class="pln"> DSA </span><span class="pun">算法私钥<</span><span class="pln">br</span><span class="pun">></span></code></li>
  
 <li class="L5"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln">r</span><span class="pun">--.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root    </span><span class="lit">590</span><span class="pln"> </span><span class="typ">May</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> </span><span class="lit">14</span><span class="pun">:</span><span class="lit">22</span><span class="pln"> ssh_host_dsa_key</span><span class="pun">.</span><span class="pln">pub            </span><span class="pun">→</span><span class="pln"> DSA </span><span class="pun">算法公钥<</span><span class="pln">br</span><span class="pun">></span></code></li>
  
 <li class="L6"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-------.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root    </span><span class="lit">963</span><span class="pln"> </span><span class="typ">May</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> </span><span class="lit">14</span><span class="pun">:</span><span class="lit">22</span><span class="pln"> ssh_host_key            </span><span class="pun">→</span><span class="pln"> SSH V1 </span><span class="pun">版</span><span class="pln">RSA </span><span class="pun">算法私钥<</span><span class="pln">br</span><span class="pun">></span></code></li>
  
 <li class="L7"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln">r</span><span class="pun">--.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root    </span><span class="lit">627</span><span class="pln"> </span><span class="typ">May</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> </span><span class="lit">14</span><span class="pun">:</span><span class="lit">22</span><span class="pln"> ssh_host_key</span><span class="pun">.</span><span class="pln">pub        </span><span class="pun">→</span><span class="pln"> SSH V1 </span><span class="pun">版</span><span class="pln"> RSA </span><span class="pun">算法公钥<</span><span class="pln">br</span><span class="pun">></span></code></li>
  
 <li class="L8"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-------.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root   </span><span class="lit">1675</span><span class="pln"> </span><span class="typ">May</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> </span><span class="lit">14</span><span class="pun">:</span><span class="lit">22</span><span class="pln"> ssh_host_rsa_key        </span><span class="pun">→</span><span class="pln"> SSH V2 </span><span class="pun">版</span><span class="pln"> RSA </span><span class="pun">算法私钥<</span><span class="pln">br</span><span class="pun">></span></code></li>
  
 <li class="L9"><code><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln">r</span><span class="pun">--.</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> root root    </span><span class="lit">382</span><span class="pln"> </span><span class="typ">May</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> </span><span class="lit">14</span><span class="pun">:</span><span class="lit">22</span><span class="pln"> ssh_host_rsa_key</span><span class="pun">.</span><span class="pln">pub            </span><span class="pun">→</span><span class="pln"> SSH V2 </span><span class="pun">版</span><span class="pln"> RSA </span><span class="pun">算法公钥</span></code></li>
 
</ol>

非对称加密协商

服务端 SSH 服务正常运行后,客户端连接时,进行如下交互:

  1. 客户端向服务端发送连接请求。
    客户端通过 SSH 工具连接服务端。相关信息通过明文发送。
  2. 服务端返回公钥信息:
    根据客户端所使用的服务协议版本及算法设置,返回相应公钥信息。比如,默认情况下,客户端通过 SSH V2 版协议,基于 RSA 算法建立连接,则服务端将 ssh_host_rsa_key.pub文件中的内容返回客户端。相关信息通过明文发送。
  3. 客户端对服务端公钥信息进行比对和确认:
    客户端接收到服务端公钥信息后,会进行如下比对,并让用户对相关信息进行确认。
    • 如果是首次连接服务端,客户端会收到类似如下信息,让用户确认公钥指纹的有效性:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      <ol class="linenums">
        
       <li class="L0"><code><span class="pln">bash</span></code></li>
        
       <li class="L1"><code><span class="typ">The</span><span class="pln"> authenticity of host </span><span class="str">'192.168.0.1 (192.168.0.1)'</span><span class="pln"> can</span><span class="str">'t be established.</span></code></li>
        
       <li class="L2"><code><span class="str">RSA key fingerprint is c2:49:d9:43:74:d5:ed:bc:28:9b:d2:7b:63:94:cf:bc.</span></code></li>
        
       <li class="L3"><code><span class="str">Are you sure you want to continue connecting (yes/no)?</span></code></li>
       
      </ol>
       
      1. 如果用户输入 no ,则连接中断并报错(Host key verification failed)。
      • 如果用户输入 yes,则会将相应的公钥信息,保存到当前用户家目录下 .ssh 目录内的 known_hosts 文件中。 比如:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        <ol class="linenums">
          
         <li class="L0"><code><span class="pln">bash</span></code></li>
          
         <li class="L1"><code><span class="pln">cat </span><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">known_hosts</span></code></li>
          
         <li class="L2"><code></code></li>
          
         <li class="L3"><code><span class="pln">IP </span><span class="pun">明文显示:</span></code></li>
          
         <li class="L4"><code><span class="lit">192.168</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> ssh</span><span class="pun">-</span><span class="pln">rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3sdlboGEgY9buZpkPuygPw0NxAvmxYd0mc3fo2MgP</span><span class="pun">+</span><span class="typ">JqgFC9</span><span class="pun">/</span><span class="lit">9ZXOgDXKJrjE2HKBieJZSPKGncIh</span><span class="pun">+</span><span class="pln">zLxTvmykeJQBXv7i1GiUjW</span><span class="pun">+</span><span class="pln">H3VY69Ge3AdGfCd</span><span class="pun">+</span><span class="pln">XF</span><span class="pun">+</span><span class="typ">Cvi1e</span><span class="pun">+</span><span class="pln">j18zhHnjSzvIBoNpT5cBWWNbw7mNHCwTb0sHAVUkWR4Ck</span><span class="pun">/</span><span class="pln">LM5</span><span class="pun">/</span><span class="pln">rQ09A</span><span class="pun">+</span><span class="pln">m6BLfZJL8CRNGxKTbyINi6o812S</span><span class="pun">+</span><span class="typ">Cy64WqDs1nTpIXp2Bkcpjclb36bFSs9Z</span><span class="pun">/</span><span class="pln">tWNuJl7A</span><span class="pun">//</span><span class="lit">7HNtxMgFGBnE07Ykvvy8s06DUmkyFy8GcXGBpnfdg9utLodfQLFQnKflCQZ110BpQaCWlWPjU9dc4w3XLJ</span><span class="pun">/</span><span class="pln">XQOP4w</span><span class="pun">==</span></code></li>
          
         <li class="L5"><code></code></li>
          
         <li class="L6"><code><span class="pln">IP </span><span class="pun">做了加密处理:</span></code></li>
          
         <li class="L7"><code><span class="pun">|</span><span class="lit">1</span><span class="pun">|</span><span class="lit">3efXAZ4sNHcUcHamBy4gDriblc8</span><span class="pun">=|</span><span class="lit">8idBhLq9aLl2sfh4KswMsk4sPFI</span><span class="pun">=</span><span class="pln"> ssh</span><span class="pun">-</span><span class="pln">rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwS4DE3hok8RCkxYlTxsexNrNa62e05UGSkoP7ie26DDWjG1Aoc74cCsE4is9p7lEfFUYYlAzeYhPqE</span><span class="pun">/</span><span class="pln">yGf5YxRZUOU2IeFI4cEqo8YZr7edVYpgAq2f2J0zMwk1syenD12lmUPkYA4mMB6it3jxXR5k</span><span class="pun">+</span><span class="pln">H0HZh9YA7mRXkiTjlkAMWirBcnUvtKYRv9LRIr3ikUiPy2gfZO291Ae9zuTsWwEtHQxIpiBgk3vwF2gCUFlX9y</span><span class="pun">//</span><span class="typ">IsMjdQq5prk7x3BjXhUorqgJO1gt1VHW8Xxx9Oe50YF1hi9DuE6VXwyh4xfHTmauRQybwsYafdA3HxrA2od6x9l19D9EH7xHAjDa5w</span><span class="pun">==</span></code></li>
         
        </ol>
    • 如果服务端因重装系统等因素导致公钥指纹出现变化,则会直接导致连接失败(报错Host key verification failed),则需要删除已保存的条目后再重新连接。 相关操作可以参阅 云服务器 ECS Linux 客户端 SSH 公钥指纹不匹配导致 SSH 登录失败
    • 如果之前已经成功连接,而且公钥指纹对比一致,则会继续下一步操作。 
  4. 客户端生成临时密钥对:
    服务端公钥校验及确认后,客户端会生成一对临时密钥用于客户端加密。该密钥对不会存储到文件,而是记录在内存中。每次连接都会重新生成临时密钥对。

  5. 客户端发送公钥信息:
    客户端向服务端,发送前述生成的临时密钥对中的公钥信息。相关信息通过明文发送。

至此,服务端及客户端都拥有对方的公钥和自身的私钥,所以称为非对称加密。

后续数据交互过程

后续登录校验及正常的数据传输,都会通过双向加密方式进行。相关交互说明如下:

  • 如果服务端需要发送数据给客户端:
    • 服务端使用所持有的客户端公钥,对需要传输的数据进行加密,再发送给客户端。
    • 客户端收到信息后,使用所持有的自身私钥解密后获取数据。
  • 反之,如果客户端需要发送数据给服务端,也是类似的流程:
    • 客户端使用所持有的服务端公钥,对需要传输的数据进行加密,再发送给服务端。
    • 服务端收到信息后,使用所持有的自身私钥解密后获取数据。

 

SSH 基于密钥交换的自动登录原理简介及配置说明

注意:本文相关配置及说明已在 CentOS 6.5 64 位操作系统中进行过测试。其它类型及版本操作系统配置可能有所差异,具体情况请参阅相应操作系统官方文档。

 

SSH 服务可以对所有传输的数据进行加密,提供比传统 telnet 服务更高的安全性(更多关于SSH 服务的连接交互过程,可以参阅 云服务器 ECS Linux SSH 连接交互过程简介)。而基于密钥认证的 SSH 自动化登录,在保障安全性的同时,可以简化登录过程,降低运维成本。本文先简要介绍基于密钥交换的 SSH 自动登录的原理,然后对配置方法进行说明。

 

原理简介

SSH证书认证登录的基础是一对唯一匹配密钥: 私钥private key)和公钥public key)。公钥用于对数据进行加密,而且只能用于加密。而私钥只能对使用所匹配的公钥,所加密过的数据进行解密。私钥需要用户单独妥善保管。SSH 客户端使用私钥向服务器证明自已的身份。而公钥是公开的,可以按需将其配置到目标服务器上自己的相应帐号中。

在进行 SSH 登录认证时,进行私钥和公钥协商。如果匹配,则身份得以证明,认证成功,允许登录。否则,将会继续使用密码验证等其它方式进行登录校验。SSH 证书验证登录配置及登录协商过程,如下证书校验交互登录流程示意图所示:

各步骤补充说明如下:

生成证书

  1. 客户端生成密钥对。
  2. 将公钥信息写入目标服务器、目标账户的配置文件。该操作隐含表示了客户端拥有对目标服务器的控制权。

协商交互过程

  1.  客户端向目标服务器发送登录请求。在SSH 服务启用了证书验证登录方式后,会优先通过证书验证方式进行登录验证。 

  2. 目标服务器根据 SSH 服务配置,在用户对应目录及文件中读取到有效的公钥信息。
  3. 目标服务器生成一串随机数,然后使用相应的公钥对其加密。

  4. 目标服务器将加密后的密文发回客户端。

  5. 客户端使用默认目录或 -i 参数指定的私钥尝试解密。

  6. 如果解密失败,则会继续尝试密码验证等其它方式进行登录校验。如果解密成功,则将解密后的原文信息重新发送给目标服务器。意思类似于: 看,这是这段话的原文。我能读懂发过来的密文,我拥有服务器的控制权,请让我登录。

  7. 目标服务器对客户端返回的信息进行比对。如果比对成功,则表示认证成功,客户端可以登录。如果对比失败,则表示认证失败,则会继续尝试密码验证等其它方式进行登录校验。

 

自动登录配置

生成密钥对

SSH 协议 V1只使用 RSA 算法,而 SSH 协议V2 RSA 算法和 DSA 算法都支持。目前所有OpenSSH 版本都应该对两种算法都支持。两种算法的密钥的生成指令和使用方法相同,本文仅以 RSA 算法为例进行相关说明。

生成密钥对的时候,可以按需决定是否设置密码。但需要注意的是,如果设置了密码,还需结合 ssh-agent 代理和 ssh-add 配置才能实现自动登录。同时,相关配置只对 ssh-agent 启动的相应 shell 生效,用户退出后重新登录时还需重新配置。所以,为简便起见,本文以常见的、不配置密码的情况进行说明。

可以在任意支持环境下生成密钥对。Windows Linux 环境下,配置分别说明如下。

Windows 环境下生成密钥对

在 Windows 环境下,通常借助各种应用软件来创建和管理密钥对。以常见的 PuTTYgen 为例,请执行如下步骤创建密钥对:

  1. 启动 PuTTYgen。本示例中的 PuTTYgen 版本为 0.68。
  2. Parameters > Type of key to generate 中,选中 RSANumber of bits in a generated key 的值不需要设置,软件会根据导入的私钥信息自动更新。
    ECS _ SSH Key Pair _ 导入私钥参数
  3. 单击 Load。PuTTYgen 默认仅显示扩展名为 .ppk 的文件。要找到您的 .pem 文件,请选择显示所有类型的文件。
    ECS _ SSH Key Pair _ 打开待导入的私钥文件
  4. 选择您从阿里云下载的“.pem”格式的私钥文件,然后单击 打开
    ECS _ SSH Key Pair _ 载入pem文件
  5. 单击 OK(确定)关闭确认对话框。
  6. 单击 Save private key。PuTTYgen 会显示一条关于在没有口令的情况下保存密钥的警告,单击 是(Y)
    ECS _ SSH Key Pair _ 保存私钥
  7. 指定与密钥对相同的私钥名称,保存。PuTTY 会自动为文件添加 .ppk 扩展名。

Linux 环境下生成密钥对

Linux 环境下,通常使用系统自带的 ssh-keygen 软件来创建和管理密钥对。请执行如下步骤创建密钥对:

  1. 以任意具有 ssh-keygen 执行权限的用户登录服务器。
  2. 使用如下指令,基于 rsa 算法创建密钥对:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <ol class="linenums">
      
     <li class="L0"></li>
      
     <li class="L1"><span class="pln">ssh</span><span class="pun">-</span><span class="pln">keygen </span><span class="pun">-</span><span class="pln">t rsa</span></li>
      
     <li class="L2"><span class="typ">Generating</span><span class="pln"> public</span><span class="pun">/</span><span class="pln">private rsa key pair</span><span class="pun">.</span></li>
      
     <li class="L3"><span class="typ">Enter</span><span class="pln"> file </span><span class="kwd">in</span><span class="pln"> which to save the key </span><span class="pun">(/</span><span class="pln">root</span><span class="pun">/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">id_rsa</span><span class="pun">):</span><span class="pln">                </span><span class="pun">→</span><span class="pln"> </span><span class="pun">默认保存路径和文件名,可以按需修改。</span></li>
      
     <li class="L4"><span class="typ">Enter</span><span class="pln"> passphrase </span><span class="pun">(</span><span class="pln">empty </span><span class="kwd">for</span><span class="pln"> no passphrase</span><span class="pun">):</span><span class="pln">                             </span><span class="pun">→</span><span class="pln"> </span><span class="pun">如前面所述,不设置密码,回车确认即可。</span></li>
      
     <li class="L5"><span class="typ">Enter</span><span class="pln"> same passphrase again</span><span class="pun">:</span><span class="pln">                                 </span><span class="pun">→</span><span class="pln"> </span><span class="pun">不设置密码,回车确认即可。</span></li>
      
     <li class="L6"><span class="typ">Your</span><span class="pln"> identification has been saved </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">/</span><span class="pln">root</span><span class="pun">/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">id_rsa</span><span class="pun">.</span><span class="pln">        </span><span class="pun">→</span><span class="pln"> </span><span class="pun">创建的私钥文件。</span></li>
      
     <li class="L7"><span class="typ">Your</span><span class="pln"> public key has been saved </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">/</span><span class="pln">root</span><span class="pun">/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">id_rsa</span><span class="pun">.</span><span class="pln">pub</span><span class="pun">.</span><span class="pln">        </span><span class="pun">→</span><span class="pln"> </span><span class="pun">创建的公钥文件。</span></li>
      
     <li class="L8"><span class="typ">The</span><span class="pln"> key fingerprint is</span><span class="pun">:</span></li>
      
     <li class="L9"><span class="lit">17</span><span class="pun">:</span><span class="pln">b8</span><span class="pun">:</span><span class="lit">0e</span><span class="pun">:</span><span class="lit">76</span><span class="pun">:</span><span class="pln">cb</span><span class="pun">:</span><span class="lit">57</span><span class="pun">:</span><span class="lit">21</span><span class="pun">:</span><span class="lit">3b</span><span class="pun">:</span><span class="pln">f2</span><span class="pun">:</span><span class="pln">bb</span><span class="pun">:</span><span class="lit">8b</span><span class="pun">:</span><span class="pln">a2</span><span class="pun">:</span><span class="lit">42</span><span class="pun">:</span><span class="lit">2b</span><span class="pun">:</span><span class="lit">54</span><span class="pun">:</span><span class="pln">be root@iZ233gr74jvZ</span></li>
      
     <li class="L0"><span class="typ">The</span><span class="pln"> key</span><span class="str">'s randomart image is:</span></li>
      
     <li class="L1"><span class="str">+--[ RSA 2048]----+</span></li>
      
     <li class="L2"><span class="str">|                 |</span></li>
      
     <li class="L3"><span class="str">|         .       |</span></li>
      
     <li class="L4"><span class="str">|        . o .    |</span></li>
      
     <li class="L5"><span class="str">|   .     . + .   |</span></li>
      
     <li class="L6"><span class="str">|  o   o S + .    |</span></li>
      
     <li class="L7"><span class="str">| ... . = = o     |</span></li>
      
     <li class="L8"><span class="str">|.. ..   + o      |</span></li>
      
     <li class="L9"><span class="str">|. oE  .  o .     |</span></li>
      
     <li class="L0"><span class="str">| . ... .. +o     |</span></li>
      
     <li class="L1"><span class="str">+-----------------+</span></li>
     
    </ol>

    说明:

  • 如果 .ssh 目录不存在,程序会自动创建。

  • 生成的密钥对默认保存在当前用户家目录下的 .ssh 文件夹中,文件名默认为 id_rsa(私钥) id_rsa.pub(公钥)。用户可以按需设置保存路径和文件名。

密钥配置

生成密钥对后,进行如下处理:

私钥的处理

私钥用于信息校验,请确保安全。可以将私钥上传到其它源服务器上,或者直接参阅前述说明创建新的密钥对。

公钥的处理

公钥信息需要写入目标服务器、目标用户的配置文件中,默认配置文件为对应用户家目录下 .ssh 文件夹中的 authorized_keys,即:

1
2
3
4
5
<ol class="linenums">
  
 <li class="L0"><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">authorized_keys</span></li>
 
</ol>

可以复制公钥信息后,直接通过 vi 等编辑器将其写入上述文件。或者通过如下指令,在源服务器上配置写入:

1
2
3
4
5
<ol class="linenums">
  
 <li class="L0"><span class="pln">cat </span><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">id_rsa</span><span class="pun">.</span><span class="pln">pub </span><span class="pun">|</span><span class="pln"> ssh </span><span class="pun"><用户名>@<目标服务器</span><span class="pln">IP</span><span class="pun">></span><span class="pln"> </span><span class="pun">‘</span><span class="pln">cat </span><span class="pun">>></span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">authorized_keys</span><span class="pun">’;比如:</span><span class="pln">cat </span><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">id_rsa</span><span class="pun">.</span><span class="pln">pub </span><span class="pun">|</span><span class="pln"> ssh root@120</span><span class="pun">.</span><span class="lit">26.38</span><span class="pun">.</span><span class="lit">248</span><span class="pln"> </span><span class="pun">‘</span><span class="pln">cat </span><span class="pun">>></span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">authorized_keys</span><span class="pun">’;</span></li>
 
</ol>

注意:

  • 该操作由于需要登录目标服务器才能完成,所以隐含表示了客户端拥有对目标服务器的控制权。
  • 如果修改了默认的目录或文件名,则需要同步修改SSH 服务配置文件(默认为/etc/ssh/sshd_config)中的AuthorizedKeysFile 参数,否则会因找不到公钥信息而导致自动登录失败。

参数与权限检查确认

要顺利完成自动登录,还需对SSH 服务相关参数及关联文件、文件夹的权限进行确认或调整。

SSH 服务参数设置

SSH 服务默认开启了证书认证支持。编辑 SSH 服务配置文件(默认为/etc/ssh/sshd_config),确保如下参数没有显示的置为 no。否则,将参数值修改为 yes,或者整个删除或注释(在最开头添加 # 号)整行配置。比如:

1
2
3
4
5
<ol class="linenums">
  
 <li class="L0"><span class="com">#RSAAuthentication yes#PubkeyAuthentication yes</span></li>
 
</ol>

同时,如前面所述,如果修改了默认的公钥路径或文件名,还需确保 AuthorizedKeysFile 参数值配置的信息与其一致。

注意:如果对相关参数做了修改,需要重启 SSH 服务生效。

相关权限设置

SSH 服务证书验证方式登录,对相关目录和文件的权限有要求。权限配置异常可能会导致登录失败。

  • .ssh 目录的权限配置
    使用如下指令,确保 $HOME/.ssh 目录只有所有者才有权写入:
    1
    2
    3
    4
    5
    <ol class="linenums">
      
     <li class="L0"><span class="pln">chmod </span><span class="lit">700</span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">ssh</span></li>
     
    </ol>
  • authorized_keys 文件的权限配置
    使用如下指令,确保其它用户对 authorized_keys 文件没有修改权限:?
    1
    2
    3
    4
    5
    <ol class="linenums">
      
     <li class="L0"><span class="pln">chmod </span><span class="lit">600</span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">authorized_keys</span></li>
     
    </ol>
  • 进一步安全配置
    进一步的安全设置可以将 authorized_keys 文件权限配置为 400(其他用户没有任何权限),并对其及 .ssh 目录添加 immutable 位权限(防止文件被修改):
    1
    2
    3
    4
    5
    <ol class="linenums">
      
     <li class="L0"><span class="pln">chmod </span><span class="lit">400</span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">authorized_keyschattr </span><span class="pun">+</span><span class="pln">i </span><span class="pun">~/.</span><span class="pln">ssh</span><span class="pun">/</span><span class="pln">authorized_keyschattr </span><span class="pun">+</span><span class="pln">i </span><span class="pun">~/.</span><span class="pln">ssh</span></li>
     
    </ol>
     

自动登录配置

完成上述配置后,在客户端即可免密码直接登录。说明如下:

Windows 环境自动登录

您可以参阅文档 使用 SSH 密钥对连接 Linux 实例

Linux 环境自动登录

Linux 环境下,在客户端直接通过 ssh 软件免密码登录:

1
2
3
4
5
<ol class="linenums">
  
 <li class="L0"><span class="pln">ssh </span><span class="pun"><用户名>@<目标服务器></span><span class="pln"> </span><span class="com"># 比如:ssh root@192.168.0.1</span></li>
 
</ol>

如果修改了私钥路径或文件名,则需要通过 –i 参数进行指定:

1
2
3
4
5
<ol class="linenums">
  
 <li class="L0"><span class="pln">ssh </span><span class="pun">–</span><span class="pln">i </span><span class="pun"><私钥路径及文件名></span><span class="pln"> </span><span class="pun"><用户名>@<目标服务器></span><span class="pln">  </span><span class="com">#比如:ssh -i /bak/my_rsa user@192.168.0.1</span></li>
 
</ol>

更多信息

  • OpenSSH Manual PagesOpenSSH 官方使用手册。
  • 公钥指纹
    由于公钥一般较长(采用RSA算法时长达 1024 位)。所以,为了简便起见,通过对其MD5计算,生成一个128位的字符串用于信息对比。此称为公钥指纹。
  • Secure ShellWikipedia 上关于 SSH 的介绍和讨论。
  • OpenSSH Manual PagesOpenSSH 官方使用手册。

 

FAQ

关于此文档暂时还没有FAQ
返回
顶部