本文首發於 https://jaychen.ccgit
做者 jaychengithub
寫一篇短文,介紹 ssh 密鑰登陸遠程服務器流程和注意事項。ubuntu
密鑰登陸比密碼登陸安全,主要是由於他使用了非對稱加密,登陸過程當中須要用到密鑰對。整個登陸流程以下:安全
整個登陸的流程就是這麼簡單,可是在實際使用 ssh 登陸中還會碰到一些小細節,這裏演示一遍 ssh 遠程登陸來展現下這些細節問題。bash
使用 ssh-keygen
就能夠直接生成登陸須要的密鑰對。ssh-keygen
是 Linux 下的命令,不添加任何參數就能夠生成密鑰對。服務器
➜ ~ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/jaychen/.ssh/id_rsa): #1 Enter passphrase (empty for no passphrase): #2 Enter same passphrase again: #3 複製代碼
執行 ssh-keygen
會出現如上的提示,在 #1
處這裏提示用戶輸入生成的私鑰的名稱,若是不填,默認私鑰保存在 /home/jaychen/.ssh/id_rsa
文件中。這裏要注意兩點:markdown
ssh-keygen
命令的用戶的家目錄下的 .ssh
文件夾中。即 $HOME/.ssh/
目錄下。.pub
的後綴。#2
處,提示輸入密碼,注意這裏的密碼是用來保證私鑰的安全的。若是填寫了密碼,那麼在使用密鑰進行登陸的時候,會讓你輸入密碼,這樣子保證了若是私鑰丟失了不至於被惡意使用。話是這麼說,可是平時使用這裏我都是直接略過。ssh
#3
是重複 #2
輸入的密碼,這裏就不廢話了。加密
生成密鑰以後,就能夠在 /home/jaychen/.ssh/
下看到兩個文件了(我這裏會放在 /home/jaychen
下是由於我使用 jaychen 用戶來執行 ssh-keygen
命令)spa
➜ .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 登陸用戶@服務器ip
複製代碼
這裏開始要注意兩個用戶的概念:
在開始登陸以前,咱們要首先要把生成公鑰上傳到服務器。
公鑰的內容要保存到要登陸的用戶的家目錄下的 .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.1 The authenticity of host '192.168.1.1 (192.168.1.1)' can't be established. ECDSA key fingerprint is SHA256:61U/SJ4n/QdR7oKT2gaHNuGxhx98saqMfzJnzA1XFZg. Are you sure you want to continue connecting (yes/no)? 複製代碼
這句話的意思是,遠程服務器的真實身份沒法校驗,只知道公鑰指紋(公鑰的 MD5 值)爲 61U/SJ4n/QdR7oKT2gaHNuGxhx98saqMfzJnzA1XFZg
,是否真的要創建鏈接。出現上面的提示是由於避免存在中間人攻擊。
中間人攻擊的前提是,你第一次登陸一臺遠程服務器,你除了用戶名、用戶名對應的公鑰私鑰以及服務器 ip 以外,對遠程服務器絲絕不瞭解的狀況下。假設你 ssh 遠程登陸 192.168.1.1 的遠程主機,在鏈接過程當中被第三者攔截,第三者假冒本身爲 192.168.1.1 的主機,那麼你就會直接鏈接到其餘人的服務器上。這就是中間人攻擊。
爲了不中間人攻擊,ssh 在首次登陸的時候會返回公鑰指紋,用戶須要本身手動去比對你要登陸的遠程服務器的公鑰的公鑰指紋和 ssh 返回的公鑰指紋是否同樣。
通過比較公鑰指紋,確認該服務器就是你要登陸的服務器,輸入 yes
以後就能夠成功登陸。整個登陸流程結束。
第一次登陸以後,在本機的 $HOME/.ssh/
目錄下就會生成一個 known_hosts
的文件,內容相似下面
➜ .ssh cat known_hosts
192.168.1.1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPKYWolOYTDevvBR6GV0rFcI0z/DHZizN5l/ajApsgx+UcOOh51liuyBRRCIyF+BR56Le0lP0Pn6nzvLjbqMqg=
複製代碼
這個文件記錄了遠程主機 ip 和遠程主機對應的公鑰指紋,那麼在下次登陸的時候,遠程主機發送過來的公鑰指紋,直接和 known_hosts
文件中對應 ip 的公鑰指紋比較便可。
不少時候,咱們開發可能須要鏈接多臺遠程服務器,而且須要配置 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
文件字段含義以下:
編寫好 config
文件以後,須要把 config
文件的權限改成 rw-r--r--
。若是權限過大,ssh 會禁止登陸。