一文彻底搞懂什么是SSH中间人攻击(Man-in-the-middle attack)

文章目录

    • 【1】背景
    • 【2】中间人攻击原理
      • 登录报错信息提示
      • 从首次登录服务器说起
      • 中间人攻击原理
      • 重装服务器导致ssh无法登录的解决方案
    • 【3】如何避免中间人攻击?
    • 【4】什么是Known_hosts ?
      • known_hosts中的文件来自哪里?
      • 这个/etc/ssh/ssh_host_ecdsa_key.pub 和/root/.ssh/id_rsa.pub的区别是啥呢?
    • 【5】什么是authorized_keys?
      • 公钥登录的原理
      • 公钥登录的sshd配置

【1】背景

服务器重新安装之后,ssh无法连接,提示中间人攻击(man-in-the-middle-attack)。之前也遇到过,按照网上的操作能解决,但是一知半解,今天趁此把该问题消化掉。

Someone could be eavesdropping on you right now (man-in-the-middle attack)!

【2】中间人攻击原理

登录报错信息提示

其实如果仔细阅读这个报错提示应该也能理解一二。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:7g/bojcSbdVWBrfNrQ5+k+XQZuo4mp0V7MnUPD21nec.
Please contact your system administrator.
Add correct host key in /c/Users/reggie/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /c/Users/reggie/.ssh/known_hosts:2
ECDSA host key for [xxx.xxx.com]:12222 has changed and you have requested strict checking.
Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

从首次登录服务器说起

首次ssh登录服务器背后都发生了什么呢?

[root@hadoop100 ~/.ssh]#ssh [email protected]
The authenticity of host '10.50.10.179 (10.50.10.179)' can't be established.
ECDSA key fingerprint is SHA256:Ld7RCy+1lIgwlW6cLVNt6ULM++jXM+XRYZ5NixblOb0.
ECDSA key fingerprint is MD5:31:36:dc:fe:37:af:5c:85:e5:58:85:63:73:86:ec:d4.
Are you sure you want to continue connecting (yes/no)? yes

上面的文字意思就是 无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?

  • ECDSA key fingerprint 是远程服务器公钥的指纹信息

“公钥指纹”,是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。上例中是31:36:dc:fe:37:af:5c:85:e5:58:85:63:73:86:ec:d4,再进行比较,就容易多了。

  • 这一步如果你可以登录远程服务器,可以校验
]# ssh-keyscan -t ECDSA -p 22 127.0.0.1 2>/dev/null | ssh-keygen -E sha256 -lf -
256 SHA256:Ld7RCy+1lIgwlW6cLVNt6ULM++jXM+XRYZ5NixblOb0 127.0.0.1 (ECDSA)
  • 如果不能登录,例如你要ssh github,那么一般这种公网上的服务器一般都会公布自己的公钥指纹信息,这个和文件下载附带rsa256检验文件是一个道理.
  • 输入yes之后提示如下表示host主机已经得到认可
Warning: Permanently added '10.50.10.179' (ECDSA) to the list of known hosts
  • 接着要求输入密码
[email protected]'s password:
  • 如果密码正确,就可以登录了。

当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。

每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,保存一些对所有用户都可信赖的远程主机的公钥。

一文彻底搞懂什么是SSH中间人攻击(Man-in-the-middle attack)_第1张图片

中间人攻击原理

SSH之所以能够保证安全,原因在于它采用了公钥加密。

