3.SSH密码登录【实验】

  1. 原理
  2. 实验
    1. 验证Fingerprint
  3. 如何确认Fingerprint
    1. 实验1 - 获得Fingerprint
    2. 实验2 - known_hosts
    3. 实验3 - 通过命令行生成 known_hosts 记录

原理

sequenceDiagram
autonumber
    local->>remote: SSH connect
 	remote->>remote: Generate fingerprint
    remote->>+local:  Is this fingprint?
    local-->>-remote: yes
    local->>local: write in known_hosts
    remote->>+local:  Password?
    local-->>-remote:  My password

实验

我们通过 VMWare/VirtualBox等 虚拟机管理软件安装好Ubuntu桌面版之后,进到桌面里并打开 terminal,首先

验证Fingerprint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 追加 fingerprint 前
$ cat ~/.ssh/known_hosts

# 该fingerprint是由ECDSA key通过SHA256生成的
# f2TduTCqvnPtV0X4NjJuGWTCTvv1zrZ6o02pR7l91PE
$ ssh  xiaojie@ubuntu 
The authenticity of host 'ubuntu (127.0.1.1)' can't be established.
ECDSA key fingerprint is SHA256:f2TduTCqvnPtV0X4NjJuGWTCTvv1zrZ6o02pR7l91PE.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'ubuntu' (ECDSA) to the list of known hosts.

# 追加 fingerprint 后
$ cat ~/.ssh/known_hosts
|1|xnqLsAJTszF/5veaA08X0z0yoFk=|9diGH8pqVfh1bIwQpJudFvm3mYc= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBN3zTtyrfWzSMnpCwh8NuOM3PABAnd1qZAN5HORNZraEAcz1oBPDAv+mFMPS43H9k51EMVCvg+tfV/smH7KCs34=

如何确认Fingerprint

/etc/ssh/ 可以发现 SSH服务端 所使用的非对称密钥,同时它又被叫做 host key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 我们发现了ECDSA key 
# - ssh_host_ecdsa_key		 =>private key
# - ssh_host_ecdsa_key.pub 	 =>public key
$ ls /etc/ssh/ -l
total 580
-rw-r--r-- 1 root root 553122 Mar  4  2019 moduli
-rw-r--r-- 1 root root   1580 Mar  4  2019 ssh_config
-rw-r--r-- 1 root root   3264 Mar  4  2019 sshd_config
-rw------- 1 root root    227 Feb 27  2020 ssh_host_ecdsa_key
-rw-r--r-- 1 root root    173 Feb 27  2020 ssh_host_ecdsa_key.pub
-rw------- 1 root root    399 Feb 27  2020 ssh_host_ed25519_key
-rw-r--r-- 1 root root     93 Feb 27  2020 ssh_host_ed25519_key.pub
-rw------- 1 root root   1679 Feb 27  2020 ssh_host_rsa_key
-rw-r--r-- 1 root root    393 Feb 27  2020 ssh_host_rsa_key.pub
-rw-r--r-- 1 root root    338 Feb 27  2020 ssh_import_id

根据第一次登录时的提示,

ECDSA key fingerprint is SHA256:f2TduTCqvnPtV0X4NjJuGWTCTvv1zrZ6o02pR7l91PE.

我们知道,使用的是 ECDSA 的 public key。

1
2
$ cat /etc/ssh/ssh_host_ecdsa_key.pub 
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBN3zTtyrfWzSMnpCwh8NuOM3PABAnd1qZAN5HORNZraEAcz1oBPDAv+mFMPS43H9k51EMVCvg+tfV/smH7KCs34= root@ubuntu

通过 Notepad++ 的对比工具,我们可以看到差异。

image-20210606143506623

  1. |1|xnqLsAJTszF/5veaA08X0z0yoFk=|9diGH8pqVfh1bIwQpJudFvm3mYc=known_hosts专有)
  2. 算法 + public key (known_hostsssh_host_ecdsa_key.pub 均有)
  3. root@ubuntussh_host_ecdsa_key.pub 专有)

②和③不进行扩展探讨。① 是 IP address。因为 Ubuntu 默认开启了 HashKnownHosts=yes,所以此 IP address 被 hash 了。详情参考 man手册

实验1 - 获得Fingerprint

Fingerprint 指纹,当第一次连接 SSH服务端 的时候,SSH客户端 将会把 服务端的 public key 的 Fingerprint 展示给用户看,以做校验。当回答 Yes之后,就认为校验成功且结束。

Fingerprint 生成命令[来源]

