SSH学习笔记

SSH概要

Secure Shell,安全外壳协议,简称ssh,是一种建立在应用层基础上的安全协议,通过对密码进行加密传输验证,可在不安全的网络中对网络服务提供安全的传输环境,实现ssh客户端和ssh服务器端的连接

(1).SSH是传输层和应用层上的安全协议,它只能通过加密连接双方会话的方式来保证连接的安全性。当使用ssh连接成功后,将建立客户端和服务端之间的会话,该会话是被加密的,之后客户端和服务端的通信都将通过会话传输。

(2).SSH服务的守护进程为sshd,默认监听在22端口上。

(3).所有ssh客户端工具,包括ssh命令,scp,sftp,ssh-copy-id等命令都是借助于ssh连接来完成任务的。也就是说它们都连接服务端的22端口,只不过连接上之后将待执行的相关命令转换传送到远程主机上,由远程主机执行。

(4).ssh客户端命令(ssh、scp、sftp等)读取两个配置文件:全局配置文件/etc/ssh/ssh_config和用户配置文件~/.ssh/config。实际上命令行上也可以传递配置选项。它们生效的优先级是:命令行配置选项 > ~/.ssh/config > /etc/ssh/ssh_config。

(5).ssh涉及到两个验证:主机验证和用户身份验证。通过主机验证,再通过该主机上的用户验证,就能唯一确定该用户的身份。一个主机上可以有很多用户,所以每台主机的验证只需一次,但主机上每个用户都需要单独进行用户验证。

(6).ssh支持多种身份验证,最常用的是密码验证机制和公钥认证机制,其中公钥认证机制在某些场景实现双机互信时几乎是必须的。虽然常用上述两种认证机制,但认证时的顺序默认是gssapi-with-mic,hostbased,publickey,keyboard-interactive,password。注意其中的主机认证机制hostbased不是主机验证,由于主机认证用的非常少(它所读取的认证文件为/etc/hosts.equiv或/etc/shosts.equiv),所以网络上比较少见到它的相关介绍。总的来说,通过在ssh配置文件(注意不是sshd配置文件)中使用指令PreferredAuthentications改变认证顺序不失为一种验证的效率提升方式。

(7).ssh客户端其实有不少很强大的功能,如端口转发(隧道模式)、代理认证、连接共享(连接复用)等。

(8).ssh服务端配置文件为/etc/ssh/sshd_config,注意和客户端的全局配置文件/etc/ssh/ssh_config区分开来。

(9).很重要却几乎被人忽略的一点,ssh登录时会请求分配一个伪终端。但有些身份认证程序如sudo可以禁止这种类型的终端分配,导致ssh连接失败。例如使用ssh执行sudo命令时sudo就会验证是否要分配终端给ssh

SSH认证过程分析

假如从客户端A连接到服务端B上,将包括主机验证和用户身份验证两个过程,以RSA非对称加密算法为例。

主机验证过程(发生在客户端)

当客户端A要连接服务端B时,首先将进行主机验证过程,即客户端A判断是否曾经连接过主机B。

客户端A执行ssh命令连接时, 会接收到服务端B的ssh公钥, 也可以称作B机器的主机信息(即host key,表示主机身份标识)

服务端B的公钥信息保存在/etc/ssh/ssh_host*文件中, 其中的*表示不同的加密算法, ssh服务启动时会选择一种算法的.pub文件作为公钥

在本例中选择的是ECDSA算法, ssh_host_ecdsa_key.pub文件内容为:

ecdsa-sha2-nistp256 AAAAE...vC2PDRA08c7c= root@iZuf60sq23qlao62jmsy0zZ

通过空格分隔为三个部分:

  1. 第一部分表示服务端B的公钥加密算法
  2. 第二部分表示服务端B的公钥值
  3. 第三部分表示服务端B的公钥生成时的用户信息

第一次建立连接

若客户端A从未连接过服务端B(即第一次建立连接), 则会询问是否进行连接

图中展示了两个信息:

  1. 服务端B的公钥是通过ECDSA算法进行加密的
  2. 由于公钥长度太长, 这里对公钥再次进行了加密, 得出公钥的指纹, 即SHA256后面的44位字符串

输入yes则会继续连接, 并将B的公钥信息保存至客户端A的~/.ssh/known_hosts文件中, 如:

|1|xNN...6aRA= ecdsa-sha2-nistp256 AAAAE...vC2PDRA08c7c=

每行数据表示一个主机信息, 通过空格分隔为三个部分:

  1. 第一部分表示服务端B的ip相关信息
  2. 第二部分表示服务端B的公钥加密算法
  3. 第三部分表示服务端B的公钥值