ssh整个登录过程 :
(1)远程主机收到用户的登录请求,把自己的公钥发给用户。
(2)用户使用这个公钥,将登录密码加密后,发送回来。
(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。

这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。
因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。

可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。

重装服务器导致ssh无法登录的解决方案

当然如果服务器重新安装也会被系统认为发生了中间人攻击,例如A服务器重装之后,其known_hosts文件中记录的B的公钥1 与 连接时B传过来的公钥2不匹配。
解决办法是只需要在known_hosts中将旧的服务器信息删掉或者忽略known_hosts认证即可。

  • 方法一:删除A的known_hosts文件中记录的B的公钥(手动进行,不适用于自动化部署情形)
  • 方法二:修改配置文件,在ssh登陆时不通过known_hosts文件进行验证(安全性有所降低),修改完重启sshd
StrictHostKeyChecking no 
UserKnownHostsFile /dev/null

【3】如何避免中间人攻击?

建议使用公钥登录,不要使用明文登录,首次明文登录之后可以禁止root用户的明文登录。

【4】什么是Known_hosts ?

known_hosts文件是一个客户端文件,包含所有远程连接的已知主机,ssh客户端使用这个文件。该文件为客户端向他们连接的服务器进行身份验证。

known_hosts 文件包含所有已知主机的主机公钥。StrictHostKeyChecking 这个参数可以选择关闭校验known_hosts
但如果使用,则由系统管理员准备。它会自动维护系统中的每个用户文件。每次用户连接到未知主机时,未知主机密钥都会添加到此文件中。
但是,如果机器被黑客攻击或受到威胁,黑客可以使用 know_hosts 文件,查看连接到这台机器的所有机器的列表,并将这些机器作为目标。为避免这种风险,并非 known_host 密钥中的所有 IP 地址都以明文格式定义。具体格式可参考

known_hosts中的文件来自哪里?

客户端的该文件内容来自于服务器的/etc/ssh/ssh_host_ecdsa_key.pub。
一文彻底搞懂什么是SSH中间人攻击(Man-in-the-middle attack)_第2张图片

这个/etc/ssh/ssh_host_ecdsa_key.pub 和/root/.ssh/id_rsa.pub的区别是啥呢?

远程主机的用户目录下的公钥变了无所谓,客户端连接主要是看主机公钥是否该表以辨识中间人攻击。
主机密钥只是普通的 SSH 密钥对。每个主机可以为每种算法拥有一个主机密钥。主机密钥几乎总是存储在以下文件中:

/etc/ssh/ssh_host_dsa_key 
/etc/ssh/ssh_host_ecdsa_key 
/etc/ssh/ssh_host_ed25519_key 
/etc/ssh/ssh_host_rsa_key

主机密钥通常在安装 SSH 服务器时自动生成。它们可以随时再生。但是,如果更改主机密钥,客户端可能会警告更改的密钥。当有人试图执行中间人攻击时,也会报告已更改的密钥。

更改密钥最好使用 SSH 密钥管理工具来完成,该工具也会在客户端更改它们,或者使用证书。

以下是man ssh中的定义

ssh automatically maintains and checks a database containing identification for all hosts it has ever been used with.  Host keys
     are stored in ~/.ssh/known_hosts in the user's home directory.  Additionally, the file /etc/ssh/ssh_known_hosts is automatically
     checked for known hosts.  Any new hosts are automatically added to the user's file.  If a host's identification ever changes, ssh
     warns about this and disables password authentication to prevent server spoofing or man-in-the-middle attacks, which could other‐
     wise be used to circumvent the encryption.  The StrictHostKeyChecking option can be used to control logins to machines whose host
     key is not known or has changed.

     When the user's identity has been accepted by the server, the server either executes the given command in a non-interactive ses‐
     sion or, if no command has been specified, logs into the machine and gives the user a normal shell as an interactive session.
     All communication with the remote command or shell will be automatically encrypted.

【5】什么是authorized_keys?

主要是用于公钥远程登录时.
远程主机将用户的公钥,保存在登录后的用户主目录的$HOME/.ssh/authorized_keys文件中。公钥就是一段字符串,只要把它追加在authorized_keys文件的末尾就行了。

这里不使用上面的ssh-copy-id命令,改用下面的命令,解释公钥的保存过程:

  $ ssh user@host   'mkdir -p .ssh && cat >> .ssh/authorized_keys'   < ~/.ssh/id_rsa.pub

这个在远程主机上执行脚本的语句,依次分解开来看:

(1)"$ ssh user@host",表示登录远程主机;
(2)单引号中的mkdir .ssh && cat >> .ssh/authorized_keys,表示登录后在远程shell上执行的命令:
(3)"$ mkdir -p .ssh"的作用是,如果用户主目录中的.ssh目录不存在,就创建一个;
(4)'cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
作用是,将本地的公钥文件~/.ssh/id_rsa.pub,重定向追加到远程文件authorized_keys的末尾。

写入authorized_keys文件后,公钥登录的设置就完成了。如果管理的机器并不多,可以使用ssh-copy -i 进行.

公钥登录的原理

所谓"公钥登录",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。

公钥登录的sshd配置

如果客户端的公钥已经加入授信列表还无法连接,请确认远程主机上的以下几个参数是否开启。

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

你可能感兴趣的:(Linux,ssh,服务器,linux)