1
2
3
# ECDSA key fingerprint is SHA256:f2TduTCqvnPtV0X4NjJuGWTCTvv1zrZ6o02pR7l91PE. <-对照
$ ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub
256 SHA256:f2TduTCqvnPtV0X4NjJuGWTCTvv1zrZ6o02pR7l91PE root@xiaojie-ubuntu (ECDSA)

实验2 - known_hosts

有趣的是,我们输入 plain text IP address,也可以使 known_hosts 生效:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ ssh xiaojie@ubuntu
The authenticity of host 'ubuntu (127.0.1.1)' can't be established.
ECDSA key fingerprint is SHA256:f2TduTCqvnPtV0X4NjJuGWTCTvv1zrZ6o02pR7l91PE.
Are you sure you want to continue connecting (yes/no)? ^C

$ key_part=($(cat /etc/ssh/ssh_host_ecdsa_key.pub | tr ' ' '\n' ))
$ algorithm="${key_part[1]}"
$ public_key=${key_part[2]}
$ echo "ubuntu ${public_key} ${public_key}" | tee -a ~/.ssh/known_hosts  

# skip the hint
$ ssh xiaojie@ubuntu
xiaojie@ubuntu's password: 

实验3 - 通过命令行生成 known_hosts 记录

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
48
49
50
# 初始化
key_part=($(cat /etc/ssh/ssh_host_ecdsa_key.pub | tr ' ' '\n' ))
algorithm="${key_part[0]}"
public_key="${key_part[1]}"

# ssh-keygen
# -f	filename Specifies the filename of the key file.This replaces all hostnames and addresses with hashed representations within the specified file
# -H	Hash a known_hosts file. 

# 第一次
$ echo "localhost ${algorithm} ${public_key}" | tee ~/.ssh/known_hosts  
$ ssh xiaojie@localhost # 确认能跳过 Fingerprint 校验
xiaojie@localhost's password:

# 进行Hash
$ ssh-keygen -f  ~/.ssh/known_hosts  -H 
/home/xiaojie/.ssh/known_hosts updated.
Original contents retained as /home/xiaojie/.ssh/known_hosts.old
WARNING: /home/xiaojie/.ssh/known_hosts.old contains unhashed entries
Delete this file to ensure privacy of hostnames

# 结果1
$ cat  ~/.ssh/known_hosts
|1|RW0IgbTBnuy62byYN2g+68INw6w=|xL+W7STYwPk020DE0MqSQlR61I8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI64qGNCHDlklX+GOOixGRR0KP49gYES/oOfDHUaKhLYLJhlniv4HkH4Ewx4PeBcpQPxoEwh0F+YXAalUxX64t4=

# 第二次
# 获得Hash后的known_hosts
$ rm ~/.ssh/known_hosts
$ ssh xiaojie@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:Km47D/u1Lb144IFniS8hltHc2foT8UZQ7Y2+wFfxc/s.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
xiaojie@localhost's password: 

# 结果2
$ cat ~/.ssh/known_hosts
|1|/uWWXcAD7S/MpBF0SOk8UQ2waAM=|+TgcDy9/az+iufvGuURb2SAqeOs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI64qGNCHDlklX+GOOixGRR0KP49gYES/oOfDHUaKhLYLJhlniv4HkH4Ewx4PeBcpQPxoEwh0F+YXAalUxX64t4=
xiaojie@xiaojie-ubuntu:~$ 

# 第三次
$ echo "127.0.0.1 ${algorithm} ${public_key}" | tee ~/.ssh/known_hosts  
$ ssh-keygen -f  ~/.ssh/known_hosts  -H
...
$ cat  ~/.ssh/known_hosts
|1|TZjrhag93izYTGXmxrpw7DP9W6E=|LdPrgVOLZNrhzm3SwCFb4Uk0uuI= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI64qGNCHDlklX+GOOixGRR0KP49gYES/oOfDHUaKhLYLJhlniv4HkH4Ewx4PeBcpQPxoEwh0F+YXAalUxX64t4=
$ ssh xiaojie@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:Km47D/u1Lb144IFniS8hltHc2foT8UZQ7Y2+wFfxc/s.
Are you sure you want to continue connecting (yes/no/[fingerprint])? ^C

结合 实验2 和 实验3,可以发现,其实 ~/.ssh/known_hosts 存在细节内容需要去考察—— ssh-keygen 获得的内容与 SSH 自动记录的内容不完全一致,区别在于 host 部分。

image-20210607010539250