SSH 登录流程分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSH 登录流程分析相关的知识,希望对你有一定的参考价值。

参考技术A 登录流程

密钥登录比密码登录安全,主要是因为他使用了非对称加密,登录过程中需要用到 密钥对 。整个登录流程如下:

远程服务器持有公钥,当有用户进行登录,服务器就会随机生成一串字符串,然后发送给正在进行登录的用户。

用户收到远程服务器发来的字符串,使用与 远程服务器公钥配对的私钥 对字符串进行加密,再发送给远程服务器。

服务器使用公钥对用户发来的加密字符串进行解密,得到的解密字符串如果与第一步中发送给客户端的随机字符串一样,那么判断为登录成功。

整个登录的流程就是这么简单,但是在实际使用 ssh 登录中还会碰到一些小细节,这里演示一遍 ssh 远程登录来展示下这些细节问题。

生成密钥对

使用ssh-keygen就可以直接生成登录需要的密钥对。ssh-keygen是 Linux 下的命令,不添加任何参数就可以生成密钥对。

➜  ~ ssh-keygenGenerating public/private rsa key pair.Enter fileinwhichto save the key (/home/jaychen/.ssh/id_rsa):#1Enter passphrase (emptyforno passphrase):#2Enter same passphrase again:#3

执行ssh-keygen会出现如上的提示,在#1处这里提示用户输入生成的私钥的名称,如果不填,默认私钥保存在/home/jaychen/.ssh/id_rsa文件中。这里要注意两点:

生成的密钥,会放在 执行ssh-keygen命令的用户的家目录 下的.ssh文件夹中。即$HOME/.ssh/目录下。

生成的公钥的文件名,通常是私钥的文件名后面加.pub的后缀。

#2处,提示输入密码,注意这里的密码是用来保证私钥的安全的。如果填写了密码,那么在使用密钥进行登录的时候,会让你输入密码,这样子保证了如果私钥丢失了不至于被恶意使用。 话是这么说,但是平时使用这里我都是直接略过。

#3是重复#2输入的密码,这里就不废话了。

生成密钥之后,就可以在/home/jaychen/.ssh/下看到两个文件了(我这里会放在/home/jaychen下是因为我使用 jaychen 用户来执行ssh-keygen命令)

➜  .ssh ls

total 16K

drwx------ 2 jaychen jaychen 4.0K 12月  7 17:57 .

drwx------ 9 jaychen jaychen 4.0K 12月  7 18:14 ..

-rw------- 1 jaychen jaychen 1.7K 12月  7 17:57 id_rsa.github

-rw-r--r-- 1 jaychen jaychen 390 12月  7 17:57 id_rsa.github.pub

生成的私钥还要注意一点: 私钥的权限应该为rw-------,如果私钥的权限过大,那么私钥任何人都可以读写就会变得不安全。ssh 登录就会失败。

首次 ssh 登录

登录远程服务器的命令是

ssh 登录用户@服务器ip

这里开始要注意两个用户的概念:

本地执行这条命令的用户,即当前登录用户,我这里演示的用户名称是 jaychen。

要登录到远程服务器的用户。

在开始登录之前,我们要首先要把生成 公钥 上传到服务器。

公钥的内容要保存到 要登录的用户的家目录下的.ssh/authorized_keys 文件中。假设你之后要使用 root 用户登录远程服务器,那么公钥的内容应该是保存在/root/.ssh/authorized_keys中。注意authorized_keys文件是可以保存多个公钥信息的,每个公钥以换行分开。

上传完毕之后,执行

ssh root@远程服务器ip

这个时候,如上面说的,远程服务器会发送一段随机字符串回来,这个时候需要使用私钥对字符串进行加密。而这个私钥会去 执行该命令的用户的家目录下的.ssh目录 读取私钥文件,默认私钥文件为id_rsa文件。即$HOME/.ssh/id_rsa文件。假设在生成密钥的时候对私钥进行了加密,那么这个时候就需要输入密码。

上面的流程用户登录的时候是不会感知的,ssh 在背后完成了所有的校验操作,如果密钥匹配的话,那么用户就可以直接登录到远程服务器,但是如果是 首次登录 的话,会出现类似下面的提示:

➜  .ssh ssh root@192.168.1.1The authenticityofhost'192.168.1.1 (192.168.1.1)' can't be established.ECDSAkeyfingerprintisSHA256:61U/SJ4n/QdR7oKT2gaHNuGxhx98saqMfzJnzA1XFZg.Are you sure you wanttocontinueconnecting (yes/no)?

这句话的意思是,远程服务器的真实身份无法校验,只知道公钥指纹(公钥的 MD5 值)为61U/SJ4n/QdR7oKT2gaHNuGxhx98saqMfzJnzA1XFZg,是否真的要建立连接。出现上面的提示是因为避免存在 中间人攻击 。

