
如果你經常使用 Linux 系統 ssh 到一個遠程服務器,在主目錄中一般會有一個 .ssh 文件夾,在這個文件夾中會有若干個文件,其中包括一個 known_hosts 文件:
$ ls -l .ssh
total 16
-rwxr-xr-x 1 abhishek abhishek 618 Aug 30 16:52 config
-rw------- 1 abhishek abhishek 1766 Nov 12 2017 id_rsa
-rw-r--r-- 1 abhishek abhishek 398 Nov 12 2017 id_rsa.pub
-rw------- 1 abhishek abhishek 1 Sep 26 15:00 known_hosts
這里,id_rsa 是你 ssh 的私鑰,id_rsa.pub 為ssh公鑰,config 文件用于創建概要信息,以便進行 ssh 連接。
本文重點要介紹的,是上述列表中的最后一個文件,known_hosts,它是客戶端 ssh 配置文件的重要組成部分。
SSH中的 known_hosts 文件是什么
known_hosts 文件存儲用戶訪問的主機的公鑰。這是一個非常重要的文件,它通過將用戶的身份保存到本地系統來確保用戶連接到合法的服務器。這也有助于避免中間人攻擊。
當你通過SSH連接到一個新的遠程服務器時,系統會提示你是否要將遠程主機添加到 known_hosts 文件:
The authenticity of host '194.195.118.85 (194.195.118.85)' can't be established.
ED25519 key fingerprint is SHA256:wF2qILJg7VbqEE4/zWmyMTSwy3ja7be1jTIg3WzmpeE.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
選擇 yes,服務器的連接信息會保存在你的系統中。
避免中間人攻擊

我們假設你經常連接某個服務器,且將該服務器的連接信息保存在了 know_hosts 文件中。
如果遠程服務器的公鑰發生了更改,你的系統會根據 known_hosts 文件中存儲的信息記錄此次更改,你也會收到此更改的通知:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: POSSIBLE DNS SPOOFING DETECTED!
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The RSA host key for xyz remote host has changed,and the key for the corresponding IP address xxx.yy.xxx.yy is unknown. This could either mean that DNS SPOOFING is happening or the IP address for the host and its host key have changed at the same time.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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 the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
69:4e:bb:70:6a:64:e3:78:07:6f:b4:00:41:07:d8:9c.
Please contact your system administrator.
Add correct host key in /home/.ssh/known_hosts to get rid of this message.
Offending key in /home/.ssh/known_hosts:1
Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.
在這種情況下,你可以在接受這個新密鑰之前聯系遠程服務器的管理員,以便確保遠程服務器沒有受到入侵。
有時候,管理員可能會由于重新安裝服務器而故意更改服務器(主機)的密鑰。
無論更改的原因是什么,你都需要首先從 known_hosts 文件中刪除舊密鑰,以便重新連接到遠程服務器。下次連接到此服務器時,客戶端主機將為此服務器創建新的主機密鑰。
管理多個經過身份驗證的用戶
如前所述,一旦客戶機主機成功連接到遠程服務器,其 known_hosts 文件將附加服務器的公鑰。
有時,你可能會希望對服務器進行身份驗證,而不需要提示進行服務器密鑰驗證。例如,你正在運行 Ansible 之類的配置管理工具,并且不希望客戶端主機請求服務器密鑰驗證。
因此,如果你有多個用戶,可以使用三種方式繞過SSH交互提示:
1)手動將服務器的公鑰附加到每個用戶的known_hosts文件中;
2)通過 ssh 訪問服務器時,對每個客戶端都使用命令行設置參數 -o StrictHostKeyChecking=no(不推薦);
3)在主 ssh_known_hosts 文件中注冊所有主機,然后將此文件編排到所有客戶端主機,然后使用 ssh-keyscan 命令:
ssh-keyscan -H -t rsa ‘your-server-ip’ >> /etc/ssh/ssh_known_hosts
下圖顯示了如何使用 StrictHostKeyChecking=no 選項:

上述方法中,第一種方法相比于另外兩種方法,操作起來更加繁瑣。
從 known_hosts 文件獲取遠程系統詳細信息
獲取遠程系統的詳細信息,不是一個簡單的工作。
基于安全考慮,幾乎所有 Linux 系統都會將 ssh 配置文件中的 HashKnownHosts 參數設置為 yes。
這也就意味著在 known_hosts 文件中的信息是以 hash 方式存儲的,你可能會看到一些隨機數,但這并不能提供任何有用的信息。
$ cat .ssh/known_hosts
|1|yWIW17YIg0wBRXJ8Ktt4mcfBqsk=|cFHOrZ8VEx0vdOjau2XQr/K7B/c= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFR293PJnDCj59XxfqYGctrMo60ZU5IOjACZZNRp9D6f
|1|Ta7hoH/az4O3l2dwfaKh8O2jitI=|WGU5TKhMA+2og1qMKE6kmynFNYo= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCmrxLW436AyBGyGCggl/j2qBCr782AVIvbiTEsWNBWLcWMKYAQpTdAXnaV4bBRqnk2NJg/60XDHKC2DF1tzx6ABWN/R6vcUAbulI9H1RUWpJ1AiDmFL84MvW2UukbpN5a6Lr+DvjclVqPxJRjQKr6Vy2K9oJgGKnHVcWSIHeAlW49kCCg5fIxF8stBTqJg0cRk6uxmcYVud1vh9a7SaZGK+jFZTB75RiHAVFuitHWpljecMxJRNYy/EhmmXrrvyU8pObVXlWlDd61uwExi4uEwNSY+Do7vR1y8svnt9mjTzzyM6MhT4sOcxWmNgdmw7bU/wPpie3dSjZMQeu2mQCSM7SG28dwjSyFPpanRsZKzkh0okAaCSItoNwl6zOf6dE3zt0s5EI6BPolhFAbT3NqmXRblxb7eV8rGEPf14iguHUkg6ZQr2OUdfeN1FYNMJ8Gb9RD159Mwjl4/jPIBdnXvt7zYct3XhPKm7Wxv4K/RWZE837C7mGQh2KEahWajdq8=
|1|NonAy25kVXL24U2mx6ZNxAY5m98=|ypf0IMpf3qq3vhrvUMprssOhODs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBE3br/9jaZfdB+qBxiVEZBJMb4XQONwzV4tH1xeFZX/zkyws2eBHrVO9O5l9b6M6+gO6nBtCwAzzaeLOn6mo8GQ=
如果你知道系統的主機名或IP地址,則可以從 known_hosts 獲取相關信息:
ssh-keygen -l -F <server-IP-or-hostname>
但是,如果你想要一個能夠以明文形式列出的所有服務器及其詳細信息的命令,那是不可能的。
當然,現實中會有一些專門的工具可以破譯 known_hosts,但這不是普通用戶可以做到的。
從known_hosts中刪除信息
如果想要從 known_hosts 文件中刪除某個特定的主機信息,可以根據遠程系統的主機名或 IP 執行這個操作:
ssh-keygen -R <server-hostname-or-ip>
當然也可以先識別相關服務器的信息,然后使用 rm 命令手動刪除,但是這個操作要麻煩的多,遠不如使用上述命令方便。
ssh-keygen -R <server-hostname-or-ip>用 rm 命令手動刪除,但是這個操作要麻煩的多,遠不如使用上述命令方便。
通過了解 ssh 相關的配置文件,有助于更好的理解系統安全相關知識。known_hosts 正是系統安全相關的重要組成部分。
以上就是本次分享全部內容。