其中第2、3两个部分的值和服务端B的公钥文件``ssh_host_ecdsa_key.pub`中的值相同。

后续连接

后面再进行连接时, 则会将服务端B发送过来的公钥信息(host key)和~/.ssh/known_hosts文件中保存的host key进行比较.

若两者相同, 则验证通过, 进行下一个过程--身份验证

若不相同, 则提示主机认证失败, 如:

上述报错意思为本次接收的指纹wtCqN4lUaPNJb1TNuLawnI1JegJ3xGrda5yij+bo0g8~/.ssh/known_hosts文件中保存的host key指纹不一致, 可以使用ssh-keygen -f "/home/alex/.ssh/known_hosts" -R "[127.0.0.1]:2222"命令删除原文件中保存的host key信息. 删除后再连接, 则又会回到第一次建立连接时的流程

host key指纹

ssh并非直接比对host key,因为host key太长了,比对效率较低。所以ssh将host key转换成host key指纹,然后比对两边的host key指纹即可。host key的指纹可由ssh-kegen命令计算得出。

计算服务端B的host key指纹

(base) alex@Aliyun-ALex:~$ sudo ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key
256 SHA256:N2QawIygnLo3m34fDevSECWNK1S7Ow+54wXnHQwMwko root@iZuf60sq23qlao62jmsy0zZ (ECDSA)

计算客户端A中known_hosts文件保存的B的host key指纹, 两者相同

alex@LPT006526:~$ ssh-keygen -l -f ~/.ssh/known_hosts
256 SHA256:N2QawIygnLo3m34fDevSECWNK1S7Ow+54wXnHQwMwko |1|xNNGD5QK4PWE8ecSJ1aWhdu6gVw=|T13/F6JZiCNy7L7eQVuIAib6aRA= (ECDSA)

身份验证过程

主机验证通过后,将进入身份验证阶段。SSH支持多种身份验证机制,它们的验证顺序如下:gssapi-with-mic,hostbased,publickey,keyboard-interactive,password,但常见的是密码认证机制(password)和公钥认证机制(public key)。当公钥认证机制未通过时,再进行密码认证机制的验证。

在进行上一步的主机验证时, 客户端A已经得到了服务端B的公钥

密码认证

密码认证过程

  1. 客户端A将用户输入的密码使用服务端B的公钥进行加密, 将加密结果发送给服务端B

  2. 服务端B使用自己的私钥对加密结果进行解密, 得到密码, 与本地密码文件进行比较, 若相同则认证成功, 否则失败

公钥认证

公钥认证前提

公钥认证可以不用输入密码, 但有两个前提:

  1. 客户端A也生成一套非对称秘钥, 可以使用ssh-keygen命令生成, 默认情况下会在~/.ssh/目录下生成id_rsa(私钥)和id_rsa.pub(公钥)文件

    alex@LPT006526:~$ ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/alex/.ssh/id_rsa):  # 直接回车,使用默认值
    Enter passphrase (empty for no passphrase):  # 直接回车,不设置密码
    Enter same passphrase again:  # 直接回车,不设置密码
    Your identification has been saved in /home/alex/.ssh/id_rsa.  # 私钥
    Your public key has been saved in /home/alex/.ssh/id_rsa.pub.  # 公钥
    The key fingerprint is:
    SHA256:zQtCAGgFVR0Ia89w9D0i0VJMZeAu94XEdbjYTlpuWrM alex@LPT006526  # 公钥指纹
    The key's randomart image is:  # 公钥图片码
    +---[RSA 2048]----+
    | o==++B=+o ...   |
    |..  o++++ ...    |
    |.  + oo+ =o .    |
    |  . =.o o+o=     |
    |     +.oS.O.     |
    |      o..o.B     |
    |         .= o    |
    |         . E     |
    |                 |
    +----[SHA256]-----+
    
  2. 将客户端A的公钥放在服务端B的~/.ssh/authorized_keys文件中, 可以在客户端A中使用命令ssh-copy-id进行设置, 也可以手动将客户端A的公钥文件~/.ssh/id_rsa.pub中的值追加到服务端B的~/.ssh/authorized_keys文件中

    alex@LPT006526:~$ ssh-copy-id alex@47.102.114.90
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/alex/.ssh/id_rsa.pub"
    /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
    alex@47.102.114.90's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'alex@47.102.114.90'"
    and check to make sure that only the key(s) you wanted were added.
    

以上两个前提设置完成后, 在客户端A中直接输入ssh连接命令即可连接至服务端B中, 不需要输入密码

公钥认证的过程

  1. 客户端A发送A的公钥给服务端B
  2. 服务端B接收到A的公钥后, 去~/.ssh/authorized_keys文件中查找是否存在A的公钥, 若存在, 则用此公钥加密一个随机字符串, 并返回给客户端A
  3. 客户端A收到后使用自己的私钥进行解密, 并将解密结果发送给服务端B
  4. 服务端B收到A的解密结果后与之前的随机字符串进行比较, 若相同, 则认证成功. 否则认证失败

MFA

多重要素验证(英语:Multi-factor authentication,缩写为 MFA),又译多因子认证、多因素验证、多因素认证,是一种计算机访问控制的方法,用户要通过两种以上的认证机制之后,才能得到授权,使用计算机资源。

相比仅凭账号密码,MFA提供了更加安全的资源保护。下面列举一些MFA的例子:

  1. 用户安全问题
  2. 密码
  3. OTPs
  4. 软件安全码、keys
  5. 指纹、人脸识别、声纹及其他生物特征
  6. 用户行为足迹分析

OTP

OTP(One-Time-Password)是MFA(Multi-Factor-Authentication)的一个实现模型. 顾名思义,一次性密码。如短信验证码, 谷歌认证等

HOTP

HOTP中,H指代 Hash-based Message Authentication Code,另一种不那么专业的解释方法为:HOTP是一种事件驱动的OTP,它的moving factor基于一个计数器。
HOTP每一次请求,都会让计数器递增,而生成的OTP在下一次计数前保持有效。OTP生成器和服务器会同步监测到用户的有效访问行为。HOTP的一个例子为Yubikey。

TOTP

TOTP中,T指代Time-based,类似HOTP,但是它的moving factor基于时间。
TOTP的有效时间被称为timestep(时间步长),通常被设定为30、60秒,如果在这个时间窗口内没有验证此密码,则会失效。

posted @ 2023-02-14 12:24  Alex-GCX  阅读(118)  评论(0编辑  收藏  举报