中间人攻击

中间人攻击的前提是,你第一次登录一台远程服务器,你除了用户名、用户名对应的公钥私钥以及服务器 ip 之外,对远程服务器丝毫不了解的情况下。假设你 ssh 远程登录 192.168.1.1 的远程主机,在连接过程中被第三者拦截,第三者假冒自己为 192.168.1.1 的主机,那么你就会直接连接到其他人的服务器上。这就是中间人攻击。

为了避免中间人攻击,ssh 在首次登录的时候会返回公钥指纹,用户需要自己手动去 比对你要登录的远程服务器的公钥的公钥指纹和 ssh 返回的公钥指纹是否一样 。

经过比较公钥指纹,确认该服务器就是你要登录的服务器,输入yes之后就可以成功登录。整个登录流程结束。

known_hosts 文件

第一次登录之后,在本机的$HOME/.ssh/目录下就会生成一个known_hosts的文件,内容类似下面

➜  .ssh cat known_hosts192.168.1.1ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPKYWolOYTDevvBR6GV0rFcI0z/DHZizN5l/ajApsgx+UcOOh51liuyBRRCIyF+BR56Le0lP0Pn6nzvLjbqMqg=

这个文件记录了远程主机 ip 和远程主机对应的公钥指纹,那么在下次登录的时候,远程主机发送过来的公钥指纹,直接和known_hosts文件中对应 ip 的公钥指纹比较即可。

config 配置

很多时候,我们开发可能需要连接多台远程服务器,并且需要配置 git 服务器的私钥。那么这么多的服务器不能共用一套私钥,不同的服务器应该使用不同的私钥。但是我们从上面的连接流程可以看到,ssh 默认是去读取$HOME/.ssh/id_rsa文件作为私钥登录的。如果想要不同的服务器使用不同的私钥进行登录,那么需要在.ssh目录下编写config文件来进行配置。

config的配置很简单,只要指明哪个用户登录哪台远程服务器需要使用哪个私钥即可。下面给出一个配置示例。

Host github.com

           User jaychen

            IdentityFile ~/.ssh/id_rsa.github

Host 192.168.1.1

             User ubuntu

IdentityFile ~/.ssh/id_rsa.xxx

上面config文件字段含义如下:

Host 指明了远程主机的 ip,除了使用 ip 地址,也可以直接使用网址。

User 指的是登录远程主机的用户。

IdentityFile 指明使用哪个私钥文件。

安全运营--centos7.6查看ssh登录日志分析服务器安全情况

linux服务器在挂到外网的时候,很容易受到黑客的扫描,攻击,拿到服务器权限。所以,如有异常账户ip登录服务器,就应该高度警惕,更换密码,检查漏洞等。

1.wtmp日志

查看所有SSH登陆日志 包括IP,输出的内容包括:用户名、终端位置、登录源信息、开始时间、结束时间、持续时间。注意最后一行输出的是wtmp文件起始记录的时间。当然也可以通过last -f参数指定读取文件

命令:last

[root@localhost ~]# last    
root     pts/0        192.168.8.88     Wed Jan  4 11:03   still logged in
root     pts/1        10.10.10.253     Tue Jan  3 21:23 - 21:39  (00:16)
root     pts/0        192.168.8.88     Tue Jan  3 21:09 - 10:55  (13:46)
reboot   system boot  3.10.0-957.el7.x Tue Jan  3 09:43 - 16:46 (2+07:02)
root     pts/0        192.168.8.88     Tue Jan  3 09:12 - down   (00:08)
reboot   system boot  3.10.0-957.el7.x Tue Jan  3 09:11 - 09:20  (00:08)
wtmp begins Mon Dec 12 16:35:12 2022

命令:last -x -F

[root@localhost ~]# last -x -F
root     pts/0        192.168.8.88     Wed Jan  4 11:03:55 2023   still logged in
root     pts/1        10.10.10.253     Tue Jan  3 21:23:34 2023 - Tue Jan  3 21:39:38 2023  (00:16)
runlevel (to lvl 3)   3.10.0-957.el7.x Mon Dec 12 16:36:28 2022 - Mon Dec 12 16:49:59 2022  (00:13)
reboot   system boot  3.10.0-957.el7.x Mon Dec 12 16:35:12 2022 - Mon Dec 12 16:49:59 2022  (00:14)

wtmp begins Mon Dec 12 16:35:12 2022

2.查看在线用户情况

(1)w 命令用于显示已经登陆系统的用户列表,并显示用户正在执行的指令。单独执行w命令会显示所有的用户,也可指定用户名称,仅显示某位用户的相关信息:

w 用户名

[root@localhost ~]# w
 16:49:36 up 2 days,  7:12,  1 user,  load average: 0.06, 0.03, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.8.88     三11    0.00s  2.57s  0.00s w

(2)who am i 显示出口IP地址,该地址用于SSH连接的源IP

[root@localhost ~]# who am i
root     pts/0        2023-01-04 11:03 (192.168.8.88)

3.lastlog 列出所有用户最近登录的信息

lastlog引用的是/var/log/lastlog文件中的信息,包括login-name、port、last login time

[root@localhost ~]# lastlog
用户名           端口     来自             最后登陆时间
root             pts/0    192.168.8.88     三 1月  4 11:03:55 +0800 2023
bin                                        **从未登录过**
daemon                                     **从未登录过**
adm                                        **从未登录过**
lp                                         **从未登录过**
sync                                       **从未登录过**
shutdown                                   **从未登录过**
halt                                       **从未登录过**
mail                                       **从未登录过**
operator                                   **从未登录过**
games                                      **从未登录过**
ftp                                        **从未登录过**
nobody                                     **从未登录过**
systemd-network                            **从未登录过**
dbus                                       **从未登录过**
polkitd                                    **从未登录过**
libstoragemgmt                             **从未登录过**
abrt                                       **从未登录过**
rpc                                        **从未登录过**
sshd                                       **从未登录过**
postfix                                    **从未登录过**
ntp                                        **从未登录过**
chrony                                     **从未登录过**
tcpdump                                    **从未登录过**
apache                                     **从未登录过**
mabos                                      **从未登录过**

4.lastb 列出失败尝试的登录信息

和last命令功能完全相同,只不过它默认读取的是/var/log/btmp文件的信息。

[root@localhost ~]# lastb

btmp begins Wed Jan  4 20:18:51 2023

5.SSH登录日志分析

检查/var/log目录下的secure(CentOS),存在大量异常IP高频率尝试登录,且有成功登录记录(重点查找事发时间段)。

cat /var/log/secure |more
Jan  4 11:03:55 localhost sshd[7648]: Accepted password for root from 192.168.8.88 port 56455 ssh2
Jan  4 11:03:55 localhost sshd[7648]: pam_unix(sshd:session): session opened for user root by (uid=0)
Jan  4 11:03:55 localhost sshd[7650]: Accepted password for root from 192.168.8.88 port 56458 ssh2
Jan  4 11:03:55 localhost sshd[7650]: pam_unix(sshd:session): session opened for user root by (uid=0)
Jan  4 15:34:34 localhost polkitd[4857]: Registered Authentication Agent for unix-process:8161:10782133 (system bus name :1.458 [/usr/bin/pkttyagent --notif
y-fd 5 --fallback], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale zh_CN.UTF-8)
Jan  4 15:34:34 localhost polkitd[4857]: Unregistered Authentication Agent for unix-process:8161:10782133 (system bus name :1.458, object path /org/freedesk
top/PolicyKit1/AuthenticationAgent, locale zh_CN.UTF-8) (disconnected from bus)
Jan  4 20:18:49 localhost useradd[20139]: failed adding user 'dbus', exit code: 9
Jan  4 20:18:51 localhost polkitd[4857]: Reloading rules

less /var/log/secure|grep'Accepted'  
[root@localhost ~]#  less /var/log/secure | grep 'Accepted'
Jan  3 09:12:14 localhost sshd[5901]: Accepted password for root from 192.168.8.88 port 57536 ssh2
Jan  3 09:12:14 localhost sshd[5903]: Accepted password for root from 192.168.8.88 port 57539 ssh2
Jan  3 21:09:05 localhost sshd[6674]: Accepted password for root from 192.168.8.88 port 58119 ssh2
Jan  3 21:09:06 localhost sshd[6676]: Accepted password for root from 192.168.8.88 port 58122 ssh2
Jan  3 21:23:28 localhost sshd[6736]: Accepted password for root from 10.10.10.253 port 52502 ssh2
Jan  3 21:23:30 localhost sshd[6738]: Accepted password for root from 10.10.10.253 port 52790 ssh2
Jan  4 11:03:55 localhost sshd[7648]: Accepted password for root from 192.168.8.88 port 56455 ssh2
Jan  4 11:03:55 localhost sshd[7650]: Accepted password for root from 192.168.8.88 port 56458 ssh2

/var/log/其他日志说明:

/var/log/message  一般信息和系统信息
/var/log/secure  登陆信息
/var/log/maillog  mail记录
/var/log/utmp 
/var/log/wtmp登陆记录信息(last命令即读取此日志)

以上是关于SSH 登录流程分析的主要内容,如果未能解决你的问题,请参考以下文章

flask 登录功能流程源码分析

springsecurity密码登录的流程分析

flask 登录功能流程源码分析

生鲜项目前期准备(开发流程,需求分析)

20 测试用例设计 流程分析

Shiro源码分析----认证流程